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_ALLOWLIST, 112 [WMI_HOST_PEER_SET_MAX_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 /** 1634 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1635 * wmi_channel_width 1636 * @bw: wmi_host_channel_width channel width 1637 * 1638 * Return: wmi_channel_width 1639 */ 1640 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1641 wmi_host_channel_width bw) 1642 { 1643 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1644 1645 switch (bw) { 1646 case WMI_HOST_CHAN_WIDTH_20: 1647 target_bw = WMI_CHAN_WIDTH_20; 1648 break; 1649 case WMI_HOST_CHAN_WIDTH_40: 1650 target_bw = WMI_CHAN_WIDTH_40; 1651 break; 1652 case WMI_HOST_CHAN_WIDTH_80: 1653 target_bw = WMI_CHAN_WIDTH_80; 1654 break; 1655 case WMI_HOST_CHAN_WIDTH_160: 1656 target_bw = WMI_CHAN_WIDTH_160; 1657 break; 1658 case WMI_HOST_CHAN_WIDTH_80P80: 1659 target_bw = WMI_CHAN_WIDTH_80P80; 1660 break; 1661 case WMI_HOST_CHAN_WIDTH_5: 1662 target_bw = WMI_CHAN_WIDTH_5; 1663 break; 1664 case WMI_HOST_CHAN_WIDTH_10: 1665 target_bw = WMI_CHAN_WIDTH_10; 1666 break; 1667 case WMI_HOST_CHAN_WIDTH_165: 1668 target_bw = WMI_CHAN_WIDTH_165; 1669 break; 1670 case WMI_HOST_CHAN_WIDTH_160P160: 1671 target_bw = WMI_CHAN_WIDTH_160P160; 1672 break; 1673 case WMI_HOST_CHAN_WIDTH_320: 1674 target_bw = WMI_CHAN_WIDTH_320; 1675 break; 1676 default: 1677 break; 1678 } 1679 1680 return target_bw; 1681 } 1682 1683 /** 1684 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1685 * param value to target 1686 * @param_id: target param id 1687 * @param_value: host param value 1688 * 1689 * @Return: target param value 1690 */ 1691 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1692 uint32_t param_id, uint32_t param_value) 1693 { 1694 uint32_t fw_param_value = 0; 1695 wmi_host_channel_width bw; 1696 uint16_t punc; 1697 1698 switch (param_id) { 1699 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1700 bw = QDF_GET_BITS(param_value, 0, 8); 1701 punc = QDF_GET_BITS(param_value, 8, 16); 1702 QDF_SET_BITS(fw_param_value, 0, 8, 1703 wmi_host_chan_bw_to_target_chan_bw(bw)); 1704 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1705 break; 1706 default: 1707 fw_param_value = param_value; 1708 break; 1709 } 1710 1711 return fw_param_value; 1712 } 1713 1714 #ifdef WLAN_SUPPORT_PPEDS 1715 /** 1716 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1717 * @wmi: wmi handle 1718 * @param: pointer to hold PPE DS config 1719 * 1720 * Return: QDF_STATUS_SUCCESS for success or error code 1721 */ 1722 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1723 struct peer_ppe_ds_param *param) 1724 { 1725 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1726 wmi_buf_t buf; 1727 int32_t err; 1728 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1729 1730 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1731 if (!buf) 1732 return QDF_STATUS_E_NOMEM; 1733 1734 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1735 WMITLV_SET_HDR(&cmd->tlv_header, 1736 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1737 WMITLV_GET_STRUCT_TLVLEN 1738 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1739 1740 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1741 1742 if (param->ppe_routing_enabled) 1743 cmd->ppe_routing_enable = param->use_ppe ? 1744 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1745 else 1746 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1747 1748 cmd->service_code = param->service_code; 1749 cmd->priority_valid = param->priority_valid; 1750 cmd->src_info = param->src_info; 1751 cmd->vdev_id = param->vdev_id; 1752 1753 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1754 "ppe_routing_enable: %u service_code: %u\n" 1755 "priority_valid:%d src_info:%u", 1756 param->vdev_id, 1757 QDF_MAC_ADDR_REF(param->peer_macaddr), 1758 param->ppe_routing_enabled, 1759 param->service_code, 1760 param->priority_valid, 1761 param->src_info); 1762 1763 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1764 err = wmi_unified_cmd_send(wmi, buf, 1765 len, 1766 WMI_PEER_CONFIG_PPE_DS_CMDID); 1767 if (err) { 1768 wmi_err("Failed to send ppeds config cmd"); 1769 wmi_buf_free(buf); 1770 return QDF_STATUS_E_FAILURE; 1771 } 1772 1773 return 0; 1774 } 1775 #endif /* WLAN_SUPPORT_PPEDS */ 1776 1777 /** 1778 * send_peer_param_cmd_tlv() - set peer parameter in fw 1779 * @wmi: wmi handle 1780 * @peer_addr: peer mac address 1781 * @param : pointer to hold peer set parameter 1782 * 1783 * Return: QDF_STATUS_SUCCESS for success or error code 1784 */ 1785 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1786 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1787 struct peer_set_params *param) 1788 { 1789 wmi_peer_set_param_cmd_fixed_param *cmd; 1790 wmi_buf_t buf; 1791 int32_t err; 1792 uint32_t param_id; 1793 uint32_t param_value; 1794 1795 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1796 if (param_id == WMI_UNAVAILABLE_PARAM) { 1797 wmi_err("Unavailable param %d", param->param_id); 1798 return QDF_STATUS_E_NOSUPPORT; 1799 } 1800 param_value = convert_host_peer_param_value_to_target_value_tlv( 1801 param_id, param->param_value); 1802 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1803 if (!buf) 1804 return QDF_STATUS_E_NOMEM; 1805 1806 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1807 WMITLV_SET_HDR(&cmd->tlv_header, 1808 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1809 WMITLV_GET_STRUCT_TLVLEN 1810 (wmi_peer_set_param_cmd_fixed_param)); 1811 cmd->vdev_id = param->vdev_id; 1812 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1813 cmd->param_id = param_id; 1814 cmd->param_value = param_value; 1815 1816 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1817 cmd->vdev_id, 1818 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1819 cmd->param_value); 1820 1821 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1822 err = wmi_unified_cmd_send(wmi, buf, 1823 sizeof(wmi_peer_set_param_cmd_fixed_param), 1824 WMI_PEER_SET_PARAM_CMDID); 1825 if (err) { 1826 wmi_err("Failed to send set_param cmd"); 1827 wmi_buf_free(buf); 1828 return QDF_STATUS_E_FAILURE; 1829 } 1830 1831 return 0; 1832 } 1833 1834 /** 1835 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1836 * @wmi: wmi handle 1837 * @bssid: bssid 1838 * @vdev_up_params: pointer to hold vdev up parameter 1839 * 1840 * Return: QDF_STATUS_SUCCESS for success or error code 1841 */ 1842 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1843 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1844 struct vdev_up_params *params) 1845 { 1846 wmi_vdev_up_cmd_fixed_param *cmd; 1847 wmi_buf_t buf; 1848 int32_t len = sizeof(*cmd); 1849 1850 wmi_debug("VDEV_UP"); 1851 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1852 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1853 buf = wmi_buf_alloc(wmi, len); 1854 if (!buf) 1855 return QDF_STATUS_E_NOMEM; 1856 1857 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1858 WMITLV_SET_HDR(&cmd->tlv_header, 1859 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1860 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1861 cmd->vdev_id = params->vdev_id; 1862 cmd->vdev_assoc_id = params->assoc_id; 1863 cmd->profile_idx = params->profile_idx; 1864 cmd->profile_num = params->profile_num; 1865 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1866 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1867 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1868 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1869 wmi_err("Failed to send vdev up command"); 1870 wmi_buf_free(buf); 1871 return QDF_STATUS_E_FAILURE; 1872 } 1873 1874 return 0; 1875 } 1876 1877 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1878 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1879 { 1880 /* Host sets the peer_type as 0 for the peer create command sent to FW 1881 * other than PASN peer create command. 1882 */ 1883 if (peer_type == WLAN_PEER_RTT_PASN) 1884 return WMI_PEER_TYPE_PASN; 1885 1886 return peer_type; 1887 } 1888 #else 1889 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1890 { 1891 return peer_type; 1892 } 1893 #endif 1894 /** 1895 * send_peer_create_cmd_tlv() - send peer create command to fw 1896 * @wmi: wmi handle 1897 * @peer_addr: peer mac address 1898 * @peer_type: peer type 1899 * @vdev_id: vdev id 1900 * 1901 * Return: QDF_STATUS_SUCCESS for success or error code 1902 */ 1903 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1904 struct peer_create_params *param) 1905 { 1906 wmi_peer_create_cmd_fixed_param *cmd; 1907 wmi_buf_t buf; 1908 uint8_t *buf_ptr; 1909 int32_t len = sizeof(*cmd); 1910 1911 len += peer_create_mlo_params_size(param); 1912 buf = wmi_buf_alloc(wmi, len); 1913 if (!buf) 1914 return QDF_STATUS_E_NOMEM; 1915 1916 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1917 WMITLV_SET_HDR(&cmd->tlv_header, 1918 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1919 WMITLV_GET_STRUCT_TLVLEN 1920 (wmi_peer_create_cmd_fixed_param)); 1921 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1922 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1923 cmd->vdev_id = param->vdev_id; 1924 1925 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1926 buf_ptr += sizeof(*cmd); 1927 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1928 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1929 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1930 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1931 wmi_buf_free(buf); 1932 return QDF_STATUS_E_FAILURE; 1933 } 1934 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1935 QDF_MAC_ADDR_REF(param->peer_addr), 1936 param->vdev_id); 1937 1938 return 0; 1939 } 1940 1941 /** 1942 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1943 * command to fw 1944 * @wmi: wmi handle 1945 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1946 * 1947 * Return: 0 for success or error code 1948 */ 1949 static 1950 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1951 struct rx_reorder_queue_setup_params *param) 1952 { 1953 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1954 wmi_buf_t buf; 1955 int32_t len = sizeof(*cmd); 1956 1957 buf = wmi_buf_alloc(wmi, len); 1958 if (!buf) 1959 return QDF_STATUS_E_NOMEM; 1960 1961 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1962 WMITLV_SET_HDR(&cmd->tlv_header, 1963 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1964 WMITLV_GET_STRUCT_TLVLEN 1965 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1966 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1967 cmd->vdev_id = param->vdev_id; 1968 cmd->tid = param->tid; 1969 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1970 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1971 cmd->queue_no = param->queue_no; 1972 cmd->ba_window_size_valid = param->ba_window_size_valid; 1973 cmd->ba_window_size = param->ba_window_size; 1974 1975 1976 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1977 if (wmi_unified_cmd_send(wmi, buf, len, 1978 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1979 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1980 wmi_buf_free(buf); 1981 return QDF_STATUS_E_FAILURE; 1982 } 1983 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1984 QDF_MAC_ADDR_REF(param->peer_macaddr), 1985 param->vdev_id, param->tid); 1986 1987 return QDF_STATUS_SUCCESS; 1988 } 1989 1990 /** 1991 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1992 * command to fw 1993 * @wmi: wmi handle 1994 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1995 * 1996 * Return: 0 for success or error code 1997 */ 1998 static 1999 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 2000 struct rx_reorder_queue_remove_params *param) 2001 { 2002 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 2003 wmi_buf_t buf; 2004 int32_t len = sizeof(*cmd); 2005 2006 buf = wmi_buf_alloc(wmi, len); 2007 if (!buf) 2008 return QDF_STATUS_E_NOMEM; 2009 2010 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 2011 wmi_buf_data(buf); 2012 WMITLV_SET_HDR(&cmd->tlv_header, 2013 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2014 WMITLV_GET_STRUCT_TLVLEN 2015 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2016 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2017 cmd->vdev_id = param->vdev_id; 2018 cmd->tid_mask = param->peer_tid_bitmap; 2019 2020 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2021 if (wmi_unified_cmd_send(wmi, buf, len, 2022 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2023 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2024 wmi_buf_free(buf); 2025 return QDF_STATUS_E_FAILURE; 2026 } 2027 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2028 QDF_MAC_ADDR_REF(param->peer_macaddr), 2029 param->vdev_id, param->peer_tid_bitmap); 2030 2031 return QDF_STATUS_SUCCESS; 2032 } 2033 2034 #ifdef WLAN_SUPPORT_GREEN_AP 2035 /** 2036 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2037 * @wmi_handle: wmi handle 2038 * @value: value 2039 * @pdev_id: pdev id to have radio context 2040 * 2041 * Return: QDF_STATUS_SUCCESS for success or error code 2042 */ 2043 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2044 uint32_t value, uint8_t pdev_id) 2045 { 2046 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2047 wmi_buf_t buf; 2048 int32_t len = sizeof(*cmd); 2049 2050 wmi_debug("Set Green AP PS val %d", value); 2051 2052 buf = wmi_buf_alloc(wmi_handle, len); 2053 if (!buf) 2054 return QDF_STATUS_E_NOMEM; 2055 2056 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2057 WMITLV_SET_HDR(&cmd->tlv_header, 2058 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2059 WMITLV_GET_STRUCT_TLVLEN 2060 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2061 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2062 wmi_handle, 2063 pdev_id); 2064 cmd->enable = value; 2065 2066 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2067 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2068 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2069 wmi_err("Set Green AP PS param Failed val %d", value); 2070 wmi_buf_free(buf); 2071 return QDF_STATUS_E_FAILURE; 2072 } 2073 2074 return 0; 2075 } 2076 #endif 2077 2078 /** 2079 * send_pdev_utf_cmd_tlv() - send utf command to fw 2080 * @wmi_handle: wmi handle 2081 * @param: pointer to pdev_utf_params 2082 * @mac_id: mac id to have radio context 2083 * 2084 * Return: QDF_STATUS_SUCCESS for success or error code 2085 */ 2086 static QDF_STATUS 2087 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2088 struct pdev_utf_params *param, 2089 uint8_t mac_id) 2090 { 2091 wmi_buf_t buf; 2092 uint8_t *cmd; 2093 /* if param->len is 0 no data is sent, return error */ 2094 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2095 static uint8_t msgref = 1; 2096 uint8_t segNumber = 0, segInfo, numSegments; 2097 uint16_t chunk_len, total_bytes; 2098 uint8_t *bufpos; 2099 struct seg_hdr_info segHdrInfo; 2100 2101 bufpos = param->utf_payload; 2102 total_bytes = param->len; 2103 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2104 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2105 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2106 2107 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2108 numSegments++; 2109 2110 while (param->len) { 2111 if (param->len > MAX_WMI_UTF_LEN) 2112 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2113 else 2114 chunk_len = param->len; 2115 2116 buf = wmi_buf_alloc(wmi_handle, 2117 (chunk_len + sizeof(segHdrInfo) + 2118 WMI_TLV_HDR_SIZE)); 2119 if (!buf) 2120 return QDF_STATUS_E_NOMEM; 2121 2122 cmd = (uint8_t *) wmi_buf_data(buf); 2123 2124 segHdrInfo.len = total_bytes; 2125 segHdrInfo.msgref = msgref; 2126 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2127 segHdrInfo.segmentInfo = segInfo; 2128 segHdrInfo.pad = 0; 2129 2130 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 2131 " segHdrInfo.segmentInfo = %d", 2132 segHdrInfo.len, segHdrInfo.msgref, 2133 segHdrInfo.segmentInfo); 2134 2135 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 2136 " chunk len %d", total_bytes, segNumber, 2137 numSegments, chunk_len); 2138 2139 segNumber++; 2140 2141 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2142 (chunk_len + sizeof(segHdrInfo))); 2143 cmd += WMI_TLV_HDR_SIZE; 2144 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 2145 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 2146 bufpos, chunk_len); 2147 2148 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2149 ret = wmi_unified_cmd_send(wmi_handle, buf, 2150 (chunk_len + sizeof(segHdrInfo) + 2151 WMI_TLV_HDR_SIZE), 2152 WMI_PDEV_UTF_CMDID); 2153 2154 if (QDF_IS_STATUS_ERROR(ret)) { 2155 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2156 wmi_buf_free(buf); 2157 break; 2158 } 2159 2160 param->len -= chunk_len; 2161 bufpos += chunk_len; 2162 } 2163 2164 msgref++; 2165 2166 return ret; 2167 } 2168 2169 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2170 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2171 { 2172 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2173 return pdev_param_tlv[host_param]; 2174 return WMI_UNAVAILABLE_PARAM; 2175 } 2176 2177 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2178 { 2179 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2180 return vdev_param_tlv[host_param]; 2181 return WMI_UNAVAILABLE_PARAM; 2182 } 2183 #else 2184 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2185 { 2186 return host_param; 2187 } 2188 2189 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2190 { 2191 return host_param; 2192 } 2193 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2194 2195 /** 2196 * send_pdev_param_cmd_tlv() - set pdev parameters 2197 * @wmi_handle: wmi handle 2198 * @param: pointer to pdev parameter 2199 * @mac_id: radio context 2200 * 2201 * Return: 0 on success, errno on failure 2202 */ 2203 static QDF_STATUS 2204 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2205 struct pdev_params *param, 2206 uint8_t mac_id) 2207 { 2208 QDF_STATUS ret; 2209 wmi_pdev_set_param_cmd_fixed_param *cmd; 2210 wmi_buf_t buf; 2211 uint16_t len = sizeof(*cmd); 2212 uint32_t pdev_param; 2213 2214 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2215 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2216 wmi_err("Unavailable param %d", param->param_id); 2217 return QDF_STATUS_E_INVAL; 2218 } 2219 2220 buf = wmi_buf_alloc(wmi_handle, len); 2221 if (!buf) 2222 return QDF_STATUS_E_NOMEM; 2223 2224 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2225 WMITLV_SET_HDR(&cmd->tlv_header, 2226 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2227 WMITLV_GET_STRUCT_TLVLEN 2228 (wmi_pdev_set_param_cmd_fixed_param)); 2229 if (param->is_host_pdev_id) 2230 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2231 wmi_handle, 2232 mac_id); 2233 else 2234 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2235 wmi_handle, 2236 mac_id); 2237 cmd->param_id = pdev_param; 2238 cmd->param_value = param->param_value; 2239 wmi_debug("Setting pdev %d param = %x, value = %u", cmd->pdev_id, 2240 cmd->param_id, cmd->param_value); 2241 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2242 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2243 WMI_PDEV_SET_PARAM_CMDID); 2244 if (QDF_IS_STATUS_ERROR(ret)) { 2245 wmi_err("Failed to send set param command ret = %d", ret); 2246 wmi_buf_free(buf); 2247 } 2248 return ret; 2249 } 2250 2251 /** 2252 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2253 * @wmi_handle: wmi handle 2254 * @params: pointer to hold set_multiple_pdev_vdev_param info 2255 * 2256 * Return: 0 on success, errno on failure 2257 */ 2258 static QDF_STATUS 2259 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2260 struct set_multiple_pdev_vdev_param *params) 2261 { 2262 uint8_t index; 2263 struct pdev_params pdevparam; 2264 uint8_t n_params = params->n_params; 2265 2266 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2267 for (index = 0; index < n_params; index++) { 2268 pdevparam.param_id = params->params[index].param_id; 2269 pdevparam.param_value = params->params[index].param_value; 2270 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2271 &pdevparam, 2272 params->dev_id))) { 2273 wmi_err("failed to send pdev setparam:%d", 2274 pdevparam.param_id); 2275 return QDF_STATUS_E_FAILURE; 2276 } 2277 } 2278 return QDF_STATUS_SUCCESS; 2279 } 2280 2281 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2282 2283 /** 2284 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2285 * @params: pointer to point set_multiple_pdev_vdev_param info 2286 * 2287 * Return: returns QDF_STATUS 2288 */ 2289 static QDF_STATUS 2290 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2291 { 2292 uint8_t index; 2293 uint32_t dev_paramid; 2294 uint8_t num = params->n_params; 2295 2296 if (params->param_type == MLME_PDEV_SETPARAM) { 2297 for (index = 0; index < num; index++) { 2298 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2299 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2300 wmi_err("pdev param %d not available", 2301 params->params[index].param_id); 2302 return QDF_STATUS_E_INVAL; 2303 } 2304 params->params[index].param_id = dev_paramid; 2305 } 2306 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2307 for (index = 0; index < num; index++) { 2308 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2309 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2310 wmi_err("vdev param %d not available", 2311 params->params[index].param_id); 2312 return QDF_STATUS_E_INVAL; 2313 } 2314 params->params[index].param_id = dev_paramid; 2315 } 2316 } else { 2317 wmi_err("invalid param type"); 2318 return QDF_STATUS_E_INVAL; 2319 } 2320 return QDF_STATUS_SUCCESS; 2321 } 2322 2323 /** 2324 * send_dev_multi_setparam_cmd_tlv()-to print the paramid and param value 2325 * @setparam: buffer pointer where host is filling paramsid and value 2326 * @params: pointer to hold set_multiple_pdev_vdev_param info 2327 * 2328 */ 2329 static void send_dev_multi_setparam_cmd_tlv(wmi_set_param_info *setparam, 2330 struct set_multiple_pdev_vdev_param *params) 2331 { 2332 if (params->param_type == MLME_VDEV_SETPARAM) { 2333 wmi_debug("Setting vdev %d param = %x value = %u", params->dev_id, 2334 setparam->param_id, setparam->param_value); 2335 } else { 2336 wmi_debug("Setting pdev %d param = %x value = %u", 2337 params->dev_id, setparam->param_id, setparam->param_value); 2338 } 2339 } 2340 2341 /** 2342 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2343 * @wmi_handle: wmi handle 2344 * @params: pointer to hold set_multiple_pdev_vdev_param info 2345 * 2346 * Return: returns QDF_STATUS 2347 */ 2348 static QDF_STATUS 2349 send_multi_pdev_vdev_set_param_cmd_tlv( 2350 wmi_unified_t wmi_handle, 2351 struct set_multiple_pdev_vdev_param *params) 2352 { 2353 uint8_t *buf_ptr; 2354 QDF_STATUS ret; 2355 wmi_buf_t buf; 2356 wmi_set_param_info *setparam; 2357 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2358 uint8_t num = params->n_params; 2359 uint16_t len; 2360 uint8_t index = 0; 2361 2362 if (convert_host_pdev_vdev_param_id_to_target(params)) 2363 return QDF_STATUS_E_INVAL; 2364 2365 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2366 buf = wmi_buf_alloc(wmi_handle, len); 2367 if (!buf) 2368 return QDF_STATUS_E_NOMEM; 2369 2370 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2371 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2372 2373 WMITLV_SET_HDR(&cmd->tlv_header, 2374 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2375 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2376 2377 cmd->is_vdev = params->param_type; 2378 if (params->param_type == MLME_PDEV_SETPARAM) { 2379 if (params->is_host_pdev_id) 2380 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2381 params->dev_id); 2382 else 2383 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2384 params->dev_id); 2385 } 2386 cmd->dev_id = params->dev_id; 2387 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2388 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2389 buf_ptr += WMI_TLV_HDR_SIZE; 2390 for (index = 0; index < num; index++) { 2391 setparam = (wmi_set_param_info *)buf_ptr; 2392 WMITLV_SET_HDR(&setparam->tlv_header, 2393 WMITLV_TAG_STRUC_wmi_set_param_info, 2394 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2395 setparam->param_id = params->params[index].param_id; 2396 setparam->param_value = params->params[index].param_value; 2397 send_dev_multi_setparam_cmd_tlv(setparam, params); 2398 buf_ptr += sizeof(*setparam); 2399 } 2400 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2401 cmd->dev_id, 0); 2402 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2403 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2404 if (QDF_IS_STATUS_ERROR(ret)) { 2405 wmi_err("failed to send WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID"); 2406 wmi_buf_free(buf); 2407 } 2408 return ret; 2409 } 2410 2411 /** 2412 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2413 * @wmi_handle: wmi handle 2414 * @params: pointer to set_multiple_pdev_vdev_param structure 2415 * 2416 * Return: 0 on success, errno on failure 2417 */ 2418 static QDF_STATUS 2419 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2420 struct set_multiple_pdev_vdev_param *params) 2421 { 2422 if (!wmi_service_enabled(wmi_handle, 2423 wmi_service_combined_set_param_support)) 2424 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2425 params); 2426 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2427 } 2428 2429 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2430 /** 2431 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2432 * @wmi_handle: wmi handle 2433 * @params: pointer to set_multiple_pdev_vdev_param structure 2434 * 2435 * Return: 0 on success, errno on failure 2436 */ 2437 static QDF_STATUS 2438 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2439 struct set_multiple_pdev_vdev_param *params) 2440 { 2441 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2442 } 2443 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2444 2445 /** 2446 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2447 * @wmi_handle: wmi handle 2448 * @msg: Structure containing the following parameters 2449 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2450 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2451 * 2452 * Provides notification to the WLAN firmware that host driver is requesting a 2453 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2454 * configurations that include the Dual Band Simultaneous (DBS) feature. 2455 * 2456 * Return: Success if the cmd is sent successfully to the firmware 2457 */ 2458 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2459 uint32_t hw_mode_index) 2460 { 2461 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2462 wmi_buf_t buf; 2463 uint32_t len; 2464 2465 len = sizeof(*cmd); 2466 2467 buf = wmi_buf_alloc(wmi_handle, len); 2468 if (!buf) 2469 return QDF_STATUS_E_NOMEM; 2470 2471 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2472 WMITLV_SET_HDR(&cmd->tlv_header, 2473 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2474 WMITLV_GET_STRUCT_TLVLEN( 2475 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2476 2477 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2478 wmi_handle, 2479 WMI_HOST_PDEV_ID_SOC); 2480 cmd->hw_mode_index = hw_mode_index; 2481 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2482 2483 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2484 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2485 WMI_PDEV_SET_HW_MODE_CMDID)) { 2486 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2487 wmi_buf_free(buf); 2488 return QDF_STATUS_E_FAILURE; 2489 } 2490 2491 return QDF_STATUS_SUCCESS; 2492 } 2493 2494 /** 2495 * send_suspend_cmd_tlv() - WMI suspend function 2496 * @param wmi_handle : handle to WMI. 2497 * @param param : pointer to hold suspend parameter 2498 * @mac_id: radio context 2499 * 2500 * Return 0 on success and -ve on failure. 2501 */ 2502 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2503 struct suspend_params *param, 2504 uint8_t mac_id) 2505 { 2506 wmi_pdev_suspend_cmd_fixed_param *cmd; 2507 wmi_buf_t wmibuf; 2508 uint32_t len = sizeof(*cmd); 2509 int32_t ret; 2510 2511 /* 2512 * send the command to Target to ignore the 2513 * PCIE reset so as to ensure that Host and target 2514 * states are in sync 2515 */ 2516 wmibuf = wmi_buf_alloc(wmi_handle, len); 2517 if (!wmibuf) 2518 return QDF_STATUS_E_NOMEM; 2519 2520 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2521 WMITLV_SET_HDR(&cmd->tlv_header, 2522 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2523 WMITLV_GET_STRUCT_TLVLEN 2524 (wmi_pdev_suspend_cmd_fixed_param)); 2525 if (param->disable_target_intr) 2526 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2527 else 2528 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2529 2530 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2531 wmi_handle, 2532 mac_id); 2533 2534 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2535 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2536 WMI_PDEV_SUSPEND_CMDID); 2537 if (ret) { 2538 wmi_buf_free(wmibuf); 2539 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2540 } 2541 2542 return ret; 2543 } 2544 2545 /** 2546 * send_resume_cmd_tlv() - WMI resume function 2547 * @param wmi_handle : handle to WMI. 2548 * @mac_id: radio context 2549 * 2550 * Return: 0 on success and -ve on failure. 2551 */ 2552 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2553 uint8_t mac_id) 2554 { 2555 wmi_buf_t wmibuf; 2556 wmi_pdev_resume_cmd_fixed_param *cmd; 2557 QDF_STATUS ret; 2558 2559 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2560 if (!wmibuf) 2561 return QDF_STATUS_E_NOMEM; 2562 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2563 WMITLV_SET_HDR(&cmd->tlv_header, 2564 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2565 WMITLV_GET_STRUCT_TLVLEN 2566 (wmi_pdev_resume_cmd_fixed_param)); 2567 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2568 wmi_handle, 2569 mac_id); 2570 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2571 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2572 WMI_PDEV_RESUME_CMDID); 2573 if (QDF_IS_STATUS_ERROR(ret)) { 2574 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2575 wmi_buf_free(wmibuf); 2576 } 2577 2578 return ret; 2579 } 2580 2581 /** 2582 * send_wow_enable_cmd_tlv() - WMI wow enable function 2583 * @param wmi_handle : handle to WMI. 2584 * @param param : pointer to hold wow enable parameter 2585 * @mac_id: radio context 2586 * 2587 * Return: 0 on success and -ve on failure. 2588 */ 2589 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2590 struct wow_cmd_params *param, 2591 uint8_t mac_id) 2592 { 2593 wmi_wow_enable_cmd_fixed_param *cmd; 2594 wmi_buf_t buf; 2595 int32_t len; 2596 int32_t ret; 2597 2598 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2599 2600 buf = wmi_buf_alloc(wmi_handle, len); 2601 if (!buf) 2602 return QDF_STATUS_E_NOMEM; 2603 2604 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2605 WMITLV_SET_HDR(&cmd->tlv_header, 2606 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2607 WMITLV_GET_STRUCT_TLVLEN 2608 (wmi_wow_enable_cmd_fixed_param)); 2609 cmd->enable = param->enable; 2610 if (param->can_suspend_link) 2611 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2612 else 2613 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2614 cmd->flags = param->flags; 2615 2616 wmi_debug("suspend type: %s flag is 0x%x", 2617 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2618 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2619 cmd->flags); 2620 2621 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2622 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2623 WMI_WOW_ENABLE_CMDID); 2624 if (ret) 2625 wmi_buf_free(buf); 2626 2627 return ret; 2628 } 2629 2630 /** 2631 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2632 * @wmi_handle: wmi handle 2633 * @peer_addr: peer mac address 2634 * @param: pointer to ap_ps parameter structure 2635 * 2636 * Return: QDF_STATUS_SUCCESS for success or error code 2637 */ 2638 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2639 uint8_t *peer_addr, 2640 struct ap_ps_params *param) 2641 { 2642 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2643 wmi_buf_t buf; 2644 int32_t err; 2645 2646 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2647 if (!buf) 2648 return QDF_STATUS_E_NOMEM; 2649 2650 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2651 WMITLV_SET_HDR(&cmd->tlv_header, 2652 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2653 WMITLV_GET_STRUCT_TLVLEN 2654 (wmi_ap_ps_peer_cmd_fixed_param)); 2655 cmd->vdev_id = param->vdev_id; 2656 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2657 cmd->param = param->param; 2658 cmd->value = param->value; 2659 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2660 err = wmi_unified_cmd_send(wmi_handle, buf, 2661 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2662 if (err) { 2663 wmi_err("Failed to send set_ap_ps_param cmd"); 2664 wmi_buf_free(buf); 2665 return QDF_STATUS_E_FAILURE; 2666 } 2667 2668 return 0; 2669 } 2670 2671 /** 2672 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2673 * @wmi_handle: wmi handle 2674 * @peer_addr: peer mac address 2675 * @param: pointer to sta_ps parameter structure 2676 * 2677 * Return: QDF_STATUS_SUCCESS for success or error code 2678 */ 2679 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2680 struct sta_ps_params *param) 2681 { 2682 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2683 wmi_buf_t buf; 2684 int32_t len = sizeof(*cmd); 2685 2686 buf = wmi_buf_alloc(wmi_handle, len); 2687 if (!buf) 2688 return QDF_STATUS_E_NOMEM; 2689 2690 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2691 WMITLV_SET_HDR(&cmd->tlv_header, 2692 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2693 WMITLV_GET_STRUCT_TLVLEN 2694 (wmi_sta_powersave_param_cmd_fixed_param)); 2695 cmd->vdev_id = param->vdev_id; 2696 cmd->param = param->param_id; 2697 cmd->value = param->value; 2698 2699 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2700 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2701 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2702 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2703 param->vdev_id, param->param_id, param->value); 2704 wmi_buf_free(buf); 2705 return QDF_STATUS_E_FAILURE; 2706 } 2707 2708 return 0; 2709 } 2710 2711 /** 2712 * send_crash_inject_cmd_tlv() - inject fw crash 2713 * @wmi_handle: wmi handle 2714 * @param: ponirt to crash inject parameter structure 2715 * 2716 * Return: QDF_STATUS_SUCCESS for success or return error 2717 */ 2718 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2719 struct crash_inject *param) 2720 { 2721 int32_t ret = 0; 2722 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2723 uint16_t len = sizeof(*cmd); 2724 wmi_buf_t buf; 2725 2726 buf = wmi_buf_alloc(wmi_handle, len); 2727 if (!buf) 2728 return QDF_STATUS_E_NOMEM; 2729 2730 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2731 WMITLV_SET_HDR(&cmd->tlv_header, 2732 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2733 WMITLV_GET_STRUCT_TLVLEN 2734 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2735 cmd->type = param->type; 2736 cmd->delay_time_ms = param->delay_time_ms; 2737 2738 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2739 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2740 WMI_FORCE_FW_HANG_CMDID); 2741 if (ret) { 2742 wmi_err("Failed to send set param command, ret = %d", ret); 2743 wmi_buf_free(buf); 2744 } 2745 2746 return ret; 2747 } 2748 2749 /** 2750 * send_dbglog_cmd_tlv() - set debug log level 2751 * @param wmi_handle : handle to WMI. 2752 * @param param : pointer to hold dbglog level parameter 2753 * 2754 * Return: 0 on success and -ve on failure. 2755 */ 2756 static QDF_STATUS 2757 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2758 struct dbglog_params *dbglog_param) 2759 { 2760 wmi_buf_t buf; 2761 wmi_debug_log_config_cmd_fixed_param *configmsg; 2762 QDF_STATUS status; 2763 int32_t i; 2764 int32_t len; 2765 int8_t *buf_ptr; 2766 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2767 2768 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2769 2770 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2771 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2772 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2773 buf = wmi_buf_alloc(wmi_handle, len); 2774 if (!buf) 2775 return QDF_STATUS_E_NOMEM; 2776 2777 configmsg = 2778 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2779 buf_ptr = (int8_t *) configmsg; 2780 WMITLV_SET_HDR(&configmsg->tlv_header, 2781 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2782 WMITLV_GET_STRUCT_TLVLEN 2783 (wmi_debug_log_config_cmd_fixed_param)); 2784 configmsg->dbg_log_param = dbglog_param->param; 2785 configmsg->value = dbglog_param->val; 2786 /* Filling in the data part of second tlv -- should 2787 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2788 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2789 sizeof 2790 (wmi_debug_log_config_cmd_fixed_param) 2791 + WMI_TLV_HDR_SIZE); 2792 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2793 WMITLV_TAG_ARRAY_UINT32, 2794 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2795 if (dbglog_param->module_id_bitmap) { 2796 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2797 module_id_bitmap_array[i] = 2798 dbglog_param->module_id_bitmap[i]; 2799 } 2800 } 2801 2802 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2803 status = wmi_unified_cmd_send(wmi_handle, buf, 2804 len, WMI_DBGLOG_CFG_CMDID); 2805 2806 if (status != QDF_STATUS_SUCCESS) 2807 wmi_buf_free(buf); 2808 2809 return status; 2810 } 2811 2812 /** 2813 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2814 * @param wmi_handle : handle to WMI. 2815 * @param macaddr : MAC address 2816 * @param param : pointer to hold vdev set parameter 2817 * 2818 * Return: 0 on success and -ve on failure. 2819 */ 2820 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2821 struct vdev_set_params *param) 2822 { 2823 QDF_STATUS ret; 2824 wmi_vdev_set_param_cmd_fixed_param *cmd; 2825 wmi_buf_t buf; 2826 uint16_t len = sizeof(*cmd); 2827 uint32_t vdev_param; 2828 2829 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2830 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2831 wmi_err("Vdev param %d not available", param->param_id); 2832 return QDF_STATUS_E_INVAL; 2833 2834 } 2835 2836 buf = wmi_buf_alloc(wmi_handle, len); 2837 if (!buf) 2838 return QDF_STATUS_E_NOMEM; 2839 2840 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2841 WMITLV_SET_HDR(&cmd->tlv_header, 2842 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2843 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2844 cmd->vdev_id = param->vdev_id; 2845 cmd->param_id = vdev_param; 2846 cmd->param_value = param->param_value; 2847 wmi_debug("Setting vdev %d param = %x, value = %u", 2848 cmd->vdev_id, cmd->param_id, cmd->param_value); 2849 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2850 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2851 if (QDF_IS_STATUS_ERROR(ret)) { 2852 wmi_err("Failed to send set param command ret = %d", ret); 2853 wmi_buf_free(buf); 2854 } 2855 2856 return ret; 2857 } 2858 2859 /** 2860 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2861 * @wmi_handle : handle to WMI. 2862 * @dev_id: device id of pdev/vdev 2863 * @params: pointer to point array of structure dev_set_param with @n_params 2864 * @n_params: total number of set params that are combined with @params 2865 * 2866 * Return: returns QDF_STATUS. 2867 */ 2868 static QDF_STATUS 2869 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2870 struct set_multiple_pdev_vdev_param *params) 2871 { 2872 uint8_t index; 2873 struct vdev_set_params vdevparam; 2874 2875 for (index = 0; index < params->n_params; index++) { 2876 vdevparam.param_id = params->params[index].param_id; 2877 vdevparam.param_value = params->params[index].param_value; 2878 vdevparam.vdev_id = params->dev_id; 2879 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2880 wmi_err("failed to send param:%d", vdevparam.param_id); 2881 return QDF_STATUS_E_FAILURE; 2882 } 2883 } 2884 return QDF_STATUS_SUCCESS; 2885 } 2886 2887 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2888 /** 2889 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2890 * @wmi_handle : handle to WMI. 2891 * @params: pointer to hold set_multiple_pdev_vdev_param info 2892 * 2893 * Return: 0 on success and errorcode on failure. 2894 */ 2895 static QDF_STATUS 2896 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2897 struct set_multiple_pdev_vdev_param *params) 2898 { 2899 if (!wmi_service_enabled(wmi_handle, 2900 wmi_service_combined_set_param_support)) 2901 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2902 params); 2903 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2904 } 2905 2906 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2907 2908 /** 2909 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2910 * @wmi_handle : handle to WMI. 2911 * @params: pointer to hold set_multiple_pdev_vdev_param info 2912 * 2913 * Return: 0 on success and errorcode on failure. 2914 */ 2915 static QDF_STATUS 2916 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2917 struct set_multiple_pdev_vdev_param *params) 2918 { 2919 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 2920 } 2921 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2922 2923 /** 2924 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2925 * @param wmi_handle : handle to WMI. 2926 * @param param : pointer to hold mu sniffer parameter 2927 * 2928 * Return: 0 on success and -ve on failure. 2929 */ 2930 static 2931 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2932 struct vdev_set_mu_snif_param *param) 2933 { 2934 QDF_STATUS ret; 2935 wmi_vdev_set_mu_snif_cmd_param *cmd; 2936 wmi_buf_t buf; 2937 uint32_t *tmp_ptr; 2938 uint16_t len = sizeof(*cmd); 2939 uint8_t *buf_ptr; 2940 uint32_t i; 2941 2942 /* Length TLV placeholder for array of uint32_t */ 2943 len += WMI_TLV_HDR_SIZE; 2944 2945 if (param->num_aid) 2946 len += param->num_aid * sizeof(uint32_t); 2947 2948 buf = wmi_buf_alloc(wmi_handle, len); 2949 if (!buf) 2950 return QDF_STATUS_E_NOMEM; 2951 2952 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2953 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2954 2955 WMITLV_SET_HDR(&cmd->tlv_header, 2956 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2957 WMITLV_GET_STRUCT_TLVLEN 2958 (wmi_vdev_set_mu_snif_cmd_param)); 2959 2960 cmd->vdev_id = param->vdev_id; 2961 cmd->mode = param->mode; 2962 cmd->max_num_user = param->num_user; 2963 2964 buf_ptr += sizeof(*cmd); 2965 2966 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2967 2968 for (i = 0; i < param->num_aid; ++i) 2969 tmp_ptr[i] = param->aid[i]; 2970 2971 WMITLV_SET_HDR(buf_ptr, 2972 WMITLV_TAG_ARRAY_UINT32, 2973 (param->num_aid * sizeof(uint32_t))); 2974 2975 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2976 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2977 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2979 WMI_VDEV_SET_MU_SNIF_CMDID); 2980 if (QDF_IS_STATUS_ERROR(ret)) { 2981 wmi_err("Failed to send set param command ret = %d", ret); 2982 wmi_buf_free(buf); 2983 } 2984 2985 return ret; 2986 } 2987 2988 /** 2989 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2990 * @wmi_handle: handle to WMI. 2991 * @macaddr: Peer mac address to be filter 2992 * @mac_id: mac id to have radio context 2993 * @enb_dsb: Enable MAC based filtering or Disable 2994 * 2995 * Return: QDF_STATUS 2996 */ 2997 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2998 uint8_t *macaddr, 2999 uint8_t mac_id, 3000 uint8_t enb_dsb) 3001 { 3002 int32_t ret; 3003 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3004 wmi_pdev_pktlog_filter_info *mac_info; 3005 wmi_buf_t buf; 3006 uint8_t *buf_ptr; 3007 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3008 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3009 3010 buf = wmi_buf_alloc(wmi_handle, len); 3011 if (!buf) 3012 return QDF_STATUS_E_NOMEM; 3013 3014 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3015 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3016 WMITLV_SET_HDR(&cmd->tlv_header, 3017 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3018 WMITLV_GET_STRUCT_TLVLEN 3019 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3020 cmd->pdev_id = mac_id; 3021 cmd->enable = enb_dsb; 3022 cmd->num_of_mac_addresses = 1; 3023 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3024 3025 buf_ptr += sizeof(*cmd); 3026 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3027 sizeof(wmi_pdev_pktlog_filter_info)); 3028 buf_ptr += WMI_TLV_HDR_SIZE; 3029 3030 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3031 3032 WMITLV_SET_HDR(&mac_info->tlv_header, 3033 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3034 WMITLV_GET_STRUCT_TLVLEN 3035 (wmi_pdev_pktlog_filter_info)); 3036 3037 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3038 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3039 WMI_PDEV_PKTLOG_FILTER_CMDID); 3040 if (ret) { 3041 wmi_err("Failed to send peer based pktlog command to FW =%d" 3042 , ret); 3043 wmi_buf_free(buf); 3044 } 3045 3046 return ret; 3047 } 3048 3049 /** 3050 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3051 * @param wmi_handle : handle to WMI. 3052 * @param PKTLOG_EVENT : packet log event 3053 * @mac_id: mac id to have radio context 3054 * 3055 * Return: 0 on success and -ve on failure. 3056 */ 3057 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3058 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3059 { 3060 int32_t ret, idx, max_idx; 3061 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3062 wmi_buf_t buf; 3063 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3064 3065 buf = wmi_buf_alloc(wmi_handle, len); 3066 if (!buf) 3067 return -QDF_STATUS_E_NOMEM; 3068 3069 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3070 WMITLV_SET_HDR(&cmd->tlv_header, 3071 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3072 WMITLV_GET_STRUCT_TLVLEN 3073 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3074 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3075 cmd->evlist = 0; 3076 for (idx = 0; idx < max_idx; idx++) { 3077 if (PKTLOG_EVENT & (1 << idx)) 3078 cmd->evlist |= pktlog_event_tlv[idx]; 3079 } 3080 cmd->pdev_id = mac_id; 3081 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3082 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3083 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3084 if (ret) { 3085 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3086 wmi_buf_free(buf); 3087 } 3088 3089 return ret; 3090 } 3091 3092 /** 3093 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3094 * @param wmi_handle : handle to WMI. 3095 * @mac_id: mac id to have radio context 3096 * 3097 * Return: 0 on success and -ve on failure. 3098 */ 3099 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3100 uint8_t mac_id) 3101 { 3102 int32_t ret; 3103 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3104 wmi_buf_t buf; 3105 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3106 3107 buf = wmi_buf_alloc(wmi_handle, len); 3108 if (!buf) 3109 return -QDF_STATUS_E_NOMEM; 3110 3111 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3112 WMITLV_SET_HDR(&cmd->tlv_header, 3113 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3114 WMITLV_GET_STRUCT_TLVLEN 3115 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3116 cmd->pdev_id = mac_id; 3117 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3118 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3119 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3120 if (ret) { 3121 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3122 wmi_buf_free(buf); 3123 } 3124 3125 return ret; 3126 } 3127 3128 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3129 /** 3130 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3131 * sync time between bwtween host and firmware 3132 * @param wmi_handle : handle to WMI. 3133 * 3134 * Return: None 3135 */ 3136 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3137 { 3138 wmi_buf_t buf; 3139 QDF_STATUS status = QDF_STATUS_SUCCESS; 3140 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3141 int32_t len; 3142 qdf_time_t time_ms; 3143 3144 len = sizeof(*time_stamp); 3145 buf = wmi_buf_alloc(wmi_handle, len); 3146 3147 if (!buf) 3148 return; 3149 3150 time_stamp = 3151 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3152 (wmi_buf_data(buf)); 3153 WMITLV_SET_HDR(&time_stamp->tlv_header, 3154 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3155 WMITLV_GET_STRUCT_TLVLEN( 3156 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3157 3158 time_ms = qdf_get_time_of_the_day_ms(); 3159 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3160 time_stamp->time_stamp_low = time_ms & 3161 WMI_FW_TIME_STAMP_LOW_MASK; 3162 /* 3163 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3164 * wont exceed 27 bit 3165 */ 3166 time_stamp->time_stamp_high = 0; 3167 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3168 time_stamp->mode, time_stamp->time_stamp_low, 3169 time_stamp->time_stamp_high); 3170 3171 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3172 status = wmi_unified_cmd_send(wmi_handle, buf, 3173 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3174 if (status) { 3175 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3176 wmi_buf_free(buf); 3177 } 3178 3179 } 3180 3181 /** 3182 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3183 * @param wmi_handle : handle to WMI. 3184 * @param param : pointer to hold FILS Discovery send cmd parameter 3185 * 3186 * Return: 0 on success and -ve on failure. 3187 */ 3188 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3189 struct fils_discovery_tmpl_params *param) 3190 { 3191 int32_t ret; 3192 wmi_fd_tmpl_cmd_fixed_param *cmd; 3193 wmi_buf_t wmi_buf; 3194 uint8_t *buf_ptr; 3195 uint32_t wmi_buf_len; 3196 3197 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3198 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3199 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3200 if (!wmi_buf) 3201 return QDF_STATUS_E_NOMEM; 3202 3203 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3204 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3205 WMITLV_SET_HDR(&cmd->tlv_header, 3206 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3207 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3208 cmd->vdev_id = param->vdev_id; 3209 cmd->buf_len = param->tmpl_len; 3210 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3211 3212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3213 buf_ptr += WMI_TLV_HDR_SIZE; 3214 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3215 3216 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3217 ret = wmi_unified_cmd_send(wmi_handle, 3218 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3219 3220 if (ret) { 3221 wmi_err("Failed to send fd tmpl: %d", ret); 3222 wmi_buf_free(wmi_buf); 3223 return ret; 3224 } 3225 3226 return 0; 3227 } 3228 3229 /** 3230 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 3231 * @param wmi_handle : handle to WMI. 3232 * @param param : pointer to hold beacon send cmd parameter 3233 * 3234 * Return: 0 on success and -ve on failure. 3235 */ 3236 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3237 struct beacon_tmpl_params *param) 3238 { 3239 int32_t ret; 3240 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3241 wmi_bcn_prb_info *bcn_prb_info; 3242 wmi_buf_t wmi_buf; 3243 uint8_t *buf_ptr; 3244 uint32_t wmi_buf_len; 3245 3246 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3247 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3248 param->tmpl_len_aligned + 3249 bcn_tmpl_mlo_param_size(param) + 3250 bcn_tmpl_ml_info_size(param); 3251 3252 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3253 if (!wmi_buf) 3254 return QDF_STATUS_E_NOMEM; 3255 3256 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3257 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3258 WMITLV_SET_HDR(&cmd->tlv_header, 3259 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3260 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3261 cmd->vdev_id = param->vdev_id; 3262 cmd->tim_ie_offset = param->tim_ie_offset; 3263 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3264 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3265 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3266 cmd->esp_ie_offset = param->esp_ie_offset; 3267 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3268 cmd->ema_params = param->ema_params; 3269 cmd->buf_len = param->tmpl_len; 3270 cmd->csa_event_bitmap = param->csa_event_bitmap; 3271 3272 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3273 param->enable_bigtk); 3274 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3275 3276 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3277 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3278 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3279 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3280 bcn_prb_info->caps = 0; 3281 bcn_prb_info->erp = 0; 3282 buf_ptr += sizeof(wmi_bcn_prb_info); 3283 3284 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3285 buf_ptr += WMI_TLV_HDR_SIZE; 3286 3287 /* for big endian host, copy engine byte_swap is enabled 3288 * But the frame content is in network byte order 3289 * Need to byte swap the frame content - so when copy engine 3290 * does byte_swap - target gets frame content in the correct order 3291 */ 3292 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3293 param->tmpl_len); 3294 3295 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3296 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3297 3298 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3299 3300 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3301 ret = wmi_unified_cmd_send(wmi_handle, 3302 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3303 if (ret) { 3304 wmi_err("Failed to send bcn tmpl: %d", ret); 3305 wmi_buf_free(wmi_buf); 3306 } 3307 3308 return 0; 3309 } 3310 3311 #ifdef WLAN_FEATURE_11BE 3312 static inline void copy_peer_flags_tlv_11be( 3313 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3314 struct peer_assoc_params *param) 3315 { 3316 if (param->bw_320) 3317 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3318 if (param->eht_flag) 3319 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3320 3321 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3322 } 3323 #else 3324 static inline void copy_peer_flags_tlv_11be( 3325 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3326 struct peer_assoc_params *param) 3327 { 3328 } 3329 #endif 3330 3331 static inline void copy_peer_flags_tlv( 3332 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3333 struct peer_assoc_params *param) 3334 { 3335 /* 3336 * The target only needs a subset of the flags maintained in the host. 3337 * Just populate those flags and send it down 3338 */ 3339 cmd->peer_flags = 0; 3340 if (param->peer_dms_capable) 3341 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3342 /* 3343 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3344 */ 3345 if (param->is_wme_set) { 3346 3347 if (param->qos_flag) 3348 cmd->peer_flags |= WMI_PEER_QOS; 3349 if (param->apsd_flag) 3350 cmd->peer_flags |= WMI_PEER_APSD; 3351 if (param->ht_flag) 3352 cmd->peer_flags |= WMI_PEER_HT; 3353 if (param->bw_40) 3354 cmd->peer_flags |= WMI_PEER_40MHZ; 3355 if (param->bw_80) 3356 cmd->peer_flags |= WMI_PEER_80MHZ; 3357 if (param->bw_160) 3358 cmd->peer_flags |= WMI_PEER_160MHZ; 3359 3360 copy_peer_flags_tlv_11be(cmd, param); 3361 3362 /* Typically if STBC is enabled for VHT it should be enabled 3363 * for HT as well 3364 **/ 3365 if (param->stbc_flag) 3366 cmd->peer_flags |= WMI_PEER_STBC; 3367 3368 /* Typically if LDPC is enabled for VHT it should be enabled 3369 * for HT as well 3370 **/ 3371 if (param->ldpc_flag) 3372 cmd->peer_flags |= WMI_PEER_LDPC; 3373 3374 if (param->static_mimops_flag) 3375 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3376 if (param->dynamic_mimops_flag) 3377 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3378 if (param->spatial_mux_flag) 3379 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3380 if (param->vht_flag) 3381 cmd->peer_flags |= WMI_PEER_VHT; 3382 if (param->he_flag) 3383 cmd->peer_flags |= WMI_PEER_HE; 3384 if (param->p2p_capable_sta) 3385 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3386 } 3387 3388 if (param->is_pmf_enabled) 3389 cmd->peer_flags |= WMI_PEER_PMF; 3390 /* 3391 * Suppress authorization for all AUTH modes that need 4-way handshake 3392 * (during re-association). 3393 * Authorization will be done for these modes on key installation. 3394 */ 3395 if (param->auth_flag) 3396 cmd->peer_flags |= WMI_PEER_AUTH; 3397 if (param->need_ptk_4_way) 3398 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3399 else 3400 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3401 if (param->need_gtk_2_way) 3402 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3403 /* safe mode bypass the 4-way handshake */ 3404 if (param->safe_mode_enabled) 3405 cmd->peer_flags &= 3406 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3407 /* inter BSS peer */ 3408 if (param->inter_bss_peer) 3409 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3410 /* Disable AMSDU for station transmit, if user configures it */ 3411 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3412 * it 3413 * if (param->amsdu_disable) Add after FW support 3414 **/ 3415 3416 /* Target asserts if node is marked HT and all MCS is set to 0. 3417 * Mark the node as non-HT if all the mcs rates are disabled through 3418 * iwpriv 3419 **/ 3420 if (param->peer_ht_rates.num_rates == 0) 3421 cmd->peer_flags &= ~WMI_PEER_HT; 3422 3423 if (param->twt_requester) 3424 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3425 3426 if (param->twt_responder) 3427 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3428 } 3429 3430 static inline void copy_peer_mac_addr_tlv( 3431 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3432 struct peer_assoc_params *param) 3433 { 3434 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3435 } 3436 3437 #ifdef WLAN_FEATURE_11BE 3438 static uint8_t *update_peer_flags_tlv_ehtinfo( 3439 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3440 struct peer_assoc_params *param, uint8_t *buf_ptr) 3441 { 3442 wmi_eht_rate_set *eht_mcs; 3443 int i; 3444 3445 cmd->peer_eht_ops = param->peer_eht_ops; 3446 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3447 3448 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3449 sizeof(param->peer_eht_cap_macinfo)); 3450 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3451 sizeof(param->peer_eht_cap_phyinfo)); 3452 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3453 sizeof(param->peer_eht_ppet)); 3454 3455 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3456 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3457 buf_ptr += WMI_TLV_HDR_SIZE; 3458 3459 /* Loop through the EHT rate set */ 3460 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3461 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3462 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3463 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3464 3465 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3466 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3467 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3468 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3469 buf_ptr += sizeof(wmi_eht_rate_set); 3470 } 3471 3472 wmi_debug("nss %d ru mask 0x%x", 3473 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3474 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3475 wmi_debug("ppet idx %d ppet %x ", 3476 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3477 } 3478 3479 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3480 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3481 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3482 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3483 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3484 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3485 param->peer_eht_tx_mcs_set 3486 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3487 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3488 param->peer_eht_rx_mcs_set 3489 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3490 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3491 QDF_MAC_ADDR_REF(param->peer_mac)); 3492 } 3493 3494 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3495 cmd->peer_eht_cap_mac[0], 3496 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3497 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 3498 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3499 3500 return buf_ptr; 3501 } 3502 #else 3503 static uint8_t *update_peer_flags_tlv_ehtinfo( 3504 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3505 struct peer_assoc_params *param, uint8_t *buf_ptr) 3506 { 3507 return buf_ptr; 3508 } 3509 #endif 3510 3511 #ifdef WLAN_FEATURE_11BE 3512 static 3513 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3514 { 3515 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3516 + WMI_TLV_HDR_SIZE); 3517 } 3518 3519 static void wmi_populate_service_11be(uint32_t *wmi_service) 3520 { 3521 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3522 } 3523 3524 #else 3525 static 3526 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3527 { 3528 return 0; 3529 } 3530 3531 static void wmi_populate_service_11be(uint32_t *wmi_service) 3532 { 3533 } 3534 3535 #endif 3536 3537 /** 3538 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3539 * @param wmi_handle : handle to WMI. 3540 * @param param : pointer to peer assoc parameter 3541 * 3542 * Return: 0 on success and -ve on failure. 3543 */ 3544 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3545 struct peer_assoc_params *param) 3546 { 3547 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3548 wmi_vht_rate_set *mcs; 3549 wmi_he_rate_set *he_mcs; 3550 wmi_buf_t buf; 3551 int32_t len; 3552 uint8_t *buf_ptr; 3553 QDF_STATUS ret; 3554 uint32_t peer_legacy_rates_align; 3555 uint32_t peer_ht_rates_align; 3556 int32_t i; 3557 3558 3559 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3560 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3561 3562 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3563 (peer_legacy_rates_align * sizeof(uint8_t)) + 3564 WMI_TLV_HDR_SIZE + 3565 (peer_ht_rates_align * sizeof(uint8_t)) + 3566 sizeof(wmi_vht_rate_set) + 3567 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3568 + WMI_TLV_HDR_SIZE) 3569 + wmi_eht_peer_assoc_params_len(param) + 3570 peer_assoc_mlo_params_size(param) + 3571 peer_assoc_t2lm_params_size(param); 3572 3573 buf = wmi_buf_alloc(wmi_handle, len); 3574 if (!buf) 3575 return QDF_STATUS_E_NOMEM; 3576 3577 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3578 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3579 WMITLV_SET_HDR(&cmd->tlv_header, 3580 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3581 WMITLV_GET_STRUCT_TLVLEN 3582 (wmi_peer_assoc_complete_cmd_fixed_param)); 3583 3584 cmd->vdev_id = param->vdev_id; 3585 3586 cmd->peer_new_assoc = param->peer_new_assoc; 3587 cmd->peer_associd = param->peer_associd; 3588 3589 copy_peer_flags_tlv(cmd, param); 3590 copy_peer_mac_addr_tlv(cmd, param); 3591 3592 cmd->peer_rate_caps = param->peer_rate_caps; 3593 cmd->peer_caps = param->peer_caps; 3594 cmd->peer_listen_intval = param->peer_listen_intval; 3595 cmd->peer_ht_caps = param->peer_ht_caps; 3596 cmd->peer_max_mpdu = param->peer_max_mpdu; 3597 cmd->peer_mpdu_density = param->peer_mpdu_density; 3598 cmd->peer_vht_caps = param->peer_vht_caps; 3599 cmd->peer_phymode = param->peer_phymode; 3600 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3601 3602 /* Update 11ax capabilities */ 3603 cmd->peer_he_cap_info = 3604 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3605 cmd->peer_he_cap_info_ext = 3606 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3607 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3608 cmd->peer_he_ops = param->peer_he_ops; 3609 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3610 sizeof(param->peer_he_cap_phyinfo)); 3611 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3612 sizeof(param->peer_ppet)); 3613 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3614 3615 /* Update peer legacy rate information */ 3616 buf_ptr += sizeof(*cmd); 3617 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3618 peer_legacy_rates_align); 3619 buf_ptr += WMI_TLV_HDR_SIZE; 3620 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3621 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3622 param->peer_legacy_rates.num_rates); 3623 3624 /* Update peer HT rate information */ 3625 buf_ptr += peer_legacy_rates_align; 3626 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3627 peer_ht_rates_align); 3628 buf_ptr += WMI_TLV_HDR_SIZE; 3629 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3630 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3631 param->peer_ht_rates.num_rates); 3632 3633 /* VHT Rates */ 3634 buf_ptr += peer_ht_rates_align; 3635 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3636 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3637 3638 cmd->auth_mode = param->akm; 3639 cmd->peer_nss = param->peer_nss; 3640 3641 /* Update bandwidth-NSS mapping */ 3642 cmd->peer_bw_rxnss_override = 0; 3643 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3644 3645 mcs = (wmi_vht_rate_set *) buf_ptr; 3646 if (param->vht_capable) { 3647 mcs->rx_max_rate = param->rx_max_rate; 3648 mcs->rx_mcs_set = param->rx_mcs_set; 3649 mcs->tx_max_rate = param->tx_max_rate; 3650 mcs->tx_mcs_set = param->tx_mcs_set; 3651 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3652 } 3653 3654 /* HE Rates */ 3655 cmd->min_data_rate = param->min_data_rate; 3656 cmd->peer_he_mcs = param->peer_he_mcs_count; 3657 buf_ptr += sizeof(wmi_vht_rate_set); 3658 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3659 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3660 buf_ptr += WMI_TLV_HDR_SIZE; 3661 3662 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3663 /* Loop through the HE rate set */ 3664 for (i = 0; i < param->peer_he_mcs_count; i++) { 3665 he_mcs = (wmi_he_rate_set *) buf_ptr; 3666 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3667 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3668 3669 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3670 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3671 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3672 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3673 buf_ptr += sizeof(wmi_he_rate_set); 3674 } 3675 3676 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3677 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3678 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3679 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3680 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3681 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3682 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3683 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3684 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3685 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3686 QDF_MAC_ADDR_REF(param->peer_mac)); 3687 } 3688 3689 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3690 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3691 "nss %d phymode %d peer_mpdu_density %d " 3692 "cmd->peer_vht_caps %x " 3693 "HE cap_info %x ops %x " 3694 "HE cap_info_ext %x " 3695 "HE phy %x %x %x " 3696 "peer_bw_rxnss_override %x", 3697 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3698 cmd->peer_rate_caps, cmd->peer_caps, 3699 cmd->peer_listen_intval, cmd->peer_ht_caps, 3700 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3701 cmd->peer_mpdu_density, 3702 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3703 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3704 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3705 cmd->peer_he_cap_phy[2], 3706 cmd->peer_bw_rxnss_override); 3707 3708 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3709 3710 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3711 3712 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3713 3714 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3715 3716 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3717 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3718 WMI_PEER_ASSOC_CMDID); 3719 if (QDF_IS_STATUS_ERROR(ret)) { 3720 wmi_err("Failed to send peer assoc command ret = %d", ret); 3721 wmi_buf_free(buf); 3722 } 3723 3724 return ret; 3725 } 3726 3727 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3728 */ 3729 static inline void copy_scan_event_cntrl_flags( 3730 wmi_start_scan_cmd_fixed_param * cmd, 3731 struct scan_req_params *param) 3732 { 3733 3734 /* Scan events subscription */ 3735 if (param->scan_ev_started) 3736 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3737 if (param->scan_ev_completed) 3738 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3739 if (param->scan_ev_bss_chan) 3740 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3741 if (param->scan_ev_foreign_chan) 3742 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3743 if (param->scan_ev_dequeued) 3744 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3745 if (param->scan_ev_preempted) 3746 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3747 if (param->scan_ev_start_failed) 3748 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3749 if (param->scan_ev_restarted) 3750 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3751 if (param->scan_ev_foreign_chn_exit) 3752 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3753 if (param->scan_ev_suspended) 3754 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3755 if (param->scan_ev_resumed) 3756 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3757 3758 /** Set scan control flags */ 3759 cmd->scan_ctrl_flags = 0; 3760 if (param->scan_f_passive) 3761 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3762 if (param->scan_f_strict_passive_pch) 3763 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3764 if (param->scan_f_promisc_mode) 3765 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3766 if (param->scan_f_capture_phy_err) 3767 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3768 if (param->scan_f_half_rate) 3769 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3770 if (param->scan_f_quarter_rate) 3771 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3772 if (param->scan_f_cck_rates) 3773 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3774 if (param->scan_f_ofdm_rates) 3775 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3776 if (param->scan_f_chan_stat_evnt) 3777 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3778 if (param->scan_f_filter_prb_req) 3779 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3780 if (param->scan_f_bcast_probe) 3781 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3782 if (param->scan_f_offchan_mgmt_tx) 3783 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3784 if (param->scan_f_offchan_data_tx) 3785 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3786 if (param->scan_f_force_active_dfs_chn) 3787 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3788 if (param->scan_f_add_tpc_ie_in_probe) 3789 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3790 if (param->scan_f_add_ds_ie_in_probe) 3791 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3792 if (param->scan_f_add_spoofed_mac_in_probe) 3793 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3794 if (param->scan_f_add_rand_seq_in_probe) 3795 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3796 if (param->scan_f_en_ie_allowlist_in_probe) 3797 cmd->scan_ctrl_flags |= 3798 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3799 3800 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3801 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3802 param->adaptive_dwell_time_mode); 3803 } 3804 3805 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3806 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3807 struct scan_req_params *params) 3808 { 3809 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3810 } 3811 3812 /** 3813 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3814 * @mac: random mac addr 3815 * @mask: random mac mask 3816 * @mac_addr: wmi random mac 3817 * @mac_mask: wmi random mac mask 3818 * 3819 * Return None. 3820 */ 3821 static inline 3822 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3823 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3824 { 3825 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3826 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3827 } 3828 3829 /* 3830 * wmi_fill_vendor_oui() - fill vendor OUIs 3831 * @buf_ptr: pointer to wmi tlv buffer 3832 * @num_vendor_oui: number of vendor OUIs to be filled 3833 * @param_voui: pointer to OUI buffer 3834 * 3835 * This function populates the wmi tlv buffer when vendor specific OUIs are 3836 * present. 3837 * 3838 * Return: None 3839 */ 3840 static inline 3841 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3842 uint32_t *pvoui) 3843 { 3844 wmi_vendor_oui *voui = NULL; 3845 uint32_t i; 3846 3847 voui = (wmi_vendor_oui *)buf_ptr; 3848 3849 for (i = 0; i < num_vendor_oui; i++) { 3850 WMITLV_SET_HDR(&voui[i].tlv_header, 3851 WMITLV_TAG_STRUC_wmi_vendor_oui, 3852 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3853 voui[i].oui_type_subtype = pvoui[i]; 3854 } 3855 } 3856 3857 /* 3858 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3859 * @ie_bitmap: output pointer to ie bit map in cmd 3860 * @num_vendor_oui: output pointer to num vendor OUIs 3861 * @ie_allowlist: input parameter 3862 * 3863 * This function populates the IE allowlist attrs of scan, pno and 3864 * scan oui commands for ie_allowlist parameter. 3865 * 3866 * Return: None 3867 */ 3868 static inline 3869 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3870 uint32_t *num_vendor_oui, 3871 struct probe_req_allowlist_attr *ie_allowlist) 3872 { 3873 uint32_t i = 0; 3874 3875 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3876 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3877 3878 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3879 } 3880 3881 /** 3882 * send_scan_start_cmd_tlv() - WMI scan start function 3883 * @param wmi_handle : handle to WMI. 3884 * @param param : pointer to hold scan start cmd parameter 3885 * 3886 * Return: 0 on success and -ve on failure. 3887 */ 3888 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3889 struct scan_req_params *params) 3890 { 3891 int32_t ret = 0; 3892 int32_t i; 3893 wmi_buf_t wmi_buf; 3894 wmi_start_scan_cmd_fixed_param *cmd; 3895 uint8_t *buf_ptr; 3896 uint32_t *tmp_ptr; 3897 wmi_ssid *ssid = NULL; 3898 wmi_mac_addr *bssid; 3899 size_t len = sizeof(*cmd); 3900 uint16_t extraie_len_with_pad = 0; 3901 uint8_t phymode_roundup = 0; 3902 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3903 wmi_hint_freq_short_ssid *s_ssid = NULL; 3904 wmi_hint_freq_bssid *hint_bssid = NULL; 3905 3906 /* Length TLV placeholder for array of uint32_t */ 3907 len += WMI_TLV_HDR_SIZE; 3908 /* calculate the length of buffer required */ 3909 if (params->chan_list.num_chan) 3910 len += params->chan_list.num_chan * sizeof(uint32_t); 3911 3912 /* Length TLV placeholder for array of wmi_ssid structures */ 3913 len += WMI_TLV_HDR_SIZE; 3914 if (params->num_ssids) 3915 len += params->num_ssids * sizeof(wmi_ssid); 3916 3917 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3918 len += WMI_TLV_HDR_SIZE; 3919 if (params->num_bssid) 3920 len += sizeof(wmi_mac_addr) * params->num_bssid; 3921 3922 /* Length TLV placeholder for array of bytes */ 3923 len += WMI_TLV_HDR_SIZE; 3924 if (params->extraie.len) 3925 extraie_len_with_pad = 3926 roundup(params->extraie.len, sizeof(uint32_t)); 3927 len += extraie_len_with_pad; 3928 3929 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3930 if (ie_allowlist->num_vendor_oui) 3931 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3932 3933 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3934 if (params->scan_f_wide_band) 3935 phymode_roundup = 3936 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3937 sizeof(uint32_t)); 3938 len += phymode_roundup; 3939 3940 len += WMI_TLV_HDR_SIZE; 3941 if (params->num_hint_bssid) 3942 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3943 3944 len += WMI_TLV_HDR_SIZE; 3945 if (params->num_hint_s_ssid) 3946 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3947 3948 /* Allocate the memory */ 3949 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3950 if (!wmi_buf) 3951 return QDF_STATUS_E_FAILURE; 3952 3953 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3954 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3955 WMITLV_SET_HDR(&cmd->tlv_header, 3956 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3957 WMITLV_GET_STRUCT_TLVLEN 3958 (wmi_start_scan_cmd_fixed_param)); 3959 3960 cmd->scan_id = params->scan_id; 3961 cmd->scan_req_id = params->scan_req_id; 3962 cmd->vdev_id = params->vdev_id; 3963 cmd->scan_priority = params->scan_priority; 3964 3965 copy_scan_event_cntrl_flags(cmd, params); 3966 3967 cmd->dwell_time_active = params->dwell_time_active; 3968 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3969 cmd->dwell_time_passive = params->dwell_time_passive; 3970 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3971 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3972 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3973 cmd->scan_start_offset = params->scan_offset_time; 3974 cmd->min_rest_time = params->min_rest_time; 3975 cmd->max_rest_time = params->max_rest_time; 3976 cmd->repeat_probe_time = params->repeat_probe_time; 3977 cmd->probe_spacing_time = params->probe_spacing_time; 3978 cmd->idle_time = params->idle_time; 3979 cmd->max_scan_time = params->max_scan_time; 3980 cmd->probe_delay = params->probe_delay; 3981 cmd->burst_duration = params->burst_duration; 3982 cmd->num_chan = params->chan_list.num_chan; 3983 cmd->num_bssid = params->num_bssid; 3984 cmd->num_ssids = params->num_ssids; 3985 cmd->ie_len = params->extraie.len; 3986 cmd->n_probes = params->n_probes; 3987 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3988 3989 if (params->scan_random.randomize) 3990 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3991 params->scan_random.mac_mask, 3992 &cmd->mac_addr, 3993 &cmd->mac_mask); 3994 3995 if (ie_allowlist->allow_list) 3996 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 3997 &cmd->num_vendor_oui, 3998 ie_allowlist); 3999 4000 buf_ptr += sizeof(*cmd); 4001 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4002 for (i = 0; i < params->chan_list.num_chan; ++i) { 4003 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4004 params->chan_list.chan[i].freq); 4005 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4006 params->chan_list.chan[i].flags); 4007 } 4008 4009 WMITLV_SET_HDR(buf_ptr, 4010 WMITLV_TAG_ARRAY_UINT32, 4011 (params->chan_list.num_chan * sizeof(uint32_t))); 4012 buf_ptr += WMI_TLV_HDR_SIZE + 4013 (params->chan_list.num_chan * sizeof(uint32_t)); 4014 4015 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4016 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4017 goto error; 4018 } 4019 4020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4021 (params->num_ssids * sizeof(wmi_ssid))); 4022 4023 if (params->num_ssids) { 4024 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4025 for (i = 0; i < params->num_ssids; ++i) { 4026 ssid->ssid_len = params->ssid[i].length; 4027 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4028 params->ssid[i].length); 4029 ssid++; 4030 } 4031 } 4032 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4033 4034 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4035 (params->num_bssid * sizeof(wmi_mac_addr))); 4036 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4037 4038 if (params->num_bssid) { 4039 for (i = 0; i < params->num_bssid; ++i) { 4040 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4041 ¶ms->bssid_list[i].bytes[0], bssid); 4042 bssid++; 4043 } 4044 } 4045 4046 buf_ptr += WMI_TLV_HDR_SIZE + 4047 (params->num_bssid * sizeof(wmi_mac_addr)); 4048 4049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4050 if (params->extraie.len) 4051 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4052 params); 4053 4054 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4055 4056 /* probe req ie allowlisting */ 4057 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4058 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4059 4060 buf_ptr += WMI_TLV_HDR_SIZE; 4061 4062 if (cmd->num_vendor_oui) { 4063 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4064 ie_allowlist->voui); 4065 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4066 } 4067 4068 /* Add phy mode TLV if it's a wide band scan */ 4069 if (params->scan_f_wide_band) { 4070 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4071 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4072 for (i = 0; i < params->chan_list.num_chan; ++i) 4073 buf_ptr[i] = 4074 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4075 buf_ptr += phymode_roundup; 4076 } else { 4077 /* Add ZERO legth phy mode TLV */ 4078 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4079 buf_ptr += WMI_TLV_HDR_SIZE; 4080 } 4081 4082 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4083 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4084 if (params->num_hint_s_ssid) { 4085 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4086 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4087 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4088 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4089 s_ssid++; 4090 } 4091 } 4092 buf_ptr += WMI_TLV_HDR_SIZE + 4093 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4094 4095 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4096 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4097 if (params->num_hint_bssid) { 4098 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4099 for (i = 0; i < params->num_hint_bssid; ++i) { 4100 hint_bssid->freq_flags = 4101 params->hint_bssid[i].freq_flags; 4102 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4103 &hint_bssid->bssid); 4104 hint_bssid++; 4105 } 4106 } 4107 4108 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4109 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4110 len, WMI_START_SCAN_CMDID); 4111 if (ret) { 4112 wmi_err("Failed to start scan: %d", ret); 4113 wmi_buf_free(wmi_buf); 4114 } 4115 return ret; 4116 error: 4117 wmi_buf_free(wmi_buf); 4118 return QDF_STATUS_E_FAILURE; 4119 } 4120 4121 /** 4122 * send_scan_stop_cmd_tlv() - WMI scan start function 4123 * @param wmi_handle : handle to WMI. 4124 * @param param : pointer to hold scan cancel cmd parameter 4125 * 4126 * Return: 0 on success and -ve on failure. 4127 */ 4128 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4129 struct scan_cancel_param *param) 4130 { 4131 wmi_stop_scan_cmd_fixed_param *cmd; 4132 int ret; 4133 int len = sizeof(*cmd); 4134 wmi_buf_t wmi_buf; 4135 4136 /* Allocate the memory */ 4137 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4138 if (!wmi_buf) { 4139 ret = QDF_STATUS_E_NOMEM; 4140 goto error; 4141 } 4142 4143 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4144 WMITLV_SET_HDR(&cmd->tlv_header, 4145 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4146 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4147 cmd->vdev_id = param->vdev_id; 4148 cmd->requestor = param->requester; 4149 cmd->scan_id = param->scan_id; 4150 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4151 wmi_handle, 4152 param->pdev_id); 4153 /* stop the scan with the corresponding scan_id */ 4154 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4155 /* Cancelling all scans */ 4156 cmd->req_type = WMI_SCAN_STOP_ALL; 4157 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4158 /* Cancelling VAP scans */ 4159 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4160 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4161 /* Cancelling specific scan */ 4162 cmd->req_type = WMI_SCAN_STOP_ONE; 4163 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4164 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4165 } else { 4166 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4167 wmi_buf_free(wmi_buf); 4168 return QDF_STATUS_E_INVAL; 4169 } 4170 4171 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4172 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4173 len, WMI_STOP_SCAN_CMDID); 4174 if (ret) { 4175 wmi_err("Failed to send stop scan: %d", ret); 4176 wmi_buf_free(wmi_buf); 4177 } 4178 4179 error: 4180 return ret; 4181 } 4182 4183 #define WMI_MAX_CHAN_INFO_LOG 192 4184 4185 /** 4186 * wmi_scan_chanlist_dump() - Dump scan channel list info 4187 * @scan_chan_list: scan channel list 4188 * 4189 * Return: void 4190 */ 4191 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4192 { 4193 uint32_t i; 4194 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4195 uint32_t len = 0; 4196 struct channel_param *chan; 4197 int ret; 4198 4199 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4200 for (i = 0; i < scan_chan_list->nallchans; i++) { 4201 chan = &scan_chan_list->ch_param[i]; 4202 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4203 " %d[%d][%d][%d]", chan->mhz, 4204 chan->maxregpower, 4205 chan->dfs_set, chan->nan_disabled); 4206 if (ret <= 0) 4207 break; 4208 len += ret; 4209 if (len >= (sizeof(info) - 20)) { 4210 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4211 info); 4212 len = 0; 4213 } 4214 } 4215 if (len) 4216 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4217 } 4218 4219 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4220 struct scan_chan_list_params *chan_list) 4221 { 4222 wmi_buf_t buf; 4223 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4224 wmi_scan_chan_list_cmd_fixed_param *cmd; 4225 int i; 4226 uint8_t *buf_ptr; 4227 wmi_channel *chan_info; 4228 struct channel_param *tchan_info; 4229 uint16_t len; 4230 uint16_t num_send_chans, num_sends = 0; 4231 4232 wmi_scan_chanlist_dump(chan_list); 4233 tchan_info = &chan_list->ch_param[0]; 4234 while (chan_list->nallchans) { 4235 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4236 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4237 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4238 else 4239 num_send_chans = chan_list->nallchans; 4240 4241 chan_list->nallchans -= num_send_chans; 4242 len += sizeof(wmi_channel) * num_send_chans; 4243 buf = wmi_buf_alloc(wmi_handle, len); 4244 if (!buf) { 4245 qdf_status = QDF_STATUS_E_NOMEM; 4246 goto end; 4247 } 4248 4249 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4250 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4251 WMITLV_SET_HDR(&cmd->tlv_header, 4252 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4253 WMITLV_GET_STRUCT_TLVLEN 4254 (wmi_scan_chan_list_cmd_fixed_param)); 4255 4256 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4257 4258 if (num_sends) 4259 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4260 4261 if (chan_list->max_bw_support_present) 4262 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4263 4264 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4265 wmi_handle, 4266 chan_list->pdev_id); 4267 4268 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4269 4270 cmd->num_scan_chans = num_send_chans; 4271 WMITLV_SET_HDR((buf_ptr + 4272 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4273 WMITLV_TAG_ARRAY_STRUC, 4274 sizeof(wmi_channel) * num_send_chans); 4275 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4276 WMI_TLV_HDR_SIZE); 4277 4278 for (i = 0; i < num_send_chans; ++i) { 4279 WMITLV_SET_HDR(&chan_info->tlv_header, 4280 WMITLV_TAG_STRUC_wmi_channel, 4281 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4282 chan_info->mhz = tchan_info->mhz; 4283 chan_info->band_center_freq1 = 4284 tchan_info->cfreq1; 4285 chan_info->band_center_freq2 = 4286 tchan_info->cfreq2; 4287 4288 if (tchan_info->is_chan_passive) 4289 WMI_SET_CHANNEL_FLAG(chan_info, 4290 WMI_CHAN_FLAG_PASSIVE); 4291 if (tchan_info->dfs_set) 4292 WMI_SET_CHANNEL_FLAG(chan_info, 4293 WMI_CHAN_FLAG_DFS); 4294 4295 if (tchan_info->dfs_set_cfreq2) 4296 WMI_SET_CHANNEL_FLAG(chan_info, 4297 WMI_CHAN_FLAG_DFS_CFREQ2); 4298 4299 if (tchan_info->allow_he) 4300 WMI_SET_CHANNEL_FLAG(chan_info, 4301 WMI_CHAN_FLAG_ALLOW_HE); 4302 4303 if (tchan_info->allow_eht) 4304 WMI_SET_CHANNEL_FLAG(chan_info, 4305 WMI_CHAN_FLAG_ALLOW_EHT); 4306 4307 if (tchan_info->allow_vht) 4308 WMI_SET_CHANNEL_FLAG(chan_info, 4309 WMI_CHAN_FLAG_ALLOW_VHT); 4310 4311 if (tchan_info->allow_ht) 4312 WMI_SET_CHANNEL_FLAG(chan_info, 4313 WMI_CHAN_FLAG_ALLOW_HT); 4314 WMI_SET_CHANNEL_MODE(chan_info, 4315 tchan_info->phy_mode); 4316 4317 if (tchan_info->half_rate) 4318 WMI_SET_CHANNEL_FLAG(chan_info, 4319 WMI_CHAN_FLAG_HALF_RATE); 4320 4321 if (tchan_info->quarter_rate) 4322 WMI_SET_CHANNEL_FLAG(chan_info, 4323 WMI_CHAN_FLAG_QUARTER_RATE); 4324 4325 if (tchan_info->psc_channel) 4326 WMI_SET_CHANNEL_FLAG(chan_info, 4327 WMI_CHAN_FLAG_PSC); 4328 4329 if (tchan_info->nan_disabled) 4330 WMI_SET_CHANNEL_FLAG(chan_info, 4331 WMI_CHAN_FLAG_NAN_DISABLED); 4332 4333 /* also fill in power information */ 4334 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4335 tchan_info->minpower); 4336 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4337 tchan_info->maxpower); 4338 WMI_SET_CHANNEL_REG_POWER(chan_info, 4339 tchan_info->maxregpower); 4340 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4341 tchan_info->antennamax); 4342 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4343 tchan_info->reg_class_id); 4344 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4345 tchan_info->maxregpower); 4346 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4347 tchan_info->max_bw_supported); 4348 4349 tchan_info++; 4350 chan_info++; 4351 } 4352 4353 qdf_status = wmi_unified_cmd_send( 4354 wmi_handle, 4355 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4356 4357 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4358 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4359 wmi_buf_free(buf); 4360 goto end; 4361 } 4362 num_sends++; 4363 } 4364 4365 end: 4366 return qdf_status; 4367 } 4368 4369 /** 4370 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4371 * 4372 * @bufp: Pointer to buffer 4373 * @param: Pointer to tx param 4374 * 4375 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4376 */ 4377 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4378 struct tx_send_params param) 4379 { 4380 wmi_tx_send_params *tx_param; 4381 QDF_STATUS status = QDF_STATUS_SUCCESS; 4382 4383 if (!bufp) { 4384 status = QDF_STATUS_E_FAILURE; 4385 return status; 4386 } 4387 tx_param = (wmi_tx_send_params *)bufp; 4388 WMITLV_SET_HDR(&tx_param->tlv_header, 4389 WMITLV_TAG_STRUC_wmi_tx_send_params, 4390 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4391 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4392 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4393 param.mcs_mask); 4394 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4395 param.nss_mask); 4396 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4397 param.retry_limit); 4398 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4399 param.chain_mask); 4400 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4401 param.bw_mask); 4402 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4403 param.preamble_type); 4404 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4405 param.frame_type); 4406 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4407 param.cfr_enable); 4408 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4409 param.en_beamforming); 4410 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4411 param.retry_limit_ext); 4412 4413 return status; 4414 } 4415 4416 #ifdef CONFIG_HL_SUPPORT 4417 /** 4418 * send_mgmt_cmd_tlv() - WMI scan start function 4419 * @wmi_handle : handle to WMI. 4420 * @param : pointer to hold mgmt cmd parameter 4421 * 4422 * Return: 0 on success and -ve on failure. 4423 */ 4424 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4425 struct wmi_mgmt_params *param) 4426 { 4427 wmi_buf_t buf; 4428 uint8_t *bufp; 4429 int32_t cmd_len; 4430 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4431 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4432 mgmt_tx_dl_frm_len; 4433 4434 if (param->frm_len > mgmt_tx_dl_frm_len) { 4435 wmi_err("mgmt frame len %u exceeds %u", 4436 param->frm_len, mgmt_tx_dl_frm_len); 4437 return QDF_STATUS_E_INVAL; 4438 } 4439 4440 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4441 WMI_TLV_HDR_SIZE + 4442 roundup(bufp_len, sizeof(uint32_t)); 4443 4444 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4445 if (!buf) 4446 return QDF_STATUS_E_NOMEM; 4447 4448 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4449 bufp = (uint8_t *) cmd; 4450 WMITLV_SET_HDR(&cmd->tlv_header, 4451 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4452 WMITLV_GET_STRUCT_TLVLEN 4453 (wmi_mgmt_tx_send_cmd_fixed_param)); 4454 4455 cmd->vdev_id = param->vdev_id; 4456 4457 cmd->desc_id = param->desc_id; 4458 cmd->chanfreq = param->chanfreq; 4459 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4460 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4461 sizeof(uint32_t))); 4462 bufp += WMI_TLV_HDR_SIZE; 4463 qdf_mem_copy(bufp, param->pdata, bufp_len); 4464 4465 cmd->frame_len = param->frm_len; 4466 cmd->buf_len = bufp_len; 4467 cmd->tx_params_valid = param->tx_params_valid; 4468 cmd->tx_flags = param->tx_flags; 4469 cmd->peer_rssi = param->peer_rssi; 4470 4471 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4472 bufp, cmd->vdev_id, cmd->chanfreq); 4473 4474 bufp += roundup(bufp_len, sizeof(uint32_t)); 4475 if (param->tx_params_valid) { 4476 if (populate_tx_send_params(bufp, param->tx_param) != 4477 QDF_STATUS_SUCCESS) { 4478 wmi_err("Populate TX send params failed"); 4479 goto free_buf; 4480 } 4481 cmd_len += sizeof(wmi_tx_send_params); 4482 } 4483 4484 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4485 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4486 WMI_MGMT_TX_SEND_CMDID)) { 4487 wmi_err("Failed to send mgmt Tx"); 4488 goto free_buf; 4489 } 4490 return QDF_STATUS_SUCCESS; 4491 4492 free_buf: 4493 wmi_buf_free(buf); 4494 return QDF_STATUS_E_FAILURE; 4495 } 4496 #else 4497 /** 4498 * send_mgmt_cmd_tlv() - WMI scan start function 4499 * @wmi_handle : handle to WMI. 4500 * @param : pointer to hold mgmt cmd parameter 4501 * 4502 * Return: 0 on success and -ve on failure. 4503 */ 4504 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4505 struct wmi_mgmt_params *param) 4506 { 4507 wmi_buf_t buf; 4508 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4509 int32_t cmd_len; 4510 uint64_t dma_addr; 4511 void *qdf_ctx = param->qdf_ctx; 4512 uint8_t *bufp; 4513 QDF_STATUS status = QDF_STATUS_SUCCESS; 4514 wmi_mlo_tx_send_params *mlo_params; 4515 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4516 mgmt_tx_dl_frm_len; 4517 4518 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4519 WMI_TLV_HDR_SIZE + 4520 roundup(bufp_len, sizeof(uint32_t)); 4521 4522 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4523 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4524 if (!buf) 4525 return QDF_STATUS_E_NOMEM; 4526 4527 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4528 bufp = (uint8_t *) cmd; 4529 WMITLV_SET_HDR(&cmd->tlv_header, 4530 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4531 WMITLV_GET_STRUCT_TLVLEN 4532 (wmi_mgmt_tx_send_cmd_fixed_param)); 4533 4534 cmd->vdev_id = param->vdev_id; 4535 4536 cmd->desc_id = param->desc_id; 4537 cmd->chanfreq = param->chanfreq; 4538 cmd->peer_rssi = param->peer_rssi; 4539 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4540 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4541 sizeof(uint32_t))); 4542 bufp += WMI_TLV_HDR_SIZE; 4543 4544 /* for big endian host, copy engine byte_swap is enabled 4545 * But the frame content is in network byte order 4546 * Need to byte swap the frame content - so when copy engine 4547 * does byte_swap - target gets frame content in the correct order 4548 */ 4549 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4550 4551 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4552 QDF_DMA_TO_DEVICE); 4553 if (status != QDF_STATUS_SUCCESS) { 4554 wmi_err("wmi buf map failed"); 4555 goto free_buf; 4556 } 4557 4558 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4559 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4560 #if defined(HTT_PADDR64) 4561 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4562 #endif 4563 cmd->frame_len = param->frm_len; 4564 cmd->buf_len = bufp_len; 4565 cmd->tx_params_valid = param->tx_params_valid; 4566 cmd->tx_flags = param->tx_flags; 4567 4568 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4569 bufp, cmd->vdev_id, cmd->chanfreq); 4570 4571 bufp += roundup(bufp_len, sizeof(uint32_t)); 4572 if (param->tx_params_valid) { 4573 status = populate_tx_send_params(bufp, param->tx_param); 4574 if (status != QDF_STATUS_SUCCESS) { 4575 wmi_err("Populate TX send params failed"); 4576 goto unmap_tx_frame; 4577 } 4578 } else { 4579 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4580 WMITLV_TAG_STRUC_wmi_tx_send_params, 4581 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4582 } 4583 4584 /* Even tx_params_valid is false, still need reserve space to pass wmi 4585 * tag check */ 4586 cmd_len += sizeof(wmi_tx_send_params); 4587 bufp += sizeof(wmi_tx_send_params); 4588 /* wmi_mlo_tx_send_params */ 4589 if (param->mlo_link_agnostic) { 4590 wmi_debug("Set mlo mgmt tid"); 4591 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4592 sizeof(wmi_mlo_tx_send_params)); 4593 bufp += WMI_TLV_HDR_SIZE; 4594 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4595 WMITLV_SET_HDR(&mlo_params->tlv_header, 4596 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4597 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4598 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4599 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4600 } 4601 4602 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4603 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4604 WMI_MGMT_TX_SEND_CMDID)) { 4605 wmi_err("Failed to send mgmt Tx"); 4606 goto unmap_tx_frame; 4607 } 4608 return QDF_STATUS_SUCCESS; 4609 4610 unmap_tx_frame: 4611 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4612 QDF_DMA_TO_DEVICE); 4613 free_buf: 4614 wmi_buf_free(buf); 4615 return QDF_STATUS_E_FAILURE; 4616 } 4617 #endif /* CONFIG_HL_SUPPORT */ 4618 4619 /** 4620 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 4621 * @wmi_handle : handle to WMI. 4622 * @param : pointer to offchan data tx cmd parameter 4623 * 4624 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4625 */ 4626 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4627 struct wmi_offchan_data_tx_params *param) 4628 { 4629 wmi_buf_t buf; 4630 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4631 int32_t cmd_len; 4632 uint64_t dma_addr; 4633 void *qdf_ctx = param->qdf_ctx; 4634 uint8_t *bufp; 4635 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4636 param->frm_len : mgmt_tx_dl_frm_len; 4637 QDF_STATUS status = QDF_STATUS_SUCCESS; 4638 4639 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4640 WMI_TLV_HDR_SIZE + 4641 roundup(bufp_len, sizeof(uint32_t)); 4642 4643 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4644 if (!buf) 4645 return QDF_STATUS_E_NOMEM; 4646 4647 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4648 bufp = (uint8_t *) cmd; 4649 WMITLV_SET_HDR(&cmd->tlv_header, 4650 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4651 WMITLV_GET_STRUCT_TLVLEN 4652 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4653 4654 cmd->vdev_id = param->vdev_id; 4655 4656 cmd->desc_id = param->desc_id; 4657 cmd->chanfreq = param->chanfreq; 4658 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4659 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4660 sizeof(uint32_t))); 4661 bufp += WMI_TLV_HDR_SIZE; 4662 qdf_mem_copy(bufp, param->pdata, bufp_len); 4663 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4664 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4665 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4666 #if defined(HTT_PADDR64) 4667 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4668 #endif 4669 cmd->frame_len = param->frm_len; 4670 cmd->buf_len = bufp_len; 4671 cmd->tx_params_valid = param->tx_params_valid; 4672 4673 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4674 bufp, cmd->vdev_id, cmd->chanfreq); 4675 4676 bufp += roundup(bufp_len, sizeof(uint32_t)); 4677 if (param->tx_params_valid) { 4678 status = populate_tx_send_params(bufp, param->tx_param); 4679 if (status != QDF_STATUS_SUCCESS) { 4680 wmi_err("Populate TX send params failed"); 4681 goto err1; 4682 } 4683 cmd_len += sizeof(wmi_tx_send_params); 4684 } 4685 4686 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4687 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4688 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4689 wmi_err("Failed to offchan data Tx"); 4690 goto err1; 4691 } 4692 4693 return QDF_STATUS_SUCCESS; 4694 4695 err1: 4696 wmi_buf_free(buf); 4697 return QDF_STATUS_E_FAILURE; 4698 } 4699 4700 /** 4701 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4702 * @wmi_handle: wmi handle 4703 * @param_value: parameter value 4704 * 4705 * Return: QDF_STATUS_SUCCESS for success or error code 4706 */ 4707 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4708 uint32_t param_value) 4709 { 4710 QDF_STATUS ret; 4711 wmi_modem_power_state_cmd_param *cmd; 4712 wmi_buf_t buf; 4713 uint16_t len = sizeof(*cmd); 4714 4715 buf = wmi_buf_alloc(wmi_handle, len); 4716 if (!buf) 4717 return QDF_STATUS_E_NOMEM; 4718 4719 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4720 WMITLV_SET_HDR(&cmd->tlv_header, 4721 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4722 WMITLV_GET_STRUCT_TLVLEN 4723 (wmi_modem_power_state_cmd_param)); 4724 cmd->modem_power_state = param_value; 4725 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4726 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4727 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4728 WMI_MODEM_POWER_STATE_CMDID); 4729 if (QDF_IS_STATUS_ERROR(ret)) { 4730 wmi_err("Failed to send notify cmd ret = %d", ret); 4731 wmi_buf_free(buf); 4732 } 4733 4734 return ret; 4735 } 4736 4737 /** 4738 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4739 * @wmi_handle: wmi handle 4740 * @vdev_id: vdev id 4741 * @val: value 4742 * 4743 * Return: QDF_STATUS_SUCCESS for success or error code. 4744 */ 4745 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4746 uint32_t vdev_id, uint8_t val) 4747 { 4748 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4749 wmi_buf_t buf; 4750 int32_t len = sizeof(*cmd); 4751 4752 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4753 4754 buf = wmi_buf_alloc(wmi_handle, len); 4755 if (!buf) 4756 return QDF_STATUS_E_NOMEM; 4757 4758 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4759 WMITLV_SET_HDR(&cmd->tlv_header, 4760 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4761 WMITLV_GET_STRUCT_TLVLEN 4762 (wmi_sta_powersave_mode_cmd_fixed_param)); 4763 cmd->vdev_id = vdev_id; 4764 if (val) 4765 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4766 else 4767 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4768 4769 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4770 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4771 WMI_STA_POWERSAVE_MODE_CMDID)) { 4772 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4773 vdev_id, val); 4774 wmi_buf_free(buf); 4775 return QDF_STATUS_E_FAILURE; 4776 } 4777 return QDF_STATUS_SUCCESS; 4778 } 4779 4780 /** 4781 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4782 * @wmi_handle: wmi handle 4783 * @vdev_id: vdev id 4784 * 4785 * Return: QDF_STATUS_SUCCESS for success or error code. 4786 */ 4787 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4788 uint8_t val) 4789 { 4790 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4791 wmi_buf_t buf; 4792 size_t len = sizeof(*cmd); 4793 4794 buf = wmi_buf_alloc(wmi_handle, len); 4795 if (!buf) 4796 return QDF_STATUS_E_NOMEM; 4797 4798 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4799 WMITLV_SET_HDR(&cmd->tlv_header, 4800 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4801 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4802 4803 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4804 WMI_IDLE_TRIGGER_MONITOR_OFF); 4805 4806 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4807 4808 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4809 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4810 wmi_buf_free(buf); 4811 return QDF_STATUS_E_FAILURE; 4812 } 4813 return QDF_STATUS_SUCCESS; 4814 } 4815 4816 /** 4817 * send_set_mimops_cmd_tlv() - set MIMO powersave 4818 * @wmi_handle: wmi handle 4819 * @vdev_id: vdev id 4820 * @value: value 4821 * 4822 * Return: QDF_STATUS_SUCCESS for success or error code. 4823 */ 4824 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4825 uint8_t vdev_id, int value) 4826 { 4827 QDF_STATUS ret; 4828 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4829 wmi_buf_t buf; 4830 uint16_t len = sizeof(*cmd); 4831 4832 buf = wmi_buf_alloc(wmi_handle, len); 4833 if (!buf) 4834 return QDF_STATUS_E_NOMEM; 4835 4836 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4837 WMITLV_SET_HDR(&cmd->tlv_header, 4838 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4839 WMITLV_GET_STRUCT_TLVLEN 4840 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4841 4842 cmd->vdev_id = vdev_id; 4843 4844 /* WMI_SMPS_FORCED_MODE values do not directly map 4845 * to SM power save values defined in the specification. 4846 * Make sure to send the right mapping. 4847 */ 4848 switch (value) { 4849 case 0: 4850 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4851 break; 4852 case 1: 4853 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4854 break; 4855 case 2: 4856 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4857 break; 4858 case 3: 4859 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4860 break; 4861 default: 4862 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4863 wmi_buf_free(buf); 4864 return QDF_STATUS_E_FAILURE; 4865 } 4866 4867 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4868 4869 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4870 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4871 WMI_STA_SMPS_FORCE_MODE_CMDID); 4872 if (QDF_IS_STATUS_ERROR(ret)) { 4873 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4874 wmi_buf_free(buf); 4875 } 4876 4877 return ret; 4878 } 4879 4880 /** 4881 * send_set_smps_params_cmd_tlv() - set smps params 4882 * @wmi_handle: wmi handle 4883 * @vdev_id: vdev id 4884 * @value: value 4885 * 4886 * Return: QDF_STATUS_SUCCESS for success or error code. 4887 */ 4888 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4889 int value) 4890 { 4891 QDF_STATUS ret; 4892 wmi_sta_smps_param_cmd_fixed_param *cmd; 4893 wmi_buf_t buf; 4894 uint16_t len = sizeof(*cmd); 4895 4896 buf = wmi_buf_alloc(wmi_handle, len); 4897 if (!buf) 4898 return QDF_STATUS_E_NOMEM; 4899 4900 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4901 WMITLV_SET_HDR(&cmd->tlv_header, 4902 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4903 WMITLV_GET_STRUCT_TLVLEN 4904 (wmi_sta_smps_param_cmd_fixed_param)); 4905 4906 cmd->vdev_id = vdev_id; 4907 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4908 cmd->param = 4909 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4910 4911 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4912 cmd->param); 4913 4914 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4915 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4916 WMI_STA_SMPS_PARAM_CMDID); 4917 if (QDF_IS_STATUS_ERROR(ret)) { 4918 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4919 wmi_buf_free(buf); 4920 } 4921 4922 return ret; 4923 } 4924 4925 /** 4926 * send_get_temperature_cmd_tlv() - get pdev temperature req 4927 * @wmi_handle: wmi handle 4928 * 4929 * Return: QDF_STATUS_SUCCESS for success or error code. 4930 */ 4931 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4932 { 4933 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4934 wmi_buf_t wmi_buf; 4935 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4936 uint8_t *buf_ptr; 4937 4938 if (!wmi_handle) { 4939 wmi_err("WMI is closed, can not issue cmd"); 4940 return QDF_STATUS_E_INVAL; 4941 } 4942 4943 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4944 if (!wmi_buf) 4945 return QDF_STATUS_E_NOMEM; 4946 4947 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4948 4949 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4950 WMITLV_SET_HDR(&cmd->tlv_header, 4951 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4952 WMITLV_GET_STRUCT_TLVLEN 4953 (wmi_pdev_get_temperature_cmd_fixed_param)); 4954 4955 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4956 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4957 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4958 wmi_err("Failed to send get temperature command"); 4959 wmi_buf_free(wmi_buf); 4960 return QDF_STATUS_E_FAILURE; 4961 } 4962 4963 return QDF_STATUS_SUCCESS; 4964 } 4965 4966 /** 4967 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4968 * @wmi_handle: wmi handle 4969 * @vdevid: vdev id 4970 * @peer_addr: peer mac address 4971 * @auto_triggerparam: auto trigger parameters 4972 * @num_ac: number of access category 4973 * 4974 * This function sets the trigger 4975 * uapsd params such as service interval, delay interval 4976 * and suspend interval which will be used by the firmware 4977 * to send trigger frames periodically when there is no 4978 * traffic on the transmit side. 4979 * 4980 * Return: QDF_STATUS_SUCCESS for success or error code. 4981 */ 4982 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4983 struct sta_uapsd_trig_params *param) 4984 { 4985 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4986 QDF_STATUS ret; 4987 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4988 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4989 uint32_t i; 4990 wmi_buf_t buf; 4991 uint8_t *buf_ptr; 4992 struct sta_uapsd_params *uapsd_param; 4993 wmi_sta_uapsd_auto_trig_param *trig_param; 4994 4995 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4996 if (!buf) 4997 return QDF_STATUS_E_NOMEM; 4998 4999 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5000 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5001 WMITLV_SET_HDR(&cmd->tlv_header, 5002 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5003 WMITLV_GET_STRUCT_TLVLEN 5004 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5005 cmd->vdev_id = param->vdevid; 5006 cmd->num_ac = param->num_ac; 5007 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5008 5009 /* TLV indicating array of structures to follow */ 5010 buf_ptr += sizeof(*cmd); 5011 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5012 5013 buf_ptr += WMI_TLV_HDR_SIZE; 5014 5015 /* 5016 * Update tag and length for uapsd auto trigger params (this will take 5017 * care of updating tag and length if it is not pre-filled by caller). 5018 */ 5019 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5020 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5021 for (i = 0; i < param->num_ac; i++) { 5022 WMITLV_SET_HDR((buf_ptr + 5023 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5024 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5025 WMITLV_GET_STRUCT_TLVLEN 5026 (wmi_sta_uapsd_auto_trig_param)); 5027 trig_param->wmm_ac = uapsd_param->wmm_ac; 5028 trig_param->user_priority = uapsd_param->user_priority; 5029 trig_param->service_interval = uapsd_param->service_interval; 5030 trig_param->suspend_interval = uapsd_param->suspend_interval; 5031 trig_param->delay_interval = uapsd_param->delay_interval; 5032 trig_param++; 5033 uapsd_param++; 5034 } 5035 5036 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5037 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5038 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5039 if (QDF_IS_STATUS_ERROR(ret)) { 5040 wmi_err("Failed to send set uapsd param ret = %d", ret); 5041 wmi_buf_free(buf); 5042 } 5043 5044 return ret; 5045 } 5046 5047 /** 5048 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5049 * @wmi_handle: Pointer to wmi handle 5050 * @thermal_info: Thermal command information 5051 * 5052 * This function sends the thermal management command 5053 * to the firmware 5054 * 5055 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5056 */ 5057 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5058 struct thermal_cmd_params *thermal_info) 5059 { 5060 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5061 wmi_buf_t buf = NULL; 5062 QDF_STATUS status; 5063 uint32_t len = 0; 5064 uint8_t action; 5065 5066 switch (thermal_info->thermal_action) { 5067 case THERMAL_MGMT_ACTION_DEFAULT: 5068 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5069 break; 5070 5071 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5072 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5073 break; 5074 5075 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5076 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5077 break; 5078 5079 case THERMAL_MGMT_ACTION_CHAINSCALING: 5080 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5081 break; 5082 5083 default: 5084 wmi_err("Invalid thermal_action code %d", 5085 thermal_info->thermal_action); 5086 return QDF_STATUS_E_FAILURE; 5087 } 5088 5089 len = sizeof(*cmd); 5090 5091 buf = wmi_buf_alloc(wmi_handle, len); 5092 if (!buf) 5093 return QDF_STATUS_E_FAILURE; 5094 5095 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5096 5097 WMITLV_SET_HDR(&cmd->tlv_header, 5098 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5099 WMITLV_GET_STRUCT_TLVLEN 5100 (wmi_thermal_mgmt_cmd_fixed_param)); 5101 5102 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5103 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5104 cmd->enable = thermal_info->thermal_enable; 5105 cmd->action = action; 5106 5107 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5108 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5109 cmd->enable, cmd->action); 5110 5111 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5112 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5113 WMI_THERMAL_MGMT_CMDID); 5114 if (QDF_IS_STATUS_ERROR(status)) { 5115 wmi_buf_free(buf); 5116 wmi_err("Failed to send thermal mgmt command"); 5117 } 5118 5119 return status; 5120 } 5121 5122 /** 5123 * send_lro_config_cmd_tlv() - process the LRO config command 5124 * @wmi_handle: Pointer to WMI handle 5125 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5126 * 5127 * This function sends down the LRO configuration parameters to 5128 * the firmware to enable LRO, sets the TCP flags and sets the 5129 * seed values for the toeplitz hash generation 5130 * 5131 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5132 */ 5133 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5134 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5135 { 5136 wmi_lro_info_cmd_fixed_param *cmd; 5137 wmi_buf_t buf; 5138 QDF_STATUS status; 5139 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5140 5141 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5142 if (!buf) 5143 return QDF_STATUS_E_FAILURE; 5144 5145 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5146 5147 WMITLV_SET_HDR(&cmd->tlv_header, 5148 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5149 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5150 5151 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5152 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5153 wmi_lro_cmd->tcp_flag); 5154 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5155 wmi_lro_cmd->tcp_flag_mask); 5156 cmd->toeplitz_hash_ipv4_0_3 = 5157 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5158 cmd->toeplitz_hash_ipv4_4_7 = 5159 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5160 cmd->toeplitz_hash_ipv4_8_11 = 5161 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5162 cmd->toeplitz_hash_ipv4_12_15 = 5163 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5164 cmd->toeplitz_hash_ipv4_16 = 5165 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5166 5167 cmd->toeplitz_hash_ipv6_0_3 = 5168 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5169 cmd->toeplitz_hash_ipv6_4_7 = 5170 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5171 cmd->toeplitz_hash_ipv6_8_11 = 5172 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5173 cmd->toeplitz_hash_ipv6_12_15 = 5174 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5175 cmd->toeplitz_hash_ipv6_16_19 = 5176 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5177 cmd->toeplitz_hash_ipv6_20_23 = 5178 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5179 cmd->toeplitz_hash_ipv6_24_27 = 5180 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5181 cmd->toeplitz_hash_ipv6_28_31 = 5182 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5183 cmd->toeplitz_hash_ipv6_32_35 = 5184 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5185 cmd->toeplitz_hash_ipv6_36_39 = 5186 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5187 cmd->toeplitz_hash_ipv6_40 = 5188 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5189 5190 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5191 wmi_handle, 5192 pdev_id); 5193 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5194 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5195 5196 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5197 status = wmi_unified_cmd_send(wmi_handle, buf, 5198 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5199 if (QDF_IS_STATUS_ERROR(status)) { 5200 wmi_buf_free(buf); 5201 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5202 } 5203 5204 return status; 5205 } 5206 5207 /** 5208 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5209 * @wmi_handle: Pointer to wmi handle 5210 * @rate_report_params: Pointer to peer rate report parameters 5211 * 5212 * 5213 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5214 */ 5215 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5216 struct wmi_peer_rate_report_params *rate_report_params) 5217 { 5218 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5219 wmi_buf_t buf = NULL; 5220 QDF_STATUS status = 0; 5221 uint32_t len = 0; 5222 uint32_t i, j; 5223 5224 len = sizeof(*cmd); 5225 5226 buf = wmi_buf_alloc(wmi_handle, len); 5227 if (!buf) 5228 return QDF_STATUS_E_FAILURE; 5229 5230 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5231 wmi_buf_data(buf); 5232 5233 WMITLV_SET_HDR( 5234 &cmd->tlv_header, 5235 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5236 WMITLV_GET_STRUCT_TLVLEN( 5237 wmi_peer_set_rate_report_condition_fixed_param)); 5238 5239 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5240 cmd->report_backoff_time = rate_report_params->backoff_time; 5241 cmd->report_timer_period = rate_report_params->timer_period; 5242 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5243 cmd->cond_per_phy[i].val_cond_flags = 5244 rate_report_params->report_per_phy[i].cond_flags; 5245 cmd->cond_per_phy[i].rate_delta.min_delta = 5246 rate_report_params->report_per_phy[i].delta.delta_min; 5247 cmd->cond_per_phy[i].rate_delta.percentage = 5248 rate_report_params->report_per_phy[i].delta.percent; 5249 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5250 cmd->cond_per_phy[i].rate_threshold[j] = 5251 rate_report_params->report_per_phy[i]. 5252 report_rate_threshold[j]; 5253 } 5254 } 5255 5256 wmi_debug("enable %d backoff_time %d period %d", 5257 cmd->enable_rate_report, 5258 cmd->report_backoff_time, cmd->report_timer_period); 5259 5260 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5261 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5262 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5263 if (QDF_IS_STATUS_ERROR(status)) { 5264 wmi_buf_free(buf); 5265 wmi_err("Failed to send peer_set_report_cond command"); 5266 } 5267 return status; 5268 } 5269 5270 /** 5271 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5272 * @wmi_handle: wmi handle 5273 * @vdev_id: vdev id. 5274 * @wmm_vparams: edca parameters 5275 * 5276 * This function updates EDCA parameters to the target 5277 * 5278 * Return: CDF Status 5279 */ 5280 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5281 uint8_t vdev_id, bool mu_edca_param, 5282 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5283 { 5284 uint8_t *buf_ptr; 5285 wmi_buf_t buf; 5286 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5287 wmi_wmm_vparams *wmm_param; 5288 struct wmi_host_wme_vparams *twmm_param; 5289 int len = sizeof(*cmd); 5290 int ac; 5291 5292 buf = wmi_buf_alloc(wmi_handle, len); 5293 5294 if (!buf) 5295 return QDF_STATUS_E_NOMEM; 5296 5297 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5298 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5299 WMITLV_SET_HDR(&cmd->tlv_header, 5300 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5301 WMITLV_GET_STRUCT_TLVLEN 5302 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5303 cmd->vdev_id = vdev_id; 5304 cmd->wmm_param_type = mu_edca_param; 5305 5306 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5307 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5308 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5309 WMITLV_SET_HDR(&wmm_param->tlv_header, 5310 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5311 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5312 wmm_param->cwmin = twmm_param->cwmin; 5313 wmm_param->cwmax = twmm_param->cwmax; 5314 wmm_param->aifs = twmm_param->aifs; 5315 if (mu_edca_param) 5316 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5317 else 5318 wmm_param->txoplimit = twmm_param->txoplimit; 5319 wmm_param->acm = twmm_param->acm; 5320 wmm_param->no_ack = twmm_param->noackpolicy; 5321 } 5322 5323 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5324 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5325 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5326 goto fail; 5327 5328 return QDF_STATUS_SUCCESS; 5329 5330 fail: 5331 wmi_buf_free(buf); 5332 wmi_err("Failed to set WMM Parameters"); 5333 return QDF_STATUS_E_FAILURE; 5334 } 5335 5336 /** 5337 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5338 * @wmi_handle: wmi handle 5339 * @vdev_id: vdev id 5340 * @probe_rsp_info: probe response info 5341 * 5342 * Return: QDF_STATUS_SUCCESS for success or error code 5343 */ 5344 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5345 uint8_t vdev_id, 5346 struct wmi_probe_resp_params *probe_rsp_info) 5347 { 5348 wmi_prb_tmpl_cmd_fixed_param *cmd; 5349 wmi_bcn_prb_info *bcn_prb_info; 5350 wmi_buf_t wmi_buf; 5351 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5352 uint8_t *buf_ptr; 5353 QDF_STATUS ret; 5354 5355 wmi_debug("Send probe response template for vdev %d", vdev_id); 5356 5357 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5358 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5359 5360 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5361 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5362 tmpl_len_aligned; 5363 5364 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5365 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5366 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5367 return QDF_STATUS_E_INVAL; 5368 } 5369 5370 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5371 if (!wmi_buf) 5372 return QDF_STATUS_E_NOMEM; 5373 5374 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5375 5376 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5377 WMITLV_SET_HDR(&cmd->tlv_header, 5378 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5379 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5380 cmd->vdev_id = vdev_id; 5381 cmd->buf_len = tmpl_len; 5382 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5383 5384 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5385 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5386 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5387 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5388 bcn_prb_info->caps = 0; 5389 bcn_prb_info->erp = 0; 5390 buf_ptr += sizeof(wmi_bcn_prb_info); 5391 5392 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5393 buf_ptr += WMI_TLV_HDR_SIZE; 5394 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5395 5396 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5397 ret = wmi_unified_cmd_send(wmi_handle, 5398 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5399 if (QDF_IS_STATUS_ERROR(ret)) { 5400 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5401 wmi_buf_free(wmi_buf); 5402 } 5403 5404 return ret; 5405 } 5406 5407 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5408 #define WPI_IV_LEN 16 5409 5410 /** 5411 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5412 * 5413 * @dest_tx: destination address of tsc key counter 5414 * @src_tx: source address of tsc key counter 5415 * @dest_rx: destination address of rsc key counter 5416 * @src_rx: source address of rsc key counter 5417 * 5418 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5419 * 5420 * Return: None 5421 * 5422 */ 5423 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5424 uint8_t *dest_rx, uint8_t *src_rx) 5425 { 5426 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5427 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5428 } 5429 #else 5430 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5431 uint8_t *dest_rx, uint8_t *src_rx) 5432 { 5433 return; 5434 } 5435 #endif 5436 5437 /** 5438 * send_setup_install_key_cmd_tlv() - set key parameters 5439 * @wmi_handle: wmi handle 5440 * @key_params: key parameters 5441 * 5442 * This function fills structure from information 5443 * passed in key_params. 5444 * 5445 * Return: QDF_STATUS_SUCCESS - success 5446 * QDF_STATUS_E_FAILURE - failure 5447 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5448 */ 5449 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5450 struct set_key_params *key_params) 5451 { 5452 wmi_vdev_install_key_cmd_fixed_param *cmd; 5453 wmi_buf_t buf; 5454 uint8_t *buf_ptr; 5455 uint32_t len; 5456 uint8_t *key_data; 5457 QDF_STATUS status; 5458 5459 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5460 WMI_TLV_HDR_SIZE; 5461 5462 buf = wmi_buf_alloc(wmi_handle, len); 5463 if (!buf) 5464 return QDF_STATUS_E_NOMEM; 5465 5466 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5467 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5468 WMITLV_SET_HDR(&cmd->tlv_header, 5469 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5470 WMITLV_GET_STRUCT_TLVLEN 5471 (wmi_vdev_install_key_cmd_fixed_param)); 5472 cmd->vdev_id = key_params->vdev_id; 5473 cmd->key_ix = key_params->key_idx; 5474 if (key_params->group_key_idx) { 5475 cmd->is_group_key_ix_valid = 1; 5476 cmd->group_key_ix = key_params->group_key_idx; 5477 } 5478 5479 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5480 cmd->key_flags |= key_params->key_flags; 5481 cmd->key_cipher = key_params->key_cipher; 5482 if ((key_params->key_txmic_len) && 5483 (key_params->key_rxmic_len)) { 5484 cmd->key_txmic_len = key_params->key_txmic_len; 5485 cmd->key_rxmic_len = key_params->key_rxmic_len; 5486 } 5487 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5488 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5489 key_params->tx_iv, 5490 cmd->wpi_key_rsc_counter, 5491 key_params->rx_iv); 5492 #endif 5493 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5494 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5495 roundup(key_params->key_len, sizeof(uint32_t))); 5496 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5497 5498 /* for big endian host, copy engine byte_swap is enabled 5499 * But key_data is in network byte order 5500 * Need to byte swap the key_data - so when copy engine 5501 * does byte_swap - target gets key_data in the correct order 5502 */ 5503 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5504 (const void *)key_params->key_data, 5505 key_params->key_len); 5506 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5507 sizeof(wmi_key_seq_counter)); 5508 cmd->key_len = key_params->key_len; 5509 5510 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5511 sizeof(wmi_key_seq_counter)); 5512 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5513 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5514 WMI_VDEV_INSTALL_KEY_CMDID); 5515 if (QDF_IS_STATUS_ERROR(status)) { 5516 qdf_mem_zero(wmi_buf_data(buf), len); 5517 wmi_buf_free(buf); 5518 } 5519 return status; 5520 } 5521 5522 /** 5523 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5524 * @wmi_handle: wmi handle 5525 * @vdev_id: vdev id 5526 * @p2p_ie: p2p IE 5527 * 5528 * Return: QDF_STATUS_SUCCESS for success or error code 5529 */ 5530 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5531 uint32_t vdev_id, uint8_t *p2p_ie) 5532 { 5533 QDF_STATUS ret; 5534 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5535 wmi_buf_t wmi_buf; 5536 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5537 uint8_t *buf_ptr; 5538 5539 ie_len = (uint32_t) (p2p_ie[1] + 2); 5540 5541 /* More than one P2P IE may be included in a single frame. 5542 If multiple P2P IEs are present, the complete P2P attribute 5543 data consists of the concatenation of the P2P Attribute 5544 fields of the P2P IEs. The P2P Attributes field of each 5545 P2P IE may be any length up to the maximum (251 octets). 5546 In this case host sends one P2P IE to firmware so the length 5547 should not exceed more than 251 bytes 5548 */ 5549 if (ie_len > 251) { 5550 wmi_err("Invalid p2p ie length %u", ie_len); 5551 return QDF_STATUS_E_INVAL; 5552 } 5553 5554 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5555 5556 wmi_buf_len = 5557 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5558 WMI_TLV_HDR_SIZE; 5559 5560 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5561 if (!wmi_buf) 5562 return QDF_STATUS_E_NOMEM; 5563 5564 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5565 5566 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5567 WMITLV_SET_HDR(&cmd->tlv_header, 5568 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5569 WMITLV_GET_STRUCT_TLVLEN 5570 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5571 cmd->vdev_id = vdev_id; 5572 cmd->ie_buf_len = ie_len; 5573 5574 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5575 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5576 buf_ptr += WMI_TLV_HDR_SIZE; 5577 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5578 5579 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5580 5581 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5582 ret = wmi_unified_cmd_send(wmi_handle, 5583 wmi_buf, wmi_buf_len, 5584 WMI_P2P_GO_SET_BEACON_IE); 5585 if (QDF_IS_STATUS_ERROR(ret)) { 5586 wmi_err("Failed to send bcn tmpl: %d", ret); 5587 wmi_buf_free(wmi_buf); 5588 } 5589 5590 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5591 return ret; 5592 } 5593 5594 /** 5595 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5596 * @wmi_handle: wmi handle 5597 * @psetoui: OUI parameters 5598 * 5599 * set scan probe OUI parameters in firmware 5600 * 5601 * Return: CDF status 5602 */ 5603 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5604 struct scan_mac_oui *psetoui) 5605 { 5606 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5607 wmi_buf_t wmi_buf; 5608 uint32_t len; 5609 uint8_t *buf_ptr; 5610 uint32_t *oui_buf; 5611 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5612 5613 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5614 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5615 5616 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5617 if (!wmi_buf) 5618 return QDF_STATUS_E_NOMEM; 5619 5620 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5621 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5622 WMITLV_SET_HDR(&cmd->tlv_header, 5623 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5624 WMITLV_GET_STRUCT_TLVLEN 5625 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5626 5627 oui_buf = &cmd->prob_req_oui; 5628 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5629 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5630 | psetoui->oui[2]; 5631 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5632 5633 cmd->vdev_id = psetoui->vdev_id; 5634 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5635 if (psetoui->enb_probe_req_sno_randomization) 5636 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5637 5638 if (ie_allowlist->allow_list) { 5639 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5640 &cmd->num_vendor_oui, 5641 ie_allowlist); 5642 cmd->flags |= 5643 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5644 } 5645 5646 buf_ptr += sizeof(*cmd); 5647 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5648 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5649 buf_ptr += WMI_TLV_HDR_SIZE; 5650 5651 if (cmd->num_vendor_oui != 0) { 5652 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5653 ie_allowlist->voui); 5654 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5655 } 5656 5657 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5658 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5659 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5660 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5661 wmi_buf_free(wmi_buf); 5662 return QDF_STATUS_E_FAILURE; 5663 } 5664 return QDF_STATUS_SUCCESS; 5665 } 5666 5667 #ifdef IPA_OFFLOAD 5668 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5669 * @wmi_handle: wmi handle 5670 * @ipa_offload: ipa offload control parameter 5671 * 5672 * Returns: 0 on success, error number otherwise 5673 */ 5674 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5675 struct ipa_uc_offload_control_params *ipa_offload) 5676 { 5677 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5678 wmi_buf_t wmi_buf; 5679 uint32_t len; 5680 u_int8_t *buf_ptr; 5681 5682 len = sizeof(*cmd); 5683 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5684 if (!wmi_buf) 5685 return QDF_STATUS_E_NOMEM; 5686 5687 wmi_debug("offload_type=%d, enable=%d", 5688 ipa_offload->offload_type, ipa_offload->enable); 5689 5690 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5691 5692 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5693 WMITLV_SET_HDR(&cmd->tlv_header, 5694 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5695 WMITLV_GET_STRUCT_TLVLEN( 5696 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5697 5698 cmd->offload_type = ipa_offload->offload_type; 5699 cmd->vdev_id = ipa_offload->vdev_id; 5700 cmd->enable = ipa_offload->enable; 5701 5702 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5703 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5704 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5705 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5706 wmi_buf_free(wmi_buf); 5707 return QDF_STATUS_E_FAILURE; 5708 } 5709 5710 return QDF_STATUS_SUCCESS; 5711 } 5712 #endif 5713 5714 /** 5715 * send_pno_stop_cmd_tlv() - PNO stop request 5716 * @wmi_handle: wmi handle 5717 * @vdev_id: vdev id 5718 * 5719 * This function request FW to stop ongoing PNO operation. 5720 * 5721 * Return: CDF status 5722 */ 5723 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5724 { 5725 wmi_nlo_config_cmd_fixed_param *cmd; 5726 int32_t len = sizeof(*cmd); 5727 wmi_buf_t buf; 5728 uint8_t *buf_ptr; 5729 int ret; 5730 5731 /* 5732 * TLV place holder for array of structures nlo_configured_parameters 5733 * TLV place holder for array of uint32_t channel_list 5734 * TLV place holder for chnl prediction cfg 5735 */ 5736 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5737 buf = wmi_buf_alloc(wmi_handle, len); 5738 if (!buf) 5739 return QDF_STATUS_E_NOMEM; 5740 5741 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5742 buf_ptr = (uint8_t *) cmd; 5743 5744 WMITLV_SET_HDR(&cmd->tlv_header, 5745 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5746 WMITLV_GET_STRUCT_TLVLEN 5747 (wmi_nlo_config_cmd_fixed_param)); 5748 5749 cmd->vdev_id = vdev_id; 5750 cmd->flags = WMI_NLO_CONFIG_STOP; 5751 buf_ptr += sizeof(*cmd); 5752 5753 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5754 buf_ptr += WMI_TLV_HDR_SIZE; 5755 5756 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5757 buf_ptr += WMI_TLV_HDR_SIZE; 5758 5759 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5760 buf_ptr += WMI_TLV_HDR_SIZE; 5761 5762 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5763 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5764 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5765 if (ret) { 5766 wmi_err("Failed to send nlo wmi cmd"); 5767 wmi_buf_free(buf); 5768 return QDF_STATUS_E_FAILURE; 5769 } 5770 5771 return QDF_STATUS_SUCCESS; 5772 } 5773 5774 /** 5775 * send_obss_disable_cmd_tlv() - disable obss scan request 5776 * @wmi_handle: wmi handle 5777 * @vdev_id: vdev id 5778 * 5779 * This function request FW to disable ongoing obss scan operation. 5780 * 5781 * Return: QDF status 5782 */ 5783 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5784 uint8_t vdev_id) 5785 { 5786 QDF_STATUS status; 5787 wmi_buf_t buf; 5788 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5789 int len = sizeof(*cmd); 5790 5791 buf = wmi_buf_alloc(wmi_handle, len); 5792 if (!buf) 5793 return QDF_STATUS_E_NOMEM; 5794 5795 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5796 5797 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5798 WMITLV_SET_HDR(&cmd->tlv_header, 5799 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5800 WMITLV_GET_STRUCT_TLVLEN( 5801 wmi_obss_scan_disable_cmd_fixed_param)); 5802 5803 cmd->vdev_id = vdev_id; 5804 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5805 WMI_OBSS_SCAN_DISABLE_CMDID); 5806 if (QDF_IS_STATUS_ERROR(status)) 5807 wmi_buf_free(buf); 5808 5809 return status; 5810 } 5811 5812 /** 5813 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5814 * @buf_ptr: Buffer passed by upper layers 5815 * @pno: Buffer to be sent to the firmware 5816 * 5817 * Copy the PNO Channel prediction configuration parameters 5818 * passed by the upper layers to a WMI format TLV and send it 5819 * down to the firmware. 5820 * 5821 * Return: None 5822 */ 5823 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5824 struct pno_scan_req_params *pno) 5825 { 5826 nlo_channel_prediction_cfg *channel_prediction_cfg = 5827 (nlo_channel_prediction_cfg *) buf_ptr; 5828 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5829 WMITLV_TAG_ARRAY_BYTE, 5830 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5831 #ifdef FEATURE_WLAN_SCAN_PNO 5832 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5833 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5834 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5835 channel_prediction_cfg->full_scan_period_ms = 5836 pno->channel_prediction_full_scan; 5837 #endif 5838 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5839 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5840 channel_prediction_cfg->enable, 5841 channel_prediction_cfg->top_k_num, 5842 channel_prediction_cfg->stationary_threshold, 5843 channel_prediction_cfg->full_scan_period_ms); 5844 } 5845 5846 /** 5847 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5848 * @wmi_handle: wmi handle 5849 * @buf_ptr: Buffer passed by upper layers 5850 * @buf_len: Length of passed buffer by upper layer 5851 * 5852 * Copy the buffer passed by the upper layers and send it 5853 * down to the firmware. 5854 * 5855 * Return: None 5856 */ 5857 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5858 void *buf_ptr, uint32_t buf_len) 5859 { 5860 wmi_buf_t buf = NULL; 5861 QDF_STATUS status; 5862 int len; 5863 uint8_t *data_ptr; 5864 5865 len = buf_len; 5866 buf = wmi_buf_alloc(wmi_handle, len); 5867 if (!buf) 5868 return QDF_STATUS_E_NOMEM; 5869 5870 data_ptr = (uint8_t *)wmi_buf_data(buf); 5871 qdf_mem_copy(data_ptr, buf_ptr, len); 5872 5873 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5874 status = wmi_unified_cmd_send(wmi_handle, buf, 5875 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5876 5877 if (QDF_IS_STATUS_ERROR(status)) { 5878 wmi_buf_free(buf); 5879 return QDF_STATUS_E_FAILURE; 5880 } 5881 return QDF_STATUS_SUCCESS; 5882 } 5883 5884 /** 5885 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 5886 * @wmi_handle: wmi handle 5887 * @buf_ptr: Buffer passed by upper layers 5888 * @buf_len: Length of passed buffer by upper layer 5889 * 5890 * Copy the buffer passed by the upper layers and send it 5891 * down to the firmware. 5892 * 5893 * Return: None 5894 */ 5895 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 5896 void *buf_ptr, uint32_t buf_len) 5897 { 5898 wmi_buf_t buf = NULL; 5899 QDF_STATUS status; 5900 int len; 5901 uint8_t *data_ptr; 5902 5903 len = buf_len; 5904 buf = wmi_buf_alloc(wmi_handle, len); 5905 if (!buf) 5906 return QDF_STATUS_E_NOMEM; 5907 5908 data_ptr = (uint8_t *)wmi_buf_data(buf); 5909 qdf_mem_copy(data_ptr, buf_ptr, len); 5910 5911 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5912 status = wmi_unified_cmd_send(wmi_handle, buf, 5913 len, 5914 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 5915 5916 if (QDF_IS_STATUS_ERROR(status)) { 5917 wmi_buf_free(buf); 5918 return QDF_STATUS_E_FAILURE; 5919 } 5920 return QDF_STATUS_SUCCESS; 5921 } 5922 5923 /** 5924 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5925 * @wmi_handle: wmi handle 5926 * @evt_buf: event buffer 5927 * @more_flag: buffer to populate more flag 5928 * 5929 * Return: status of operation 5930 */ 5931 static QDF_STATUS 5932 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5933 uint32_t *more_flag) 5934 { 5935 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5936 wmi_ctrl_path_stats_event_fixed_param *ev; 5937 5938 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5939 if (!param_buf) { 5940 wmi_err_rl("param_buf is NULL"); 5941 return QDF_STATUS_E_FAILURE; 5942 } 5943 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5944 5945 *more_flag = ev->more; 5946 return QDF_STATUS_SUCCESS; 5947 } 5948 5949 /** 5950 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 5951 * from event data 5952 * @wmi_handle: wmi handle 5953 * @evt_buf: event buffer 5954 * @end_of_event_flag: buffer to populate end_of_event flag 5955 * 5956 * Return: status of operation 5957 */ 5958 static QDF_STATUS 5959 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi, void *evt_buf, 5960 uint32_t *end_of_event_flag) 5961 { 5962 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5963 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5964 5965 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5966 if (!param_buf) { 5967 wmi_err_rl("param_buf is NULL"); 5968 return QDF_STATUS_E_FAILURE; 5969 } 5970 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5971 param_buf->fixed_param; 5972 5973 *end_of_event_flag = ev->end_of_event; 5974 return QDF_STATUS_SUCCESS; 5975 } 5976 5977 /** 5978 * extract_halphy_stats_event_count - api to extract event count flag from 5979 * event data 5980 * @wmi_handle: wmi handle 5981 * @evt_buf: event buffer 5982 * @event_count_flag: buffer to populate event_count flag 5983 * 5984 * Return: status of operation 5985 */ 5986 static QDF_STATUS 5987 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi, void *evt_buf, 5988 uint32_t *event_count_flag) 5989 { 5990 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5991 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5992 5993 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5994 if (!param_buf) { 5995 wmi_err_rl("param_buf is NULL"); 5996 return QDF_STATUS_E_FAILURE; 5997 } 5998 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5999 param_buf->fixed_param; 6000 6001 *event_count_flag = ev->event_count; 6002 return QDF_STATUS_SUCCESS; 6003 } 6004 6005 /** 6006 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6007 * @wmi_handle: wmi handle 6008 * @params: configuration parameters 6009 * 6010 * Return: QDF_STATUS 6011 */ 6012 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6013 struct nlo_mawc_params *params) 6014 { 6015 wmi_buf_t buf = NULL; 6016 QDF_STATUS status; 6017 int len; 6018 uint8_t *buf_ptr; 6019 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6020 6021 len = sizeof(*wmi_nlo_mawc_params); 6022 buf = wmi_buf_alloc(wmi_handle, len); 6023 if (!buf) 6024 return QDF_STATUS_E_NOMEM; 6025 6026 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6027 wmi_nlo_mawc_params = 6028 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6029 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6030 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6031 WMITLV_GET_STRUCT_TLVLEN 6032 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6033 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6034 if (params->enable) 6035 wmi_nlo_mawc_params->enable = 1; 6036 else 6037 wmi_nlo_mawc_params->enable = 0; 6038 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6039 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6040 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6041 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6042 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6043 wmi_nlo_mawc_params->exp_backoff_ratio, 6044 wmi_nlo_mawc_params->init_scan_interval, 6045 wmi_nlo_mawc_params->max_scan_interval); 6046 6047 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6048 status = wmi_unified_cmd_send(wmi_handle, buf, 6049 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6050 if (QDF_IS_STATUS_ERROR(status)) { 6051 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6052 status); 6053 wmi_buf_free(buf); 6054 return QDF_STATUS_E_FAILURE; 6055 } 6056 6057 return QDF_STATUS_SUCCESS; 6058 } 6059 6060 /** 6061 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6062 * scan 6063 * @scan_freq_list: frequency list for pno scan 6064 * 6065 * Return: void 6066 */ 6067 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6068 { 6069 uint32_t i; 6070 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6071 uint32_t len = 0; 6072 struct chan_info *chan_info; 6073 int ret; 6074 6075 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6076 for (i = 0; i < scan_freq_list->num_chan; i++) { 6077 chan_info = &scan_freq_list->chan[i]; 6078 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6079 " %d[%d]", chan_info->freq, 6080 chan_info->flags); 6081 if (ret <= 0) 6082 break; 6083 len += ret; 6084 if (len >= (sizeof(info) - 20)) { 6085 wmi_nofl_debug("Freq[flag]:%s", 6086 info); 6087 len = 0; 6088 } 6089 } 6090 if (len) 6091 wmi_nofl_debug("Freq[flag]:%s", info); 6092 } 6093 6094 /** 6095 * send_pno_start_cmd_tlv() - PNO start request 6096 * @wmi_handle: wmi handle 6097 * @pno: PNO request 6098 * 6099 * This function request FW to start PNO request. 6100 * Request: CDF status 6101 */ 6102 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6103 struct pno_scan_req_params *pno) 6104 { 6105 wmi_nlo_config_cmd_fixed_param *cmd; 6106 nlo_configured_parameters *nlo_list; 6107 uint32_t *channel_list; 6108 int32_t len; 6109 qdf_freq_t freq; 6110 wmi_buf_t buf; 6111 uint8_t *buf_ptr; 6112 uint8_t i; 6113 int ret; 6114 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6115 connected_nlo_rssi_params *nlo_relative_rssi; 6116 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6117 6118 /* 6119 * TLV place holder for array nlo_configured_parameters(nlo_list) 6120 * TLV place holder for array of uint32_t channel_list 6121 * TLV place holder for chnnl prediction cfg 6122 * TLV place holder for array of wmi_vendor_oui 6123 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6124 */ 6125 len = sizeof(*cmd) + 6126 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6127 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6128 6129 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6130 len += sizeof(nlo_configured_parameters) * 6131 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6132 len += sizeof(nlo_channel_prediction_cfg); 6133 len += sizeof(enlo_candidate_score_params); 6134 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6135 len += sizeof(connected_nlo_rssi_params); 6136 len += sizeof(connected_nlo_bss_band_rssi_pref); 6137 6138 buf = wmi_buf_alloc(wmi_handle, len); 6139 if (!buf) 6140 return QDF_STATUS_E_NOMEM; 6141 6142 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6143 6144 buf_ptr = (uint8_t *) cmd; 6145 WMITLV_SET_HDR(&cmd->tlv_header, 6146 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6147 WMITLV_GET_STRUCT_TLVLEN 6148 (wmi_nlo_config_cmd_fixed_param)); 6149 cmd->vdev_id = pno->vdev_id; 6150 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6151 6152 #ifdef FEATURE_WLAN_SCAN_PNO 6153 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6154 pno->adaptive_dwell_mode); 6155 #endif 6156 /* Current FW does not support min-max range for dwell time */ 6157 cmd->active_dwell_time = pno->active_dwell_time; 6158 cmd->passive_dwell_time = pno->passive_dwell_time; 6159 6160 if (pno->do_passive_scan) 6161 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6162 /* Copy scan interval */ 6163 cmd->fast_scan_period = pno->fast_scan_period; 6164 cmd->slow_scan_period = pno->slow_scan_period; 6165 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6166 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6167 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6168 6169 /* mac randomization attributes */ 6170 if (pno->scan_random.randomize) { 6171 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6172 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6173 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6174 pno->scan_random.mac_mask, 6175 &cmd->mac_addr, 6176 &cmd->mac_mask); 6177 } 6178 6179 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6180 6181 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6182 6183 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6184 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6185 buf_ptr += WMI_TLV_HDR_SIZE; 6186 6187 nlo_list = (nlo_configured_parameters *) buf_ptr; 6188 for (i = 0; i < cmd->no_of_ssids; i++) { 6189 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6190 WMITLV_TAG_ARRAY_BYTE, 6191 WMITLV_GET_STRUCT_TLVLEN 6192 (nlo_configured_parameters)); 6193 /* Copy ssid and it's length */ 6194 nlo_list[i].ssid.valid = true; 6195 nlo_list[i].ssid.ssid.ssid_len = 6196 pno->networks_list[i].ssid.length; 6197 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6198 pno->networks_list[i].ssid.ssid, 6199 nlo_list[i].ssid.ssid.ssid_len); 6200 6201 /* Copy rssi threshold */ 6202 if (pno->networks_list[i].rssi_thresh && 6203 pno->networks_list[i].rssi_thresh > 6204 WMI_RSSI_THOLD_DEFAULT) { 6205 nlo_list[i].rssi_cond.valid = true; 6206 nlo_list[i].rssi_cond.rssi = 6207 pno->networks_list[i].rssi_thresh; 6208 } 6209 nlo_list[i].bcast_nw_type.valid = true; 6210 nlo_list[i].bcast_nw_type.bcast_nw_type = 6211 pno->networks_list[i].bc_new_type; 6212 } 6213 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6214 6215 /* Copy channel info */ 6216 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6217 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6218 (cmd->num_of_channels * sizeof(uint32_t))); 6219 buf_ptr += WMI_TLV_HDR_SIZE; 6220 6221 channel_list = (uint32_t *) buf_ptr; 6222 for (i = 0; i < cmd->num_of_channels; i++) { 6223 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6224 pno->networks_list[0].pno_chan_list.chan[i].freq); 6225 6226 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6227 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6228 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6229 wlan_chan_to_freq(freq)); 6230 } 6231 6232 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6233 pno->networks_list[0].pno_chan_list.chan[i].flags); 6234 } 6235 6236 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6237 6238 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6239 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6240 sizeof(nlo_channel_prediction_cfg)); 6241 buf_ptr += WMI_TLV_HDR_SIZE; 6242 wmi_set_pno_channel_prediction(buf_ptr, pno); 6243 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6244 /** TODO: Discrete firmware doesn't have command/option to configure 6245 * App IE which comes from wpa_supplicant as of part PNO start request. 6246 */ 6247 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6248 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6249 buf_ptr += sizeof(enlo_candidate_score_params); 6250 6251 if (ie_allowlist->allow_list) { 6252 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6253 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6254 &cmd->num_vendor_oui, 6255 ie_allowlist); 6256 } 6257 6258 /* ie allow list */ 6259 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6260 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6261 buf_ptr += WMI_TLV_HDR_SIZE; 6262 if (cmd->num_vendor_oui != 0) { 6263 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6264 ie_allowlist->voui); 6265 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6266 } 6267 6268 if (pno->relative_rssi_set) 6269 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6270 6271 /* 6272 * Firmware calculation using connected PNO params: 6273 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6274 * deduction of rssi_pref for chosen band_pref and 6275 * addition of rssi_pref for remaining bands (other than chosen band). 6276 */ 6277 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6278 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6279 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6280 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6281 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6282 buf_ptr += sizeof(*nlo_relative_rssi); 6283 6284 /* 6285 * As of now Kernel and Host supports one band and rssi preference. 6286 * Firmware supports array of band and rssi preferences 6287 */ 6288 cmd->num_cnlo_band_pref = 1; 6289 WMITLV_SET_HDR(buf_ptr, 6290 WMITLV_TAG_ARRAY_STRUC, 6291 cmd->num_cnlo_band_pref * 6292 sizeof(connected_nlo_bss_band_rssi_pref)); 6293 buf_ptr += WMI_TLV_HDR_SIZE; 6294 6295 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6296 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6297 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6298 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6299 WMITLV_GET_STRUCT_TLVLEN( 6300 connected_nlo_bss_band_rssi_pref)); 6301 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6302 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6303 } 6304 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6305 6306 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6307 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6308 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6309 if (ret) { 6310 wmi_err("Failed to send nlo wmi cmd"); 6311 wmi_buf_free(buf); 6312 return QDF_STATUS_E_FAILURE; 6313 } 6314 6315 return QDF_STATUS_SUCCESS; 6316 } 6317 6318 /** 6319 * is_service_enabled_tlv() - Check if service enabled 6320 * @param wmi_handle: wmi handle 6321 * @param service_id: service identifier 6322 * 6323 * Return: 1 enabled, 0 disabled 6324 */ 6325 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6326 uint32_t service_id) 6327 { 6328 struct wmi_soc *soc = wmi_handle->soc; 6329 6330 if (!soc->wmi_service_bitmap) { 6331 wmi_err("WMI service bit map is not saved yet"); 6332 return false; 6333 } 6334 6335 /* if wmi_service_enabled was received with extended2 bitmap, 6336 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6337 */ 6338 if (soc->wmi_ext2_service_bitmap) { 6339 if (!soc->wmi_ext_service_bitmap) { 6340 wmi_err("WMI service ext bit map is not saved yet"); 6341 return false; 6342 } 6343 6344 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6345 soc->wmi_ext_service_bitmap, 6346 soc->wmi_ext2_service_bitmap, 6347 service_id); 6348 } 6349 6350 if (service_id >= WMI_MAX_EXT_SERVICE) { 6351 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6352 service_id); 6353 return false; 6354 } 6355 /* if wmi_service_enabled was received with extended bitmap, 6356 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6357 */ 6358 if (soc->wmi_ext_service_bitmap) 6359 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6360 soc->wmi_ext_service_bitmap, 6361 service_id); 6362 6363 if (service_id >= WMI_MAX_SERVICE) { 6364 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6365 service_id); 6366 return false; 6367 } 6368 6369 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6370 service_id); 6371 } 6372 6373 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6374 /** 6375 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6376 * @wmi_handle: wmi handle 6377 * @clear_req: ll stats clear request command params 6378 * 6379 * Return: QDF_STATUS_SUCCESS for success or error code 6380 */ 6381 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6382 const struct ll_stats_clear_params *clear_req) 6383 { 6384 wmi_clear_link_stats_cmd_fixed_param *cmd; 6385 int32_t len; 6386 wmi_buf_t buf; 6387 uint8_t *buf_ptr; 6388 int ret; 6389 6390 len = sizeof(*cmd); 6391 buf = wmi_buf_alloc(wmi_handle, len); 6392 6393 if (!buf) 6394 return QDF_STATUS_E_NOMEM; 6395 6396 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6397 qdf_mem_zero(buf_ptr, len); 6398 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6399 6400 WMITLV_SET_HDR(&cmd->tlv_header, 6401 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6402 WMITLV_GET_STRUCT_TLVLEN 6403 (wmi_clear_link_stats_cmd_fixed_param)); 6404 6405 cmd->stop_stats_collection_req = clear_req->stop_req; 6406 cmd->vdev_id = clear_req->vdev_id; 6407 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6408 6409 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6410 &cmd->peer_macaddr); 6411 6412 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6413 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6414 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6415 cmd->stop_stats_collection_req, 6416 cmd->vdev_id, cmd->stats_clear_req_mask, 6417 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6418 6419 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6420 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6421 WMI_CLEAR_LINK_STATS_CMDID); 6422 if (ret) { 6423 wmi_err("Failed to send clear link stats req"); 6424 wmi_buf_free(buf); 6425 return QDF_STATUS_E_FAILURE; 6426 } 6427 6428 wmi_debug("Clear Link Layer Stats request sent successfully"); 6429 return QDF_STATUS_SUCCESS; 6430 } 6431 6432 /** 6433 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6434 * @wmi_handle: wmi handle 6435 * @set_req: ll stats set request command params 6436 * 6437 * Return: QDF_STATUS_SUCCESS for success or error code 6438 */ 6439 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6440 const struct ll_stats_set_params *set_req) 6441 { 6442 wmi_start_link_stats_cmd_fixed_param *cmd; 6443 int32_t len; 6444 wmi_buf_t buf; 6445 uint8_t *buf_ptr; 6446 int ret; 6447 6448 len = sizeof(*cmd); 6449 buf = wmi_buf_alloc(wmi_handle, len); 6450 6451 if (!buf) 6452 return QDF_STATUS_E_NOMEM; 6453 6454 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6455 qdf_mem_zero(buf_ptr, len); 6456 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6457 6458 WMITLV_SET_HDR(&cmd->tlv_header, 6459 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6460 WMITLV_GET_STRUCT_TLVLEN 6461 (wmi_start_link_stats_cmd_fixed_param)); 6462 6463 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6464 cmd->aggressive_statistics_gathering = 6465 set_req->aggressive_statistics_gathering; 6466 6467 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6468 cmd->mpdu_size_threshold, 6469 cmd->aggressive_statistics_gathering); 6470 6471 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6472 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6473 WMI_START_LINK_STATS_CMDID); 6474 if (ret) { 6475 wmi_err("Failed to send set link stats request"); 6476 wmi_buf_free(buf); 6477 return QDF_STATUS_E_FAILURE; 6478 } 6479 6480 return QDF_STATUS_SUCCESS; 6481 } 6482 6483 /** 6484 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6485 * @wmi_handle: wmi handle 6486 * @get_req: ll stats get request command params 6487 * 6488 * Return: QDF_STATUS_SUCCESS for success or error code 6489 */ 6490 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6491 const struct ll_stats_get_params *get_req) 6492 { 6493 wmi_request_link_stats_cmd_fixed_param *cmd; 6494 int32_t len; 6495 wmi_buf_t buf; 6496 uint8_t *buf_ptr; 6497 int ret; 6498 6499 len = sizeof(*cmd); 6500 buf = wmi_buf_alloc(wmi_handle, len); 6501 6502 if (!buf) 6503 return QDF_STATUS_E_NOMEM; 6504 6505 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6506 qdf_mem_zero(buf_ptr, len); 6507 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6508 6509 WMITLV_SET_HDR(&cmd->tlv_header, 6510 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6511 WMITLV_GET_STRUCT_TLVLEN 6512 (wmi_request_link_stats_cmd_fixed_param)); 6513 6514 cmd->request_id = get_req->req_id; 6515 cmd->stats_type = get_req->param_id_mask; 6516 cmd->vdev_id = get_req->vdev_id; 6517 6518 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6519 &cmd->peer_macaddr); 6520 6521 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6522 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6523 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6524 6525 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6526 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 6527 WMI_REQUEST_LINK_STATS_CMDID, true); 6528 if (ret) { 6529 wmi_buf_free(buf); 6530 return QDF_STATUS_E_FAILURE; 6531 } 6532 6533 return QDF_STATUS_SUCCESS; 6534 } 6535 6536 #ifdef WLAN_FEATURE_11BE_MLO 6537 static int 6538 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6539 { 6540 int32_t len = 0; 6541 6542 /* In case of MLO connection, update the length of the buffer. 6543 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6544 * hence just update the TLV header, but allocate no memory for it. 6545 */ 6546 if (!get_req->is_mlo_req) 6547 return len; 6548 6549 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6550 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6551 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6552 6553 return len; 6554 } 6555 6556 static void 6557 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6558 void *buf_ptr) 6559 { 6560 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6561 uint32_t *vdev_id_bitmap; 6562 wmi_mac_addr *mld_mac; 6563 6564 /* In case of MLO connection, update the TLV Headers */ 6565 if (!get_req->is_mlo_req) 6566 return; 6567 6568 buf_ptr += sizeof(*unified_cmd); 6569 6570 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 6571 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6572 buf_ptr += WMI_TLV_HDR_SIZE; 6573 6574 /* Adding vdev_bitmap_id array TLV */ 6575 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6576 sizeof(*vdev_id_bitmap)); 6577 buf_ptr += WMI_TLV_HDR_SIZE; 6578 vdev_id_bitmap = buf_ptr; 6579 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 6580 buf_ptr += sizeof(*vdev_id_bitmap); 6581 6582 /* Adding mld_macaddr array TLV */ 6583 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 6584 sizeof(*mld_mac)); 6585 buf_ptr += WMI_TLV_HDR_SIZE; 6586 mld_mac = buf_ptr; 6587 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 6588 6589 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 6590 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 6591 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 6592 } 6593 #else 6594 static inline int 6595 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6596 { 6597 return 0; 6598 } 6599 6600 static inline void 6601 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6602 void *buf_ptr) 6603 { 6604 } 6605 #endif 6606 6607 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6608 /** 6609 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 6610 * station request 6611 * @wmi_handle: wmi handle 6612 * @get_req: ll stats get request command params 6613 * 6614 * Return: QDF_STATUS_SUCCESS for success or error code 6615 */ 6616 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6617 wmi_unified_t wmi_handle, 6618 const struct ll_stats_get_params *get_req) 6619 { 6620 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6621 int32_t len; 6622 wmi_buf_t buf; 6623 void *buf_ptr; 6624 QDF_STATUS ret; 6625 bool is_ll_get_sta_stats_over_qmi; 6626 6627 len = sizeof(*unified_cmd); 6628 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6629 6630 buf = wmi_buf_alloc(wmi_handle, len); 6631 if (!buf) 6632 return QDF_STATUS_E_NOMEM; 6633 6634 buf_ptr = wmi_buf_data(buf); 6635 6636 unified_cmd = buf_ptr; 6637 WMITLV_SET_HDR( 6638 &unified_cmd->tlv_header, 6639 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6640 WMITLV_GET_STRUCT_TLVLEN 6641 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6642 6643 unified_cmd->link_stats_type = get_req->param_id_mask; 6644 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6645 WMI_REQUEST_PEER_STAT | 6646 WMI_REQUEST_VDEV_STAT | 6647 WMI_REQUEST_PDEV_STAT | 6648 WMI_REQUEST_PEER_EXTD2_STAT | 6649 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6650 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6651 wmi_handle, 6652 WMI_HOST_PDEV_ID_SOC); 6653 6654 unified_cmd->vdev_id = get_req->vdev_id; 6655 unified_cmd->request_id = get_req->req_id; 6656 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6657 &unified_cmd->peer_macaddr); 6658 6659 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6660 QDF_MAC_ADDR_FMT, 6661 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6662 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6663 6664 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6665 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6666 6667 /** 6668 * FW support for LL_get_sta command. True represents the unified 6669 * ll_get_sta command should be sent over QMI always irrespective of 6670 * WOW state. 6671 */ 6672 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6673 wmi_handle, 6674 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6675 6676 if (is_ll_get_sta_stats_over_qmi) { 6677 ret = wmi_unified_cmd_send_over_qmi( 6678 wmi_handle, buf, len, 6679 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6680 } else { 6681 ret = wmi_unified_cmd_send_pm_chk( 6682 wmi_handle, buf, len, 6683 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6684 true); 6685 } 6686 6687 if (QDF_IS_STATUS_ERROR(ret)) { 6688 wmi_buf_free(buf); 6689 return QDF_STATUS_E_FAILURE; 6690 } 6691 6692 return ret; 6693 } 6694 #endif 6695 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6696 6697 /** 6698 * send_congestion_cmd_tlv() - send request to fw to get CCA 6699 * @wmi_handle: wmi handle 6700 * @vdev_id: vdev id 6701 * 6702 * Return: CDF status 6703 */ 6704 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6705 uint8_t vdev_id) 6706 { 6707 wmi_buf_t buf; 6708 wmi_request_stats_cmd_fixed_param *cmd; 6709 uint8_t len; 6710 uint8_t *buf_ptr; 6711 6712 len = sizeof(*cmd); 6713 buf = wmi_buf_alloc(wmi_handle, len); 6714 if (!buf) 6715 return QDF_STATUS_E_FAILURE; 6716 6717 buf_ptr = wmi_buf_data(buf); 6718 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6719 WMITLV_SET_HDR(&cmd->tlv_header, 6720 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6721 WMITLV_GET_STRUCT_TLVLEN 6722 (wmi_request_stats_cmd_fixed_param)); 6723 6724 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6725 cmd->vdev_id = vdev_id; 6726 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6727 cmd->vdev_id, cmd->stats_id); 6728 6729 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6730 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6731 WMI_REQUEST_STATS_CMDID)) { 6732 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6733 wmi_buf_free(buf); 6734 return QDF_STATUS_E_FAILURE; 6735 } 6736 6737 return QDF_STATUS_SUCCESS; 6738 } 6739 6740 /** 6741 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6742 * @wmi_handle: wmi handle 6743 * @rssi_req: get RSSI request 6744 * 6745 * Return: CDF status 6746 */ 6747 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6748 { 6749 wmi_buf_t buf; 6750 wmi_request_stats_cmd_fixed_param *cmd; 6751 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6752 6753 buf = wmi_buf_alloc(wmi_handle, len); 6754 if (!buf) 6755 return QDF_STATUS_E_FAILURE; 6756 6757 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6758 WMITLV_SET_HDR(&cmd->tlv_header, 6759 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6760 WMITLV_GET_STRUCT_TLVLEN 6761 (wmi_request_stats_cmd_fixed_param)); 6762 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6763 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6764 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6765 WMI_REQUEST_STATS_CMDID)) { 6766 wmi_err("Failed to send host stats request to fw"); 6767 wmi_buf_free(buf); 6768 return QDF_STATUS_E_FAILURE; 6769 } 6770 6771 return QDF_STATUS_SUCCESS; 6772 } 6773 6774 /** 6775 * send_snr_cmd_tlv() - get RSSI from fw 6776 * @wmi_handle: wmi handle 6777 * @vdev_id: vdev id 6778 * 6779 * Return: CDF status 6780 */ 6781 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6782 { 6783 wmi_buf_t buf; 6784 wmi_request_stats_cmd_fixed_param *cmd; 6785 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6786 6787 buf = wmi_buf_alloc(wmi_handle, len); 6788 if (!buf) 6789 return QDF_STATUS_E_FAILURE; 6790 6791 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6792 cmd->vdev_id = vdev_id; 6793 6794 WMITLV_SET_HDR(&cmd->tlv_header, 6795 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6796 WMITLV_GET_STRUCT_TLVLEN 6797 (wmi_request_stats_cmd_fixed_param)); 6798 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6799 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6800 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6801 WMI_REQUEST_STATS_CMDID)) { 6802 wmi_err("Failed to send host stats request to fw"); 6803 wmi_buf_free(buf); 6804 return QDF_STATUS_E_FAILURE; 6805 } 6806 6807 return QDF_STATUS_SUCCESS; 6808 } 6809 6810 /** 6811 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6812 * @wmi_handle: wmi handle 6813 * @link_status: get link params 6814 * 6815 * Return: CDF status 6816 */ 6817 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6818 struct link_status_params *link_status) 6819 { 6820 wmi_buf_t buf; 6821 wmi_request_stats_cmd_fixed_param *cmd; 6822 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6823 6824 buf = wmi_buf_alloc(wmi_handle, len); 6825 if (!buf) 6826 return QDF_STATUS_E_FAILURE; 6827 6828 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6829 WMITLV_SET_HDR(&cmd->tlv_header, 6830 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6831 WMITLV_GET_STRUCT_TLVLEN 6832 (wmi_request_stats_cmd_fixed_param)); 6833 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6834 cmd->vdev_id = link_status->vdev_id; 6835 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6836 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6837 WMI_REQUEST_STATS_CMDID)) { 6838 wmi_err("Failed to send WMI link status request to fw"); 6839 wmi_buf_free(buf); 6840 return QDF_STATUS_E_FAILURE; 6841 } 6842 6843 return QDF_STATUS_SUCCESS; 6844 } 6845 6846 #ifdef WLAN_SUPPORT_GREEN_AP 6847 /** 6848 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6849 * @wmi_handle: wmi handler 6850 * @egap_params: pointer to egap_params 6851 * 6852 * Return: 0 for success, otherwise appropriate error code 6853 */ 6854 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 6855 struct wlan_green_ap_egap_params *egap_params) 6856 { 6857 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 6858 wmi_buf_t buf; 6859 int32_t err; 6860 6861 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6862 if (!buf) 6863 return QDF_STATUS_E_NOMEM; 6864 6865 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 6866 WMITLV_SET_HDR(&cmd->tlv_header, 6867 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 6868 WMITLV_GET_STRUCT_TLVLEN( 6869 wmi_ap_ps_egap_param_cmd_fixed_param)); 6870 6871 cmd->enable = egap_params->host_enable_egap; 6872 cmd->inactivity_time = egap_params->egap_inactivity_time; 6873 cmd->wait_time = egap_params->egap_wait_time; 6874 cmd->flags = egap_params->egap_feature_flags; 6875 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 6876 err = wmi_unified_cmd_send(wmi_handle, buf, 6877 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 6878 if (err) { 6879 wmi_err("Failed to send ap_ps_egap cmd"); 6880 wmi_buf_free(buf); 6881 return QDF_STATUS_E_FAILURE; 6882 } 6883 6884 return QDF_STATUS_SUCCESS; 6885 } 6886 #endif 6887 6888 /** 6889 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 6890 * @wmi_handle: wmi handle 6891 * @vdev_id: vdev id 6892 * 6893 * Return: QDF_STATUS_SUCCESS for success or error code 6894 */ 6895 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 6896 uint8_t vdev_id) 6897 { 6898 wmi_csa_offload_enable_cmd_fixed_param *cmd; 6899 wmi_buf_t buf; 6900 int32_t len = sizeof(*cmd); 6901 6902 wmi_debug("vdev_id %d", vdev_id); 6903 buf = wmi_buf_alloc(wmi_handle, len); 6904 if (!buf) 6905 return QDF_STATUS_E_NOMEM; 6906 6907 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 6908 WMITLV_SET_HDR(&cmd->tlv_header, 6909 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 6910 WMITLV_GET_STRUCT_TLVLEN 6911 (wmi_csa_offload_enable_cmd_fixed_param)); 6912 cmd->vdev_id = vdev_id; 6913 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 6914 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 6915 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6916 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 6917 wmi_err("Failed to send CSA offload enable command"); 6918 wmi_buf_free(buf); 6919 return QDF_STATUS_E_FAILURE; 6920 } 6921 6922 return 0; 6923 } 6924 6925 #ifdef WLAN_FEATURE_CIF_CFR 6926 /** 6927 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 6928 * @wmi_handle: wmi handle 6929 * @data_len: len of dma cfg req 6930 * @data: dma cfg req 6931 * 6932 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 6933 */ 6934 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 6935 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 6936 { 6937 wmi_buf_t buf; 6938 uint8_t *cmd; 6939 QDF_STATUS ret; 6940 6941 WMITLV_SET_HDR(cfg, 6942 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 6943 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 6944 6945 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 6946 if (!buf) 6947 return QDF_STATUS_E_FAILURE; 6948 6949 cmd = (uint8_t *) wmi_buf_data(buf); 6950 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 6951 wmi_debug("Sending OEM Data Request to target, data len %lu", 6952 sizeof(*cfg)); 6953 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 6954 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 6955 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 6956 if (QDF_IS_STATUS_ERROR(ret)) { 6957 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 6958 wmi_buf_free(buf); 6959 } 6960 6961 return ret; 6962 } 6963 #endif 6964 6965 /** 6966 * send_start_11d_scan_cmd_tlv() - start 11d scan request 6967 * @wmi_handle: wmi handle 6968 * @start_11d_scan: 11d scan start request parameters 6969 * 6970 * This function request FW to start 11d scan. 6971 * 6972 * Return: QDF status 6973 */ 6974 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6975 struct reg_start_11d_scan_req *start_11d_scan) 6976 { 6977 wmi_11d_scan_start_cmd_fixed_param *cmd; 6978 int32_t len; 6979 wmi_buf_t buf; 6980 int ret; 6981 6982 len = sizeof(*cmd); 6983 buf = wmi_buf_alloc(wmi_handle, len); 6984 if (!buf) 6985 return QDF_STATUS_E_NOMEM; 6986 6987 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 6988 6989 WMITLV_SET_HDR(&cmd->tlv_header, 6990 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 6991 WMITLV_GET_STRUCT_TLVLEN 6992 (wmi_11d_scan_start_cmd_fixed_param)); 6993 6994 cmd->vdev_id = start_11d_scan->vdev_id; 6995 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 6996 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 6997 6998 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 6999 7000 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7001 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7002 WMI_11D_SCAN_START_CMDID); 7003 if (ret) { 7004 wmi_err("Failed to send start 11d scan wmi cmd"); 7005 wmi_buf_free(buf); 7006 return QDF_STATUS_E_FAILURE; 7007 } 7008 7009 return QDF_STATUS_SUCCESS; 7010 } 7011 7012 /** 7013 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7014 * @wmi_handle: wmi handle 7015 * @start_11d_scan: 11d scan stop request parameters 7016 * 7017 * This function request FW to stop 11d scan. 7018 * 7019 * Return: QDF status 7020 */ 7021 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7022 struct reg_stop_11d_scan_req *stop_11d_scan) 7023 { 7024 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7025 int32_t len; 7026 wmi_buf_t buf; 7027 int ret; 7028 7029 len = sizeof(*cmd); 7030 buf = wmi_buf_alloc(wmi_handle, len); 7031 if (!buf) 7032 return QDF_STATUS_E_NOMEM; 7033 7034 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7035 7036 WMITLV_SET_HDR(&cmd->tlv_header, 7037 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7038 WMITLV_GET_STRUCT_TLVLEN 7039 (wmi_11d_scan_stop_cmd_fixed_param)); 7040 7041 cmd->vdev_id = stop_11d_scan->vdev_id; 7042 7043 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7044 7045 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7046 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7047 WMI_11D_SCAN_STOP_CMDID); 7048 if (ret) { 7049 wmi_err("Failed to send stop 11d scan wmi cmd"); 7050 wmi_buf_free(buf); 7051 return QDF_STATUS_E_FAILURE; 7052 } 7053 7054 return QDF_STATUS_SUCCESS; 7055 } 7056 7057 /** 7058 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7059 * @wmi_handle: wmi handle 7060 * @data_len: the length of @data 7061 * @data: the pointer to data buf 7062 * 7063 * Return: CDF status 7064 */ 7065 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7066 uint32_t data_len, 7067 uint8_t *data) 7068 { 7069 wmi_buf_t buf; 7070 uint8_t *cmd; 7071 QDF_STATUS ret; 7072 7073 buf = wmi_buf_alloc(wmi_handle, 7074 (data_len + WMI_TLV_HDR_SIZE)); 7075 if (!buf) 7076 return QDF_STATUS_E_FAILURE; 7077 7078 cmd = (uint8_t *) wmi_buf_data(buf); 7079 7080 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7081 cmd += WMI_TLV_HDR_SIZE; 7082 qdf_mem_copy(cmd, data, 7083 data_len); 7084 7085 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7086 7087 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7088 ret = wmi_unified_cmd_send(wmi_handle, buf, 7089 (data_len + 7090 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7091 7092 if (QDF_IS_STATUS_ERROR(ret)) { 7093 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7094 wmi_buf_free(buf); 7095 } 7096 7097 return ret; 7098 } 7099 7100 #ifdef FEATURE_OEM_DATA 7101 /** 7102 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7103 * @wmi_handle: wmi handle 7104 * @oem_data: the pointer to oem data 7105 * 7106 * Return: QDF status 7107 */ 7108 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7109 struct oem_data *oem_data) 7110 { 7111 QDF_STATUS ret; 7112 wmi_oem_data_cmd_fixed_param *cmd; 7113 struct wmi_ops *ops; 7114 wmi_buf_t buf; 7115 uint16_t len = sizeof(*cmd); 7116 uint16_t oem_data_len_aligned; 7117 uint8_t *buf_ptr; 7118 uint32_t pdev_id; 7119 7120 if (!oem_data || !oem_data->data) { 7121 wmi_err_rl("oem data is not valid"); 7122 return QDF_STATUS_E_FAILURE; 7123 } 7124 7125 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7126 if (oem_data_len_aligned < oem_data->data_len) { 7127 wmi_err_rl("integer overflow while rounding up data_len"); 7128 return QDF_STATUS_E_FAILURE; 7129 } 7130 7131 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7132 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7133 return QDF_STATUS_E_FAILURE; 7134 } 7135 7136 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7137 buf = wmi_buf_alloc(wmi_handle, len); 7138 if (!buf) 7139 return QDF_STATUS_E_NOMEM; 7140 7141 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7142 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7143 WMITLV_SET_HDR(&cmd->tlv_header, 7144 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7145 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7146 7147 pdev_id = oem_data->pdev_id; 7148 if (oem_data->pdev_vdev_flag) { 7149 ops = wmi_handle->ops; 7150 if (oem_data->is_host_pdev_id) 7151 pdev_id = 7152 ops->convert_host_pdev_id_to_target(wmi_handle, 7153 pdev_id); 7154 else 7155 pdev_id = 7156 ops->convert_pdev_id_host_to_target(wmi_handle, 7157 pdev_id); 7158 } 7159 7160 cmd->vdev_id = oem_data->vdev_id; 7161 cmd->data_len = oem_data->data_len; 7162 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7163 cmd->pdev_id = pdev_id; 7164 7165 buf_ptr += sizeof(*cmd); 7166 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7167 buf_ptr += WMI_TLV_HDR_SIZE; 7168 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7169 7170 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7171 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7172 if (QDF_IS_STATUS_ERROR(ret)) { 7173 wmi_err_rl("Failed with ret = %d", ret); 7174 wmi_buf_free(buf); 7175 } 7176 7177 return ret; 7178 } 7179 #endif 7180 7181 /** 7182 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7183 * @wmi_handle: wmi handle 7184 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7185 * 7186 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7187 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7188 * to firmware based on phyerr filtering 7189 * offload status. 7190 * 7191 * Return: 1 success, 0 failure 7192 */ 7193 static QDF_STATUS 7194 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7195 bool dfs_phyerr_filter_offload) 7196 { 7197 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7198 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7199 wmi_buf_t buf; 7200 uint16_t len; 7201 QDF_STATUS ret; 7202 7203 7204 if (false == dfs_phyerr_filter_offload) { 7205 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7206 len = sizeof(*disable_phyerr_offload_cmd); 7207 buf = wmi_buf_alloc(wmi_handle, len); 7208 if (!buf) 7209 return 0; 7210 7211 disable_phyerr_offload_cmd = 7212 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7213 wmi_buf_data(buf); 7214 7215 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7216 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7217 WMITLV_GET_STRUCT_TLVLEN 7218 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7219 7220 /* 7221 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7222 * to the firmware to disable the phyerror 7223 * filtering offload. 7224 */ 7225 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7226 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7227 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7228 if (QDF_IS_STATUS_ERROR(ret)) { 7229 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7230 ret); 7231 wmi_buf_free(buf); 7232 return QDF_STATUS_E_FAILURE; 7233 } 7234 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7235 } else { 7236 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7237 7238 len = sizeof(*enable_phyerr_offload_cmd); 7239 buf = wmi_buf_alloc(wmi_handle, len); 7240 if (!buf) 7241 return QDF_STATUS_E_FAILURE; 7242 7243 enable_phyerr_offload_cmd = 7244 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7245 wmi_buf_data(buf); 7246 7247 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7248 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7249 WMITLV_GET_STRUCT_TLVLEN 7250 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7251 7252 /* 7253 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7254 * to the firmware to enable the phyerror 7255 * filtering offload. 7256 */ 7257 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7258 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7259 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7260 7261 if (QDF_IS_STATUS_ERROR(ret)) { 7262 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7263 wmi_buf_free(buf); 7264 return QDF_STATUS_E_FAILURE; 7265 } 7266 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7267 } 7268 7269 return QDF_STATUS_SUCCESS; 7270 } 7271 7272 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7273 /** 7274 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7275 * @wmi_handle: wmi handle 7276 * @pktlog_event: pktlog event 7277 * @cmd_id: pktlog cmd id 7278 * @user_triggered: user triggered input for PKTLOG enable mode 7279 * 7280 * Return: CDF status 7281 */ 7282 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7283 WMI_PKTLOG_EVENT pktlog_event, 7284 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7285 { 7286 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7287 WMI_CMD_ID CMD_ID; 7288 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7289 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7290 int len = 0; 7291 wmi_buf_t buf; 7292 int32_t idx, max_idx; 7293 7294 PKTLOG_EVENT = pktlog_event; 7295 CMD_ID = cmd_id; 7296 7297 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7298 switch (CMD_ID) { 7299 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7300 len = sizeof(*cmd); 7301 buf = wmi_buf_alloc(wmi_handle, len); 7302 if (!buf) 7303 return QDF_STATUS_E_NOMEM; 7304 7305 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7306 wmi_buf_data(buf); 7307 WMITLV_SET_HDR(&cmd->tlv_header, 7308 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7309 WMITLV_GET_STRUCT_TLVLEN 7310 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7311 cmd->evlist = 0; 7312 for (idx = 0; idx < max_idx; idx++) { 7313 if (PKTLOG_EVENT & (1 << idx)) 7314 cmd->evlist |= pktlog_event_tlv[idx]; 7315 } 7316 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7317 : WMI_PKTLOG_ENABLE_AUTO; 7318 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7319 wmi_handle, 7320 WMI_HOST_PDEV_ID_SOC); 7321 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7322 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7323 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7324 wmi_err("Failed to send pktlog enable cmdid"); 7325 goto wmi_send_failed; 7326 } 7327 break; 7328 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7329 len = sizeof(*disable_cmd); 7330 buf = wmi_buf_alloc(wmi_handle, len); 7331 if (!buf) 7332 return QDF_STATUS_E_NOMEM; 7333 7334 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7335 wmi_buf_data(buf); 7336 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7337 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7338 WMITLV_GET_STRUCT_TLVLEN 7339 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7340 disable_cmd->pdev_id = 7341 wmi_handle->ops->convert_pdev_id_host_to_target( 7342 wmi_handle, 7343 WMI_HOST_PDEV_ID_SOC); 7344 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7345 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7346 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7347 wmi_err("failed to send pktlog disable cmdid"); 7348 goto wmi_send_failed; 7349 } 7350 break; 7351 default: 7352 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7353 break; 7354 } 7355 7356 return QDF_STATUS_SUCCESS; 7357 7358 wmi_send_failed: 7359 wmi_buf_free(buf); 7360 return QDF_STATUS_E_FAILURE; 7361 } 7362 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7363 7364 /** 7365 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7366 * @wmi_handle: wmi handle 7367 * @preq: stats ext params 7368 * 7369 * Return: CDF status 7370 */ 7371 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7372 struct stats_ext_params *preq) 7373 { 7374 QDF_STATUS ret; 7375 wmi_req_stats_ext_cmd_fixed_param *cmd; 7376 wmi_buf_t buf; 7377 size_t len; 7378 uint8_t *buf_ptr; 7379 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7380 uint32_t *vdev_bitmap; 7381 7382 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7383 sizeof(*cmd))) { 7384 wmi_err("Data length=%d is greater than max wmi msg size", 7385 preq->request_data_len); 7386 return QDF_STATUS_E_FAILURE; 7387 } 7388 7389 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7390 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7391 7392 buf = wmi_buf_alloc(wmi_handle, len); 7393 if (!buf) 7394 return QDF_STATUS_E_NOMEM; 7395 7396 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7397 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7398 7399 WMITLV_SET_HDR(&cmd->tlv_header, 7400 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7401 WMITLV_GET_STRUCT_TLVLEN 7402 (wmi_req_stats_ext_cmd_fixed_param)); 7403 cmd->vdev_id = preq->vdev_id; 7404 cmd->data_len = preq->request_data_len; 7405 7406 wmi_debug("The data len value is %u and vdev id set is %u", 7407 preq->request_data_len, preq->vdev_id); 7408 7409 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7410 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7411 7412 buf_ptr += WMI_TLV_HDR_SIZE; 7413 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7414 7415 buf_ptr += cmd->data_len; 7416 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7417 7418 buf_ptr += WMI_TLV_HDR_SIZE; 7419 7420 vdev_bitmap = (A_UINT32 *)buf_ptr; 7421 7422 vdev_bitmap[0] = preq->vdev_id_bitmap; 7423 7424 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7425 7426 buf_ptr += sizeof(uint32_t); 7427 7428 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7429 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7430 WMI_REQUEST_STATS_EXT_CMDID); 7431 if (QDF_IS_STATUS_ERROR(ret)) { 7432 wmi_err("Failed to send notify cmd ret = %d", ret); 7433 wmi_buf_free(buf); 7434 } 7435 7436 return ret; 7437 } 7438 7439 /** 7440 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7441 * @wmi_handle: wmi handle 7442 * @params: DHCP server offload info 7443 * 7444 * Return: QDF_STATUS_SUCCESS for success or error code 7445 */ 7446 static QDF_STATUS 7447 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7448 struct dhcp_offload_info_params *params) 7449 { 7450 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7451 wmi_buf_t buf; 7452 QDF_STATUS status; 7453 7454 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7455 if (!buf) 7456 return QDF_STATUS_E_NOMEM; 7457 7458 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7459 7460 WMITLV_SET_HDR(&cmd->tlv_header, 7461 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7462 WMITLV_GET_STRUCT_TLVLEN 7463 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7464 cmd->vdev_id = params->vdev_id; 7465 cmd->enable = params->dhcp_offload_enabled; 7466 cmd->num_client = params->dhcp_client_num; 7467 cmd->srv_ipv4 = params->dhcp_srv_addr; 7468 cmd->start_lsb = 0; 7469 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7470 status = wmi_unified_cmd_send(wmi_handle, buf, 7471 sizeof(*cmd), 7472 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7473 if (QDF_IS_STATUS_ERROR(status)) { 7474 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7475 wmi_buf_free(buf); 7476 return QDF_STATUS_E_FAILURE; 7477 } 7478 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7479 7480 return status; 7481 } 7482 7483 /** 7484 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7485 * @wmi_handle: wmi handle 7486 * @param: pointer to pdev regdomain params 7487 * 7488 * Return: 0 for success or error code 7489 */ 7490 static QDF_STATUS 7491 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7492 struct pdev_set_regdomain_params *param) 7493 { 7494 wmi_buf_t buf; 7495 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7496 int32_t len = sizeof(*cmd); 7497 7498 buf = wmi_buf_alloc(wmi_handle, len); 7499 if (!buf) 7500 return QDF_STATUS_E_NOMEM; 7501 7502 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7503 WMITLV_SET_HDR(&cmd->tlv_header, 7504 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7505 WMITLV_GET_STRUCT_TLVLEN 7506 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7507 7508 cmd->reg_domain = param->currentRDinuse; 7509 cmd->reg_domain_2G = param->currentRD2G; 7510 cmd->reg_domain_5G = param->currentRD5G; 7511 cmd->conformance_test_limit_2G = param->ctl_2G; 7512 cmd->conformance_test_limit_5G = param->ctl_5G; 7513 cmd->dfs_domain = param->dfsDomain; 7514 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7515 wmi_handle, 7516 param->pdev_id); 7517 7518 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7519 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7520 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7521 wmi_err("Failed to send pdev set regdomain command"); 7522 wmi_buf_free(buf); 7523 return QDF_STATUS_E_FAILURE; 7524 } 7525 7526 return QDF_STATUS_SUCCESS; 7527 } 7528 7529 /** 7530 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7531 * @wmi_handle: wmi handle 7532 * @reg_dmn: reg domain 7533 * @regdmn2G: 2G reg domain 7534 * @regdmn5G: 5G reg domain 7535 * @ctl2G: 2G test limit 7536 * @ctl5G: 5G test limit 7537 * 7538 * Return: none 7539 */ 7540 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7541 uint32_t reg_dmn, uint16_t regdmn2G, 7542 uint16_t regdmn5G, uint8_t ctl2G, 7543 uint8_t ctl5G) 7544 { 7545 wmi_buf_t buf; 7546 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7547 int32_t len = sizeof(*cmd); 7548 7549 7550 buf = wmi_buf_alloc(wmi_handle, len); 7551 if (!buf) 7552 return QDF_STATUS_E_NOMEM; 7553 7554 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7555 WMITLV_SET_HDR(&cmd->tlv_header, 7556 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7557 WMITLV_GET_STRUCT_TLVLEN 7558 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7559 cmd->reg_domain = reg_dmn; 7560 cmd->reg_domain_2G = regdmn2G; 7561 cmd->reg_domain_5G = regdmn5G; 7562 cmd->conformance_test_limit_2G = ctl2G; 7563 cmd->conformance_test_limit_5G = ctl5G; 7564 7565 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 7566 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 7567 cmd->conformance_test_limit_2G, 7568 cmd->conformance_test_limit_5G); 7569 7570 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7571 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7572 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7573 wmi_err("Failed to send pdev set regdomain command"); 7574 wmi_buf_free(buf); 7575 return QDF_STATUS_E_FAILURE; 7576 } 7577 7578 return QDF_STATUS_SUCCESS; 7579 } 7580 7581 /** 7582 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 7583 * @param: param sent from the host side 7584 * @cmd: param to be sent to the fw side 7585 */ 7586 static inline void copy_custom_aggr_bitmap( 7587 struct set_custom_aggr_size_params *param, 7588 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 7589 { 7590 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 7591 param->ac); 7592 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 7593 param->aggr_type); 7594 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7595 param->tx_aggr_size_disable); 7596 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7597 param->rx_aggr_size_disable); 7598 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 7599 param->tx_ac_enable); 7600 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 7601 param->aggr_ba_enable); 7602 } 7603 7604 /** 7605 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 7606 * @wmi_handle: wmi handle 7607 * @param: pointer to hold custom aggr size params 7608 * 7609 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7610 */ 7611 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 7612 wmi_unified_t wmi_handle, 7613 struct set_custom_aggr_size_params *param) 7614 { 7615 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 7616 wmi_buf_t buf; 7617 int32_t len = sizeof(*cmd); 7618 7619 buf = wmi_buf_alloc(wmi_handle, len); 7620 if (!buf) 7621 return QDF_STATUS_E_FAILURE; 7622 7623 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7624 wmi_buf_data(buf); 7625 WMITLV_SET_HDR(&cmd->tlv_header, 7626 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7627 WMITLV_GET_STRUCT_TLVLEN( 7628 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7629 cmd->vdev_id = param->vdev_id; 7630 cmd->tx_aggr_size = param->tx_aggr_size; 7631 cmd->rx_aggr_size = param->rx_aggr_size; 7632 copy_custom_aggr_bitmap(param, cmd); 7633 7634 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7635 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7636 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7637 "tx_ac_enable=0x%X", 7638 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7639 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7640 param->rx_aggr_size_disable, param->tx_ac_enable); 7641 7642 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7643 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7644 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7645 wmi_err("Setting custom aggregation size failed"); 7646 wmi_buf_free(buf); 7647 return QDF_STATUS_E_FAILURE; 7648 } 7649 7650 return QDF_STATUS_SUCCESS; 7651 } 7652 7653 /** 7654 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7655 * @param wmi_handle : handle to WMI. 7656 * @param param : pointer to tx antenna param 7657 * 7658 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7659 */ 7660 7661 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7662 struct set_qdepth_thresh_params *param) 7663 { 7664 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7665 wmi_msduq_qdepth_thresh_update *cmd_update; 7666 wmi_buf_t buf; 7667 int32_t len = 0; 7668 int i; 7669 uint8_t *buf_ptr; 7670 QDF_STATUS ret; 7671 7672 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7673 wmi_err("Invalid Update Count!"); 7674 return QDF_STATUS_E_INVAL; 7675 } 7676 7677 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7678 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7679 param->num_of_msduq_updates); 7680 buf = wmi_buf_alloc(wmi_handle, len); 7681 7682 if (!buf) 7683 return QDF_STATUS_E_NOMEM; 7684 7685 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7686 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7687 buf_ptr; 7688 7689 WMITLV_SET_HDR(&cmd->tlv_header, 7690 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7691 , WMITLV_GET_STRUCT_TLVLEN( 7692 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7693 7694 cmd->pdev_id = 7695 wmi_handle->ops->convert_pdev_id_host_to_target( 7696 wmi_handle, 7697 param->pdev_id); 7698 cmd->vdev_id = param->vdev_id; 7699 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7700 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7701 7702 buf_ptr += sizeof( 7703 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7704 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7705 param->num_of_msduq_updates * 7706 sizeof(wmi_msduq_qdepth_thresh_update)); 7707 buf_ptr += WMI_TLV_HDR_SIZE; 7708 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7709 7710 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7711 WMITLV_SET_HDR(&cmd_update->tlv_header, 7712 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7713 WMITLV_GET_STRUCT_TLVLEN( 7714 wmi_msduq_qdepth_thresh_update)); 7715 cmd_update->tid_num = param->update_params[i].tid_num; 7716 cmd_update->msduq_update_mask = 7717 param->update_params[i].msduq_update_mask; 7718 cmd_update->qdepth_thresh_value = 7719 param->update_params[i].qdepth_thresh_value; 7720 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7721 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7722 " update mask=0x%X thresh val=0x%X", 7723 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7724 cmd->peer_mac_address.mac_addr31to0, 7725 cmd->peer_mac_address.mac_addr47to32, 7726 cmd_update->msduq_update_mask, 7727 cmd_update->qdepth_thresh_value); 7728 cmd_update++; 7729 } 7730 7731 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7732 cmd->vdev_id, 0); 7733 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7734 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7735 7736 if (ret != 0) { 7737 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7738 wmi_buf_free(buf); 7739 } 7740 7741 return ret; 7742 } 7743 7744 /** 7745 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7746 * @wmi_handle: wmi handle 7747 * @param: pointer to hold vap dscp tid map param 7748 * 7749 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7750 */ 7751 static QDF_STATUS 7752 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7753 struct vap_dscp_tid_map_params *param) 7754 { 7755 wmi_buf_t buf; 7756 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7757 int32_t len = sizeof(*cmd); 7758 7759 buf = wmi_buf_alloc(wmi_handle, len); 7760 if (!buf) 7761 return QDF_STATUS_E_FAILURE; 7762 7763 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7764 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7765 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7766 7767 cmd->vdev_id = param->vdev_id; 7768 cmd->enable_override = 0; 7769 7770 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7771 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7772 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7773 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7774 wmi_err("Failed to set dscp cmd"); 7775 wmi_buf_free(buf); 7776 return QDF_STATUS_E_FAILURE; 7777 } 7778 7779 return QDF_STATUS_SUCCESS; 7780 } 7781 7782 /** 7783 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7784 * @wmi_handle: wmi handle 7785 * @param: pointer to hold fwtest param 7786 * 7787 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7788 */ 7789 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7790 struct set_fwtest_params *param) 7791 { 7792 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7793 wmi_buf_t buf; 7794 int32_t len = sizeof(*cmd); 7795 7796 buf = wmi_buf_alloc(wmi_handle, len); 7797 7798 if (!buf) 7799 return QDF_STATUS_E_FAILURE; 7800 7801 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7802 WMITLV_SET_HDR(&cmd->tlv_header, 7803 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7804 WMITLV_GET_STRUCT_TLVLEN( 7805 wmi_fwtest_set_param_cmd_fixed_param)); 7806 cmd->param_id = param->arg; 7807 cmd->param_value = param->value; 7808 7809 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7810 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7811 wmi_err("Setting FW test param failed"); 7812 wmi_buf_free(buf); 7813 return QDF_STATUS_E_FAILURE; 7814 } 7815 7816 return QDF_STATUS_SUCCESS; 7817 } 7818 7819 /** 7820 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7821 * 7822 * @param wmi_handle : handle to WMI. 7823 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7824 */ 7825 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7826 { 7827 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7828 wmi_buf_t buf; 7829 QDF_STATUS ret; 7830 int32_t len; 7831 7832 len = sizeof(*cmd); 7833 7834 buf = wmi_buf_alloc(wmi_handle, len); 7835 if (!buf) 7836 return QDF_STATUS_E_FAILURE; 7837 7838 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7839 WMITLV_SET_HDR(&cmd->tlv_header, 7840 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7841 WMITLV_GET_STRUCT_TLVLEN( 7842 wmi_pdev_dfs_disable_cmd_fixed_param)); 7843 /* Filling it with WMI_PDEV_ID_SOC for now */ 7844 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7845 wmi_handle, 7846 WMI_HOST_PDEV_ID_SOC); 7847 7848 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7849 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7850 WMI_PDEV_DFS_DISABLE_CMDID); 7851 7852 if (ret != 0) { 7853 wmi_err("Sending PDEV DFS disable cmd failed"); 7854 wmi_buf_free(buf); 7855 } 7856 7857 return ret; 7858 } 7859 7860 /** 7861 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 7862 * 7863 * @param wmi_handle : handle to WMI. 7864 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7865 */ 7866 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 7867 { 7868 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 7869 wmi_buf_t buf; 7870 QDF_STATUS ret; 7871 int32_t len; 7872 7873 len = sizeof(*cmd); 7874 7875 buf = wmi_buf_alloc(wmi_handle, len); 7876 if (!buf) 7877 return QDF_STATUS_E_FAILURE; 7878 7879 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 7880 WMITLV_SET_HDR(&cmd->tlv_header, 7881 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 7882 WMITLV_GET_STRUCT_TLVLEN( 7883 wmi_pdev_dfs_enable_cmd_fixed_param)); 7884 /* Reserved for future use */ 7885 cmd->reserved0 = 0; 7886 7887 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 7888 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7889 WMI_PDEV_DFS_ENABLE_CMDID); 7890 7891 if (ret != 0) { 7892 wmi_err("Sending PDEV DFS enable cmd failed"); 7893 wmi_buf_free(buf); 7894 } 7895 7896 return ret; 7897 } 7898 7899 /** 7900 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 7901 * to fw 7902 * @wmi_handle: wmi handle 7903 * @param: pointer to hold periodic chan stats param 7904 * 7905 * Return: 0 for success or error code 7906 */ 7907 static QDF_STATUS 7908 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 7909 struct periodic_chan_stats_params *param) 7910 { 7911 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 7912 wmi_buf_t buf; 7913 QDF_STATUS ret; 7914 int32_t len; 7915 7916 len = sizeof(*cmd); 7917 7918 buf = wmi_buf_alloc(wmi_handle, len); 7919 if (!buf) 7920 return QDF_STATUS_E_FAILURE; 7921 7922 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 7923 wmi_buf_data(buf); 7924 WMITLV_SET_HDR(&cmd->tlv_header, 7925 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 7926 WMITLV_GET_STRUCT_TLVLEN( 7927 wmi_set_periodic_channel_stats_config_fixed_param)); 7928 cmd->enable = param->enable; 7929 cmd->stats_period = param->stats_period; 7930 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7931 wmi_handle, 7932 param->pdev_id); 7933 7934 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 7935 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7936 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 7937 7938 if (ret != 0) { 7939 wmi_err("Sending periodic chan stats config failed"); 7940 wmi_buf_free(buf); 7941 } 7942 7943 return ret; 7944 } 7945 7946 #ifdef WLAN_IOT_SIM_SUPPORT 7947 /** 7948 * send_simulation_test_cmd_tlv() - send simulation test command to fw 7949 * 7950 * @wmi_handle: wmi handle 7951 * @param: pointer to hold simulation test parameter 7952 * 7953 * Return: 0 for success or error code 7954 */ 7955 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 7956 struct simulation_test_params 7957 *param) 7958 { 7959 wmi_simulation_test_cmd_fixed_param *cmd; 7960 u32 wmi_buf_len; 7961 wmi_buf_t buf; 7962 u8 *buf_ptr; 7963 u32 aligned_len = 0; 7964 7965 wmi_buf_len = sizeof(*cmd); 7966 if (param->buf_len) { 7967 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 7968 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 7969 } 7970 7971 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 7972 if (!buf) { 7973 wmi_err("wmi_buf_alloc failed"); 7974 return QDF_STATUS_E_NOMEM; 7975 } 7976 7977 buf_ptr = wmi_buf_data(buf); 7978 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 7979 WMITLV_SET_HDR(&cmd->tlv_header, 7980 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 7981 WMITLV_GET_STRUCT_TLVLEN( 7982 wmi_simulation_test_cmd_fixed_param)); 7983 cmd->pdev_id = param->pdev_id; 7984 cmd->vdev_id = param->vdev_id; 7985 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 7986 cmd->test_cmd_type = param->test_cmd_type; 7987 cmd->test_subcmd_type = param->test_subcmd_type; 7988 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 7989 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 7990 param->frame_subtype); 7991 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 7992 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 7993 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 7994 cmd->buf_len = param->buf_len; 7995 7996 if (param->buf_len) { 7997 buf_ptr += sizeof(*cmd); 7998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 7999 buf_ptr += WMI_TLV_HDR_SIZE; 8000 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8001 } 8002 8003 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8004 WMI_SIMULATION_TEST_CMDID)) { 8005 wmi_err("Failed to send test simulation cmd"); 8006 wmi_buf_free(buf); 8007 return QDF_STATUS_E_FAILURE; 8008 } 8009 8010 return QDF_STATUS_SUCCESS; 8011 } 8012 #endif 8013 8014 #ifdef WLAN_FEATURE_11BE 8015 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8016 #else 8017 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8018 #endif 8019 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8020 { 8021 switch (wmi_width) { 8022 case WMI_CHAN_WIDTH_20: 8023 return CH_WIDTH_20MHZ; 8024 case WMI_CHAN_WIDTH_40: 8025 return CH_WIDTH_40MHZ; 8026 case WMI_CHAN_WIDTH_80: 8027 return CH_WIDTH_80MHZ; 8028 case WMI_CHAN_WIDTH_160: 8029 return CH_WIDTH_160MHZ; 8030 case WMI_CHAN_WIDTH_80P80: 8031 return CH_WIDTH_80P80MHZ; 8032 case WMI_CHAN_WIDTH_5: 8033 return CH_WIDTH_5MHZ; 8034 case WMI_CHAN_WIDTH_10: 8035 return CH_WIDTH_10MHZ; 8036 case WMI_CHAN_WIDTH_320: 8037 return WLAN_PHY_CH_WIDTH_320MHZ; 8038 default: 8039 return CH_WIDTH_INVALID; 8040 } 8041 } 8042 8043 /** 8044 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8045 * command to fw 8046 * @wmi_handle: wmi handle 8047 * @param: pointer to hold spectral config parameter 8048 * 8049 * Return: 0 for success or error code 8050 */ 8051 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8052 struct vdev_spectral_configure_params *param) 8053 { 8054 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8055 wmi_buf_t buf; 8056 QDF_STATUS ret; 8057 int32_t len; 8058 8059 len = sizeof(*cmd); 8060 buf = wmi_buf_alloc(wmi_handle, len); 8061 if (!buf) 8062 return QDF_STATUS_E_FAILURE; 8063 8064 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8065 WMITLV_SET_HDR(&cmd->tlv_header, 8066 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8067 WMITLV_GET_STRUCT_TLVLEN( 8068 wmi_vdev_spectral_configure_cmd_fixed_param)); 8069 8070 cmd->vdev_id = param->vdev_id; 8071 cmd->spectral_scan_count = param->count; 8072 cmd->spectral_scan_period = param->period; 8073 cmd->spectral_scan_priority = param->spectral_pri; 8074 cmd->spectral_scan_fft_size = param->fft_size; 8075 cmd->spectral_scan_gc_ena = param->gc_enable; 8076 cmd->spectral_scan_restart_ena = param->restart_enable; 8077 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8078 cmd->spectral_scan_init_delay = param->init_delay; 8079 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8080 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8081 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8082 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8083 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8084 cmd->spectral_scan_pwr_format = param->pwr_format; 8085 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8086 cmd->spectral_scan_bin_scale = param->bin_scale; 8087 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8088 cmd->spectral_scan_chn_mask = param->chn_mask; 8089 cmd->spectral_scan_mode = param->mode; 8090 cmd->spectral_scan_center_freq1 = param->center_freq1; 8091 cmd->spectral_scan_center_freq2 = param->center_freq2; 8092 cmd->spectral_scan_chan_width = param->chan_width; 8093 cmd->recapture_sample_on_gain_change = param->fft_recap; 8094 /* Not used, fill with zeros */ 8095 cmd->spectral_scan_chan_freq = 0; 8096 8097 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8098 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8099 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8100 8101 if (ret != 0) { 8102 wmi_err("Sending set quiet cmd failed"); 8103 wmi_buf_free(buf); 8104 } 8105 8106 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8107 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8108 param->vdev_id, param->count); 8109 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8110 param->period, param->spectral_pri); 8111 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8112 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8113 param->fft_size, param->gc_enable); 8114 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8115 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8116 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8117 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8118 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8119 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8120 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8121 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8122 param->rssi_thr, param->pwr_format); 8123 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8124 param->rpt_mode, param->bin_scale); 8125 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8126 param->dbm_adj, param->chn_mask); 8127 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8128 param->mode, param->center_freq1); 8129 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8130 param->center_freq2, param->chan_freq); 8131 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8132 param->chan_width, ret); 8133 8134 return ret; 8135 } 8136 8137 /** 8138 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8139 * command to fw 8140 * @wmi_handle: wmi handle 8141 * @param: pointer to hold spectral enable parameter 8142 * 8143 * Return: 0 for success or error code 8144 */ 8145 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8146 struct vdev_spectral_enable_params *param) 8147 { 8148 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8149 wmi_buf_t buf; 8150 QDF_STATUS ret; 8151 int32_t len; 8152 8153 len = sizeof(*cmd); 8154 buf = wmi_buf_alloc(wmi_handle, len); 8155 if (!buf) 8156 return QDF_STATUS_E_FAILURE; 8157 8158 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8159 WMITLV_SET_HDR(&cmd->tlv_header, 8160 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8161 WMITLV_GET_STRUCT_TLVLEN( 8162 wmi_vdev_spectral_enable_cmd_fixed_param)); 8163 8164 cmd->vdev_id = param->vdev_id; 8165 8166 if (param->active_valid) { 8167 cmd->trigger_cmd = param->active ? 1 : 2; 8168 /* 1: Trigger, 2: Clear Trigger */ 8169 } else { 8170 cmd->trigger_cmd = 0; /* 0: Ignore */ 8171 } 8172 8173 if (param->enabled_valid) { 8174 cmd->enable_cmd = param->enabled ? 1 : 2; 8175 /* 1: Enable 2: Disable */ 8176 } else { 8177 cmd->enable_cmd = 0; /* 0: Ignore */ 8178 } 8179 cmd->spectral_scan_mode = param->mode; 8180 8181 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8182 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8183 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8184 8185 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8186 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8187 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8188 8189 if (ret != 0) { 8190 wmi_err("Sending scan enable CMD failed"); 8191 wmi_buf_free(buf); 8192 } 8193 8194 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8195 ret); 8196 8197 return ret; 8198 } 8199 8200 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8201 static QDF_STATUS 8202 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8203 wmi_unified_t wmi_handle, 8204 uint8_t *event, struct spectral_startscan_resp_params *param) 8205 { 8206 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8207 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8208 8209 if (!wmi_handle) { 8210 wmi_err("WMI handle is null"); 8211 return QDF_STATUS_E_INVAL; 8212 } 8213 8214 if (!event) { 8215 wmi_err("WMI event is null"); 8216 return QDF_STATUS_E_INVAL; 8217 } 8218 8219 if (!param) { 8220 wmi_err("Spectral startscan response params is null"); 8221 return QDF_STATUS_E_INVAL; 8222 } 8223 8224 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8225 if (!param_buf) 8226 return QDF_STATUS_E_INVAL; 8227 8228 ev = param_buf->fixed_param; 8229 if (!ev) 8230 return QDF_STATUS_E_INVAL; 8231 8232 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8233 wmi_handle, 8234 ev->pdev_id); 8235 param->smode = ev->spectral_scan_mode; 8236 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8237 param->num_det_info = param_buf->num_det_info; 8238 8239 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8240 ev->pdev_id, ev->spectral_scan_mode, 8241 param_buf->num_fft_bin_index, param_buf->num_det_info); 8242 8243 return QDF_STATUS_SUCCESS; 8244 } 8245 8246 static QDF_STATUS 8247 extract_pdev_sscan_fft_bin_index_tlv( 8248 wmi_unified_t wmi_handle, uint8_t *event, 8249 struct spectral_fft_bin_markers_160_165mhz *param) 8250 { 8251 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8252 wmi_pdev_sscan_fft_bin_index *ev; 8253 8254 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8255 if (!param_buf) 8256 return QDF_STATUS_E_INVAL; 8257 8258 ev = param_buf->fft_bin_index; 8259 if (!ev) 8260 return QDF_STATUS_E_INVAL; 8261 8262 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8263 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8264 param->start_pri80 + 1; 8265 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8266 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8267 param->start_sec80 + 1; 8268 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8269 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8270 param->start_5mhz + 1; 8271 param->is_valid = true; 8272 8273 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8274 param->start_pri80, param->num_pri80, 8275 param->start_sec80, param->num_sec80, 8276 param->start_5mhz, param->num_5mhz); 8277 8278 return QDF_STATUS_SUCCESS; 8279 } 8280 8281 /** 8282 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8283 * for a spectral scan session 8284 * @wmi_handle: handle to WMI. 8285 * @event: Event buffer 8286 * @chan_info: Spectral session channel information data structure to be filled 8287 * by this API 8288 * 8289 * Return: QDF_STATUS of operation 8290 */ 8291 static QDF_STATUS 8292 extract_pdev_spectral_session_chan_info_tlv( 8293 wmi_unified_t wmi_handle, void *event, 8294 struct spectral_session_chan_info *chan_info) 8295 { 8296 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8297 wmi_pdev_sscan_chan_info *chan_info_tlv; 8298 8299 if (!param_buf) { 8300 wmi_err("param_buf is NULL"); 8301 return QDF_STATUS_E_NULL_VALUE; 8302 } 8303 8304 if (!chan_info) { 8305 wmi_err("chan_info is NULL"); 8306 return QDF_STATUS_E_NULL_VALUE; 8307 } 8308 8309 chan_info_tlv = param_buf->chan_info; 8310 if (!chan_info_tlv) { 8311 wmi_err("chan_info tlv is not present in the event"); 8312 return QDF_STATUS_E_NULL_VALUE; 8313 } 8314 8315 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8316 "operating_cfreq2:%u operating_bw:%u" 8317 "operating_puncture_20mhz_bitmap:%u" 8318 "sscan_cfreq1:%u sscan_cfreq2:%u" 8319 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8320 chan_info_tlv->operating_pri20_freq, 8321 chan_info_tlv->operating_cfreq1, 8322 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8323 chan_info_tlv->operating_puncture_20mhz_bitmap, 8324 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8325 chan_info_tlv->sscan_bw, 8326 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8327 8328 chan_info->operating_pri20_freq = 8329 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8330 chan_info->operating_cfreq1 = 8331 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8332 chan_info->operating_cfreq2 = 8333 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8334 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8335 chan_info->operating_puncture_20mhz_bitmap = 8336 chan_info_tlv->operating_puncture_20mhz_bitmap; 8337 8338 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8339 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8340 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8341 chan_info->sscan_puncture_20mhz_bitmap = 8342 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8343 8344 return QDF_STATUS_SUCCESS; 8345 } 8346 8347 static QDF_STATUS 8348 extract_pdev_spectral_session_detector_info_tlv( 8349 wmi_unified_t wmi_handle, void *event, 8350 struct spectral_session_det_info *det_info, uint8_t idx) 8351 { 8352 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8353 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8354 8355 if (!param_buf) { 8356 wmi_err("param_buf is NULL"); 8357 return QDF_STATUS_E_NULL_VALUE; 8358 } 8359 8360 if (!det_info) { 8361 wmi_err("chan_info is NULL"); 8362 return QDF_STATUS_E_NULL_VALUE; 8363 } 8364 8365 if (!param_buf->det_info) { 8366 wmi_err("det_info tlv is not present in the event"); 8367 return QDF_STATUS_E_NULL_VALUE; 8368 } 8369 8370 if (idx >= param_buf->num_det_info) { 8371 wmi_err("det_info index(%u) is greater than or equal to %u", 8372 idx, param_buf->num_det_info); 8373 return QDF_STATUS_E_FAILURE; 8374 } 8375 8376 det_info_tlv = ¶m_buf->det_info[idx]; 8377 8378 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8379 idx, det_info_tlv->detector_id, 8380 det_info_tlv->start_freq, det_info_tlv->end_freq); 8381 8382 det_info->det_id = det_info_tlv->detector_id; 8383 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8384 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8385 8386 return QDF_STATUS_SUCCESS; 8387 } 8388 8389 /** 8390 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8391 * capabilities WMI event 8392 * @wmi_handle: handle to WMI. 8393 * @event: Event buffer 8394 * @param: Spectral capabilities event parameters data structure to be filled 8395 * by this API 8396 * 8397 * Return: QDF_STATUS of operation 8398 */ 8399 static QDF_STATUS 8400 extract_spectral_caps_fixed_param_tlv( 8401 wmi_unified_t wmi_handle, void *event, 8402 struct spectral_capabilities_event_params *params) 8403 { 8404 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8405 8406 if (!param_buf) { 8407 wmi_err("param_buf is NULL"); 8408 return QDF_STATUS_E_NULL_VALUE; 8409 } 8410 8411 if (!params) { 8412 wmi_err("event parameters is NULL"); 8413 return QDF_STATUS_E_NULL_VALUE; 8414 } 8415 8416 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 8417 params->num_fft_size_caps = param_buf->num_fft_size_caps; 8418 8419 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 8420 params->num_sscan_bw_caps, params->num_fft_size_caps); 8421 8422 return QDF_STATUS_SUCCESS; 8423 } 8424 8425 /** 8426 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 8427 * Spectral capabilities WMI event 8428 * @wmi_handle: handle to WMI. 8429 * @event: Event buffer 8430 * @bw_caps: Data structure to be populated by this API after extraction 8431 * 8432 * Return: QDF_STATUS of operation 8433 */ 8434 static QDF_STATUS 8435 extract_spectral_scan_bw_caps_tlv( 8436 wmi_unified_t wmi_handle, void *event, 8437 struct spectral_scan_bw_capabilities *bw_caps) 8438 { 8439 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8440 int idx; 8441 8442 if (!param_buf) { 8443 wmi_err("param_buf is NULL"); 8444 return QDF_STATUS_E_NULL_VALUE; 8445 } 8446 8447 if (!bw_caps) { 8448 wmi_err("bw_caps is null"); 8449 return QDF_STATUS_E_NULL_VALUE; 8450 } 8451 8452 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 8453 bw_caps[idx].pdev_id = 8454 wmi_handle->ops->convert_pdev_id_target_to_host( 8455 wmi_handle, 8456 param_buf->sscan_bw_caps[idx].pdev_id); 8457 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 8458 bw_caps[idx].operating_bw = wmi_map_ch_width( 8459 param_buf->sscan_bw_caps[idx].operating_bw); 8460 bw_caps[idx].supported_bws = 8461 param_buf->sscan_bw_caps[idx].supported_flags; 8462 8463 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 8464 "operating_bw:%u supported_flags:0x%x", 8465 idx, param_buf->sscan_bw_caps[idx].pdev_id, 8466 param_buf->sscan_bw_caps[idx].sscan_mode, 8467 param_buf->sscan_bw_caps[idx].operating_bw, 8468 param_buf->sscan_bw_caps[idx].supported_flags); 8469 } 8470 8471 return QDF_STATUS_SUCCESS; 8472 } 8473 8474 /** 8475 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 8476 * Spectral capabilities WMI event 8477 * @wmi_handle: handle to WMI. 8478 * @event: Event buffer 8479 * @fft_size_caps: Data structure to be populated by this API after extraction 8480 * 8481 * Return: QDF_STATUS of operation 8482 */ 8483 static QDF_STATUS 8484 extract_spectral_fft_size_caps_tlv( 8485 wmi_unified_t wmi_handle, void *event, 8486 struct spectral_fft_size_capabilities *fft_size_caps) 8487 { 8488 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8489 int idx; 8490 8491 if (!param_buf) { 8492 wmi_err("param_buf is NULL"); 8493 return QDF_STATUS_E_NULL_VALUE; 8494 } 8495 8496 if (!fft_size_caps) { 8497 wmi_err("fft size caps is NULL"); 8498 return QDF_STATUS_E_NULL_VALUE; 8499 } 8500 8501 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 8502 fft_size_caps[idx].pdev_id = 8503 wmi_handle->ops->convert_pdev_id_target_to_host( 8504 wmi_handle, 8505 param_buf->fft_size_caps[idx].pdev_id); 8506 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 8507 param_buf->fft_size_caps[idx].sscan_bw); 8508 fft_size_caps[idx].supports_fft_sizes = 8509 param_buf->fft_size_caps[idx].supported_flags; 8510 8511 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 8512 "supported_flags:0x%x", 8513 idx, param_buf->fft_size_caps[idx].pdev_id, 8514 param_buf->fft_size_caps[idx].sscan_bw, 8515 param_buf->fft_size_caps[idx].supported_flags); 8516 } 8517 8518 return QDF_STATUS_SUCCESS; 8519 } 8520 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 8521 8522 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 8523 static inline void 8524 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8525 struct thermal_mitigation_params *param) 8526 { 8527 tt_conf->client_id = param->client_id; 8528 tt_conf->priority = param->priority; 8529 } 8530 #else 8531 static inline void 8532 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8533 struct thermal_mitigation_params *param) 8534 { 8535 } 8536 #endif 8537 8538 /** 8539 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 8540 * @param wmi_handle : handle to WMI. 8541 * @param param : pointer to hold thermal mitigation param 8542 * 8543 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 8544 */ 8545 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 8546 wmi_unified_t wmi_handle, 8547 struct thermal_mitigation_params *param) 8548 { 8549 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 8550 wmi_therm_throt_level_config_info *lvl_conf = NULL; 8551 wmi_buf_t buf = NULL; 8552 uint8_t *buf_ptr = NULL; 8553 int error; 8554 int32_t len; 8555 int i; 8556 8557 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 8558 param->num_thermal_conf * 8559 sizeof(wmi_therm_throt_level_config_info); 8560 8561 buf = wmi_buf_alloc(wmi_handle, len); 8562 if (!buf) 8563 return QDF_STATUS_E_NOMEM; 8564 8565 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 8566 8567 /* init fixed params */ 8568 WMITLV_SET_HDR(tt_conf, 8569 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 8570 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 8571 8572 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8573 wmi_handle, 8574 param->pdev_id); 8575 tt_conf->enable = param->enable; 8576 tt_conf->dc = param->dc; 8577 tt_conf->dc_per_event = param->dc_per_event; 8578 tt_conf->therm_throt_levels = param->num_thermal_conf; 8579 wmi_fill_client_id_priority(tt_conf, param); 8580 buf_ptr = (uint8_t *) ++tt_conf; 8581 /* init TLV params */ 8582 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8583 (param->num_thermal_conf * 8584 sizeof(wmi_therm_throt_level_config_info))); 8585 8586 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 8587 for (i = 0; i < param->num_thermal_conf; i++) { 8588 WMITLV_SET_HDR(&lvl_conf->tlv_header, 8589 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 8590 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 8591 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 8592 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 8593 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 8594 lvl_conf->prio = param->levelconf[i].priority; 8595 lvl_conf++; 8596 } 8597 8598 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 8599 error = wmi_unified_cmd_send(wmi_handle, buf, len, 8600 WMI_THERM_THROT_SET_CONF_CMDID); 8601 if (QDF_IS_STATUS_ERROR(error)) { 8602 wmi_buf_free(buf); 8603 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 8604 } 8605 8606 return error; 8607 } 8608 8609 /** 8610 * send_coex_config_cmd_tlv() - send coex config command to fw 8611 * @wmi_handle: wmi handle 8612 * @param: pointer to coex config param 8613 * 8614 * Return: 0 for success or error code 8615 */ 8616 static QDF_STATUS 8617 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8618 struct coex_config_params *param) 8619 { 8620 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8621 wmi_buf_t buf; 8622 QDF_STATUS ret; 8623 int32_t len; 8624 8625 len = sizeof(*cmd); 8626 buf = wmi_buf_alloc(wmi_handle, len); 8627 if (!buf) 8628 return QDF_STATUS_E_FAILURE; 8629 8630 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8631 WMITLV_SET_HDR(&cmd->tlv_header, 8632 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8633 WMITLV_GET_STRUCT_TLVLEN( 8634 WMI_COEX_CONFIG_CMD_fixed_param)); 8635 8636 cmd->vdev_id = param->vdev_id; 8637 cmd->config_type = param->config_type; 8638 cmd->config_arg1 = param->config_arg1; 8639 cmd->config_arg2 = param->config_arg2; 8640 cmd->config_arg3 = param->config_arg3; 8641 cmd->config_arg4 = param->config_arg4; 8642 cmd->config_arg5 = param->config_arg5; 8643 cmd->config_arg6 = param->config_arg6; 8644 8645 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8646 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8647 WMI_COEX_CONFIG_CMDID); 8648 8649 if (ret != 0) { 8650 wmi_err("Sending COEX CONFIG CMD failed"); 8651 wmi_buf_free(buf); 8652 } 8653 8654 return ret; 8655 } 8656 8657 #ifdef WLAN_FEATURE_DBAM_CONFIG 8658 8659 static enum wmi_coex_dbam_mode_type 8660 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 8661 { 8662 switch (mode) { 8663 case COEX_DBAM_ENABLE: 8664 return WMI_COEX_DBAM_ENABLE; 8665 case COEX_DBAM_FORCE_ENABLE: 8666 return WMI_COEX_DBAM_FORCED; 8667 case COEX_DBAM_DISABLE: 8668 default: 8669 return WMI_COEX_DBAM_DISABLE; 8670 } 8671 } 8672 8673 /** 8674 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 8675 * @wmi_handle: wmi handle 8676 * @param: pointer to coex dbam config param 8677 * 8678 * Return: 0 for success or error code 8679 */ 8680 static QDF_STATUS 8681 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 8682 struct coex_dbam_config_params *param) 8683 { 8684 wmi_coex_dbam_cmd_fixed_param *cmd; 8685 wmi_buf_t buf; 8686 void *buf_ptr; 8687 QDF_STATUS ret; 8688 int32_t len; 8689 8690 len = sizeof(*cmd); 8691 buf = wmi_buf_alloc(wmi_handle, len); 8692 if (!buf) { 8693 wmi_err_rl("Failed to allocate wmi buffer"); 8694 return QDF_STATUS_E_NOMEM; 8695 } 8696 8697 buf_ptr = wmi_buf_data(buf); 8698 cmd = buf_ptr; 8699 WMITLV_SET_HDR(&cmd->tlv_header, 8700 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 8701 WMITLV_GET_STRUCT_TLVLEN( 8702 wmi_coex_dbam_cmd_fixed_param)); 8703 8704 cmd->vdev_id = param->vdev_id; 8705 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 8706 8707 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 8708 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8709 WMI_COEX_DBAM_CMDID); 8710 8711 if (QDF_IS_STATUS_ERROR(ret)) { 8712 wmi_err("Sending DBAM CONFIG CMD failed"); 8713 wmi_buf_free(buf); 8714 return QDF_STATUS_E_FAILURE; 8715 } 8716 8717 return ret; 8718 } 8719 8720 static enum coex_dbam_comp_status 8721 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 8722 { 8723 switch (status) { 8724 case WMI_COEX_DBAM_COMP_SUCCESS: 8725 case WMI_COEX_DBAM_COMP_ONGOING: 8726 case WMI_COEX_DBAM_COMP_DELAYED: 8727 return COEX_DBAM_COMP_SUCCESS; 8728 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 8729 return COEX_DBAM_COMP_NOT_SUPPORT; 8730 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 8731 case WMI_COEX_DBAM_COMP_FAIL: 8732 default: 8733 return COEX_DBAM_COMP_FAIL; 8734 } 8735 } 8736 8737 /** 8738 * extract_dbam_comp_status_event_tlv() - extract dbam complete status event 8739 * @wmi_handle: WMI handle 8740 * @evt_buf: event buffer 8741 * @resp: pointer to coex dbam config response 8742 * 8743 * Return: QDF_STATUS 8744 */ 8745 static QDF_STATUS 8746 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8747 struct coex_dbam_config_resp *resp) 8748 { 8749 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 8750 wmi_coex_dbam_complete_event_fixed_param *event; 8751 8752 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 8753 8754 event = param_buf->fixed_param; 8755 8756 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 8757 8758 return QDF_STATUS_SUCCESS; 8759 } 8760 #endif 8761 8762 #ifdef WLAN_SUPPORT_TWT 8763 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8764 target_resource_config *tgt_res_cfg) 8765 { 8766 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8767 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8768 } 8769 #else 8770 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8771 target_resource_config *tgt_res_cfg) 8772 { 8773 resource_cfg->twt_ap_pdev_count = 0; 8774 resource_cfg->twt_ap_sta_count = 0; 8775 } 8776 #endif 8777 8778 #ifdef WLAN_FEATURE_NAN 8779 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8780 { 8781 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8782 resource_cfg->host_service_flags, 1); 8783 } 8784 #else 8785 static inline 8786 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8787 { 8788 } 8789 #endif 8790 8791 #if defined(CONFIG_AFC_SUPPORT) 8792 static 8793 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8794 target_resource_config *tgt_res_cfg) 8795 { 8796 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8797 resource_cfg->host_service_flags, 8798 tgt_res_cfg->afc_indoor_support); 8799 8800 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8801 resource_cfg->host_service_flags, 8802 tgt_res_cfg->afc_outdoor_support); 8803 } 8804 #else 8805 static 8806 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8807 target_resource_config *tgt_res_cfg) 8808 { 8809 } 8810 #endif 8811 8812 static 8813 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8814 target_resource_config *tgt_res_cfg) 8815 { 8816 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 8817 resource_cfg->num_peers = tgt_res_cfg->num_peers; 8818 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 8819 resource_cfg->num_offload_reorder_buffs = 8820 tgt_res_cfg->num_offload_reorder_buffs; 8821 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 8822 resource_cfg->num_tids = tgt_res_cfg->num_tids; 8823 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 8824 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 8825 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 8826 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 8827 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 8828 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 8829 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 8830 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 8831 resource_cfg->scan_max_pending_req = 8832 tgt_res_cfg->scan_max_pending_req; 8833 resource_cfg->bmiss_offload_max_vdev = 8834 tgt_res_cfg->bmiss_offload_max_vdev; 8835 resource_cfg->roam_offload_max_vdev = 8836 tgt_res_cfg->roam_offload_max_vdev; 8837 resource_cfg->roam_offload_max_ap_profiles = 8838 tgt_res_cfg->roam_offload_max_ap_profiles; 8839 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 8840 resource_cfg->num_mcast_table_elems = 8841 tgt_res_cfg->num_mcast_table_elems; 8842 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 8843 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 8844 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 8845 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 8846 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 8847 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 8848 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 8849 resource_cfg->vow_config = tgt_res_cfg->vow_config; 8850 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 8851 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 8852 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 8853 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 8854 resource_cfg->num_tdls_conn_table_entries = 8855 tgt_res_cfg->num_tdls_conn_table_entries; 8856 resource_cfg->beacon_tx_offload_max_vdev = 8857 tgt_res_cfg->beacon_tx_offload_max_vdev; 8858 resource_cfg->num_multicast_filter_entries = 8859 tgt_res_cfg->num_multicast_filter_entries; 8860 resource_cfg->num_wow_filters = 8861 tgt_res_cfg->num_wow_filters; 8862 resource_cfg->num_keep_alive_pattern = 8863 tgt_res_cfg->num_keep_alive_pattern; 8864 resource_cfg->keep_alive_pattern_size = 8865 tgt_res_cfg->keep_alive_pattern_size; 8866 resource_cfg->max_tdls_concurrent_sleep_sta = 8867 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 8868 resource_cfg->max_tdls_concurrent_buffer_sta = 8869 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 8870 resource_cfg->wmi_send_separate = 8871 tgt_res_cfg->wmi_send_separate; 8872 resource_cfg->num_ocb_vdevs = 8873 tgt_res_cfg->num_ocb_vdevs; 8874 resource_cfg->num_ocb_channels = 8875 tgt_res_cfg->num_ocb_channels; 8876 resource_cfg->num_ocb_schedules = 8877 tgt_res_cfg->num_ocb_schedules; 8878 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 8879 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 8880 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 8881 resource_cfg->max_num_dbs_scan_duty_cycle = 8882 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 8883 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 8884 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 8885 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 8886 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 8887 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 8888 /* Deferred AI: Max rnr neighbors supported in multisoc case 8889 * where in SoC can support 6ghz. During WMI init of a SoC 8890 * currently there is no way to figure if another SOC is plugged in 8891 * and it can support 6Ghz. 8892 */ 8893 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 8894 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 8895 resource_cfg->ema_max_profile_period = 8896 tgt_res_cfg->ema_max_profile_period; 8897 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 8898 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 8899 8900 if (tgt_res_cfg->max_ndp_sessions) 8901 resource_cfg->max_ndp_sessions = 8902 tgt_res_cfg->max_ndp_sessions; 8903 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 8904 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 8905 8906 if (tgt_res_cfg->atf_config) 8907 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 8908 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 8909 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 8910 resource_cfg->flag1, 1); 8911 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 8912 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 8913 resource_cfg->flag1, 1); 8914 if (tgt_res_cfg->cce_disable) 8915 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 8916 if (tgt_res_cfg->enable_pci_gen) 8917 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 8918 resource_cfg->flag1, 1); 8919 if (tgt_res_cfg->eapol_minrate_set) { 8920 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 8921 resource_cfg->flag1, 1); 8922 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 8923 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 8924 resource_cfg->flag1, 1); 8925 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 8926 resource_cfg->flag1, 8927 tgt_res_cfg->eapol_minrate_ac_set); 8928 } 8929 } 8930 if (tgt_res_cfg->new_htt_msg_format) { 8931 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 8932 resource_cfg->flag1, 1); 8933 } 8934 8935 if (tgt_res_cfg->peer_unmap_conf_support) 8936 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 8937 resource_cfg->flag1, 1); 8938 8939 if (tgt_res_cfg->tstamp64_en) 8940 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 8941 resource_cfg->flag1, 1); 8942 8943 if (tgt_res_cfg->three_way_coex_config_legacy_en) 8944 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 8945 resource_cfg->flag1, 1); 8946 if (tgt_res_cfg->pktcapture_support) 8947 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 8948 resource_cfg->flag1, 1); 8949 8950 /* 8951 * Control padding using config param/ini of iphdr_pad_config 8952 */ 8953 if (tgt_res_cfg->iphdr_pad_config) 8954 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 8955 resource_cfg->flag1, 1); 8956 8957 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 8958 tgt_res_cfg->ipa_disable); 8959 8960 if (tgt_res_cfg->time_sync_ftm) 8961 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 8962 1); 8963 8964 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 8965 resource_cfg->peer_map_unmap_versions = 8966 tgt_res_cfg->peer_map_unmap_version; 8967 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 8968 if (tgt_res_cfg->re_ul_resp) 8969 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 8970 tgt_res_cfg->re_ul_resp); 8971 8972 /* 8973 * Enable Service Aware Wifi 8974 */ 8975 if (tgt_res_cfg->sawf) 8976 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 8977 tgt_res_cfg->sawf); 8978 8979 /* 8980 * Enable ast flow override per peer 8981 */ 8982 resource_cfg->msdu_flow_override_config0 = 0; 8983 WMI_MSDU_FLOW_AST_ENABLE_SET( 8984 resource_cfg->msdu_flow_override_config0, 8985 WMI_CONFIG_MSDU_AST_INDEX_1, 8986 tgt_res_cfg->ast_1_valid_mask_enable); 8987 8988 WMI_MSDU_FLOW_AST_ENABLE_SET( 8989 resource_cfg->msdu_flow_override_config0, 8990 WMI_CONFIG_MSDU_AST_INDEX_2, 8991 tgt_res_cfg->ast_2_valid_mask_enable); 8992 8993 WMI_MSDU_FLOW_AST_ENABLE_SET( 8994 resource_cfg->msdu_flow_override_config0, 8995 WMI_CONFIG_MSDU_AST_INDEX_3, 8996 tgt_res_cfg->ast_3_valid_mask_enable); 8997 8998 /* 8999 * Enable ast flow mask and TID valid mask configurations 9000 */ 9001 resource_cfg->msdu_flow_override_config1 = 0; 9002 9003 /*Enable UDP flow for Ast index 0*/ 9004 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9005 resource_cfg->msdu_flow_override_config1, 9006 WMI_CONFIG_MSDU_AST_INDEX_0, 9007 tgt_res_cfg->ast_0_flow_mask_enable); 9008 9009 /*Enable Non UDP flow for Ast index 1*/ 9010 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9011 resource_cfg->msdu_flow_override_config1, 9012 WMI_CONFIG_MSDU_AST_INDEX_1, 9013 tgt_res_cfg->ast_1_flow_mask_enable); 9014 9015 /*Enable Hi-Priority flow for Ast index 2*/ 9016 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9017 resource_cfg->msdu_flow_override_config1, 9018 WMI_CONFIG_MSDU_AST_INDEX_2, 9019 tgt_res_cfg->ast_2_flow_mask_enable); 9020 9021 /*Enable Low-Priority flow for Ast index 3*/ 9022 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9023 resource_cfg->msdu_flow_override_config1, 9024 WMI_CONFIG_MSDU_AST_INDEX_3, 9025 tgt_res_cfg->ast_3_flow_mask_enable); 9026 9027 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9028 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9029 resource_cfg->msdu_flow_override_config1, 9030 tgt_res_cfg->ast_tid_high_mask_enable); 9031 9032 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9033 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9034 resource_cfg->msdu_flow_override_config1, 9035 tgt_res_cfg->ast_tid_low_mask_enable); 9036 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9037 resource_cfg->host_service_flags, 9038 tgt_res_cfg->nan_separate_iface_support); 9039 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9040 resource_cfg->host_service_flags, 1); 9041 9042 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9043 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9044 9045 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9046 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9047 resource_cfg->flags2, 1); 9048 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9049 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9050 resource_cfg->flags2, 1); 9051 9052 if (tgt_res_cfg->sae_eapol_offload) 9053 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9054 resource_cfg->host_service_flags, 1); 9055 9056 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9057 resource_cfg->host_service_flags, 9058 tgt_res_cfg->is_reg_cc_ext_event_supported); 9059 9060 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9061 resource_cfg->host_service_flags, 9062 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9063 9064 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9065 resource_cfg->host_service_flags, 9066 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9067 9068 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9069 resource_cfg->host_service_flags, 9070 tgt_res_cfg->afc_timer_check_disable); 9071 9072 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9073 resource_cfg->host_service_flags, 9074 tgt_res_cfg->afc_req_id_check_disable); 9075 9076 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9077 9078 wmi_set_nan_channel_support(resource_cfg); 9079 9080 if (tgt_res_cfg->twt_ack_support_cap) 9081 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9082 resource_cfg->host_service_flags, 1); 9083 9084 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9085 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9086 resource_cfg->host_service_flags, 1); 9087 9088 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 9089 tgt_res_cfg->target_cap_flags); 9090 if (tgt_res_cfg->notify_frame_support) 9091 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9092 resource_cfg->flags2, 1); 9093 9094 } 9095 9096 #ifdef FEATURE_SET 9097 /** 9098 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9099 * requirement2 version to target vendor1 requirement2 version 9100 * @vendor1_req2_ver: Host vendor1 requirement2 version 9101 * 9102 * Return: Target vendor1 requirement2 version 9103 */ 9104 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9105 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9106 { 9107 switch (vendor1_req2_ver) { 9108 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9109 return WMI_VENDOR1_REQ2_VERSION_3_00; 9110 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9111 return WMI_VENDOR1_REQ2_VERSION_3_01; 9112 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9113 return WMI_VENDOR1_REQ2_VERSION_3_20; 9114 default: 9115 return WMI_VENDOR1_REQ2_VERSION_3_00; 9116 } 9117 } 9118 9119 /** 9120 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9121 * requirement1 version to target vendor1 requirement1 version 9122 * @vendor1_req1_ver: Host vendor1 requirement1 version 9123 * 9124 * Return: Target vendor1 requirement1 version 9125 */ 9126 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9127 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9128 { 9129 switch (vendor1_req1_ver) { 9130 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9131 return WMI_VENDOR1_REQ1_VERSION_3_00; 9132 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9133 return WMI_VENDOR1_REQ1_VERSION_3_01; 9134 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9135 return WMI_VENDOR1_REQ1_VERSION_3_20; 9136 default: 9137 return WMI_VENDOR1_REQ1_VERSION_3_00; 9138 } 9139 } 9140 9141 /** 9142 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9143 * target wifi standard 9144 * @wifi_standard: Host wifi standard 9145 * 9146 * Return: Target wifi standard 9147 */ 9148 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9149 WMI_HOST_WIFI_STANDARD wifi_standard) 9150 { 9151 switch (wifi_standard) { 9152 case WMI_HOST_WIFI_STANDARD_4: 9153 return WMI_WIFI_STANDARD_4; 9154 case WMI_HOST_WIFI_STANDARD_5: 9155 return WMI_WIFI_STANDARD_5; 9156 case WMI_HOST_WIFI_STANDARD_6: 9157 return WMI_WIFI_STANDARD_6; 9158 case WMI_HOST_WIFI_STANDARD_6E: 9159 return WMI_WIFI_STANDARD_6E; 9160 case WMI_HOST_WIFI_STANDARD_7: 9161 return WMI_WIFI_STANDARD_7; 9162 default: 9163 return WMI_WIFI_STANDARD_4; 9164 } 9165 } 9166 9167 /** 9168 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9169 * target band concurrency 9170 * @band_concurrency: Host Band concurrency 9171 * 9172 * Return: Target band concurrency 9173 */ 9174 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9175 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9176 { 9177 switch (band_concurrency) { 9178 case WMI_HOST_BAND_CONCURRENCY_DBS: 9179 return WMI_HOST_DBS; 9180 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9181 return WMI_HOST_DBS_SBS; 9182 default: 9183 return 0; 9184 } 9185 } 9186 9187 /** 9188 * convert_host_to_target_num_antennas() -Convert host num antennas to 9189 * target num antennas 9190 * @num_antennas: Host num antennas 9191 * 9192 * Return: Target num antennas 9193 */ 9194 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9195 WMI_HOST_NUM_ANTENNAS num_antennas) 9196 { 9197 switch (num_antennas) { 9198 case WMI_HOST_SISO: 9199 return WMI_SISO; 9200 case WMI_HOST_MIMO_2X2: 9201 return WMI_MIMO_2X2; 9202 default: 9203 return WMI_SISO; 9204 } 9205 } 9206 9207 /** 9208 * copy_feature_set_info() -Copy feaure set info from host to target 9209 * @feature_set_bitmap: Target feature set pointer 9210 * @feature_set: Host feature set structure 9211 * 9212 * Return: None 9213 */ 9214 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9215 struct target_feature_set *feature_set) 9216 { 9217 WMI_NUM_ANTENNAS num_antennas; 9218 WMI_BAND_CONCURRENCY band_concurrency; 9219 WMI_WIFI_STANDARD wifi_standard; 9220 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9221 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9222 9223 num_antennas = convert_host_to_target_num_antennas( 9224 feature_set->num_antennas); 9225 band_concurrency = convert_host_to_target_band_concurrency( 9226 feature_set->concurrency_support); 9227 wifi_standard = convert_host_to_target_wifi_standard( 9228 feature_set->wifi_standard); 9229 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9230 feature_set->vendor_req_1_version); 9231 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9232 feature_set->vendor_req_2_version); 9233 9234 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9235 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9236 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9237 feature_set->pno_in_unassoc_state); 9238 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9239 feature_set->pno_in_assoc_state); 9240 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9241 feature_set->enable_twt); 9242 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9243 feature_set->enable_twt_requester); 9244 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9245 feature_set->enable_twt_broadcast); 9246 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9247 feature_set->enable_twt_flexible); 9248 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9249 feature_set->enable_wifi_optimizer); 9250 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9251 feature_set->enable_rfc835); 9252 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9253 feature_set->sap_5g_supported); 9254 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9255 feature_set->sap_6g_supported); 9256 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9257 feature_set->sap_max_num_clients); 9258 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9259 feature_set_bitmap, 9260 feature_set->set_country_code_hal_supported); 9261 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9262 feature_set_bitmap, 9263 feature_set->get_valid_channel_supported); 9264 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9265 feature_set->supported_dot11mode); 9266 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9267 feature_set->sap_wpa3_support); 9268 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9269 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9270 feature_set_bitmap, 9271 feature_set->roaming_high_cu_roam_trigger); 9272 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9273 feature_set_bitmap, 9274 feature_set->roaming_emergency_trigger); 9275 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9276 feature_set->roaming_btm_trihgger); 9277 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9278 feature_set->roaming_idle_trigger); 9279 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9280 feature_set->roaming_wtc_trigger); 9281 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9282 feature_set->roaming_btcoex_trigger); 9283 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9284 feature_set->roaming_btw_wpa_wpa2); 9285 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9286 feature_set_bitmap, 9287 feature_set->roaming_manage_chan_list_api); 9288 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9289 feature_set->roaming_adaptive_11r); 9290 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9291 feature_set->roaming_ctrl_api_get_set); 9292 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9293 feature_set->roaming_ctrl_api_reassoc); 9294 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9295 feature_set->roaming_ctrl_get_cu); 9296 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9297 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9298 feature_set_bitmap, 9299 feature_set->assurance_disconnect_reason_api); 9300 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9301 feature_set->frame_pcap_log_mgmt); 9302 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9303 feature_set->frame_pcap_log_ctrl); 9304 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9305 feature_set->frame_pcap_log_data); 9306 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9307 feature_set->security_wpa3_sae_h2e); 9308 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9309 feature_set->security_wpa3_sae_ft); 9310 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9311 feature_set_bitmap, 9312 feature_set->security_wpa3_enterp_suitb); 9313 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9314 feature_set_bitmap, 9315 feature_set->security_wpa3_enterp_suitb_192bit); 9316 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9317 feature_set->security_fills_sha_256); 9318 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9319 feature_set->security_fills_sha_384); 9320 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9321 feature_set->security_fills_sha_256_FT); 9322 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9323 feature_set->security_fills_sha_384_FT); 9324 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9325 feature_set->security_enhanced_open); 9326 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9327 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9328 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9329 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9330 feature_set->enable_tdls_offchannel); 9331 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9332 feature_set->enable_tdls_capability_enhance); 9333 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9334 feature_set->max_tdls_peers); 9335 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9336 feature_set->sta_dual_p2p_support); 9337 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 9338 feature_set_bitmap, 9339 feature_set->peer_bigdata_getbssinfo_support); 9340 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 9341 feature_set_bitmap, 9342 feature_set->peer_bigdata_assocreject_info_support); 9343 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 9344 feature_set_bitmap, 9345 feature_set->peer_getstainfo_support); 9346 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 9347 feature_set->feature_set_version); 9348 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 9349 } 9350 9351 /** 9352 * feature_set_cmd_send_tlv() -Send feature set command 9353 * @wmi_handle: WMI handle 9354 * @feature_set: Feature set structure 9355 * 9356 * Return: QDF_STATUS_SUCCESS on success else reurn failure 9357 */ 9358 static QDF_STATUS feature_set_cmd_send_tlv( 9359 struct wmi_unified *wmi_handle, 9360 struct target_feature_set *feature_set) 9361 { 9362 wmi_pdev_featureset_cmd_fixed_param *cmd; 9363 wmi_buf_t buf; 9364 uint16_t len; 9365 QDF_STATUS ret; 9366 uint8_t *buf_ptr; 9367 uint32_t *feature_set_bitmap; 9368 9369 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9370 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 9371 buf = wmi_buf_alloc(wmi_handle, len); 9372 9373 if (!buf) 9374 return QDF_STATUS_E_NOMEM; 9375 9376 wmi_debug("Send feature set param"); 9377 9378 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9379 9380 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 9381 9382 WMITLV_SET_HDR(&cmd->tlv_header, 9383 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 9384 WMITLV_GET_STRUCT_TLVLEN( 9385 wmi_pdev_featureset_cmd_fixed_param)); 9386 9387 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 9388 WMI_TLV_HDR_SIZE); 9389 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 9390 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 9391 copy_feature_set_info(feature_set_bitmap, feature_set); 9392 9393 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 9394 9395 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9396 WMI_PDEV_FEATURESET_CMDID); 9397 if (QDF_IS_STATUS_ERROR(ret)) 9398 wmi_buf_free(buf); 9399 9400 return ret; 9401 } 9402 #endif 9403 9404 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 9405 * @wmi_handle: pointer to wmi handle 9406 * @buf_ptr: pointer to current position in init command buffer 9407 * @len: pointer to length. This will be updated with current length of cmd 9408 * @param: point host parameters for init command 9409 * 9410 * Return: Updated pointer of buf_ptr. 9411 */ 9412 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 9413 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 9414 { 9415 uint16_t idx; 9416 9417 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 9418 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 9419 wmi_pdev_band_to_mac *band_to_mac; 9420 9421 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 9422 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 9423 sizeof(wmi_resource_config) + 9424 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 9425 sizeof(wlan_host_memory_chunk))); 9426 9427 WMITLV_SET_HDR(&hw_mode->tlv_header, 9428 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 9429 (WMITLV_GET_STRUCT_TLVLEN 9430 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 9431 9432 hw_mode->hw_mode_index = param->hw_mode_id; 9433 hw_mode->num_band_to_mac = param->num_band_to_mac; 9434 9435 buf_ptr = (uint8_t *) (hw_mode + 1); 9436 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 9437 WMI_TLV_HDR_SIZE); 9438 for (idx = 0; idx < param->num_band_to_mac; idx++) { 9439 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 9440 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 9441 WMITLV_GET_STRUCT_TLVLEN 9442 (wmi_pdev_band_to_mac)); 9443 band_to_mac[idx].pdev_id = 9444 wmi_handle->ops->convert_pdev_id_host_to_target( 9445 wmi_handle, 9446 param->band_to_mac[idx].pdev_id); 9447 band_to_mac[idx].start_freq = 9448 param->band_to_mac[idx].start_freq; 9449 band_to_mac[idx].end_freq = 9450 param->band_to_mac[idx].end_freq; 9451 } 9452 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9453 (param->num_band_to_mac * 9454 sizeof(wmi_pdev_band_to_mac)) + 9455 WMI_TLV_HDR_SIZE; 9456 9457 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9458 (param->num_band_to_mac * 9459 sizeof(wmi_pdev_band_to_mac))); 9460 } 9461 9462 return buf_ptr; 9463 } 9464 9465 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 9466 wmi_init_cmd_fixed_param *cmd) 9467 { 9468 int num_allowlist; 9469 wmi_abi_version my_vers; 9470 9471 num_allowlist = sizeof(version_whitelist) / 9472 sizeof(wmi_whitelist_version_info); 9473 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 9474 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 9475 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 9476 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 9477 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 9478 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 9479 9480 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 9481 &my_vers, 9482 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 9483 &cmd->host_abi_vers); 9484 9485 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 9486 __func__, 9487 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 9488 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 9489 cmd->host_abi_vers.abi_version_ns_0, 9490 cmd->host_abi_vers.abi_version_ns_1, 9491 cmd->host_abi_vers.abi_version_ns_2, 9492 cmd->host_abi_vers.abi_version_ns_3); 9493 9494 /* Save version sent from host - 9495 * Will be used to check ready event 9496 */ 9497 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 9498 sizeof(wmi_abi_version)); 9499 } 9500 9501 /* 9502 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 9503 * @wmi_handle: Pointer to WMi handle 9504 * @ie_data: Pointer for ie data 9505 * 9506 * This function sends action frame tb ppdu cfg to FW 9507 * 9508 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9509 * 9510 */ 9511 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 9512 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 9513 { 9514 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 9515 wmi_buf_t buf; 9516 uint8_t *buf_ptr; 9517 uint32_t len, frm_len_aligned; 9518 QDF_STATUS ret; 9519 9520 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 9521 /* Allocate memory for the WMI command */ 9522 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 9523 9524 buf = wmi_buf_alloc(wmi_handle, len); 9525 if (!buf) 9526 return QDF_STATUS_E_NOMEM; 9527 9528 buf_ptr = wmi_buf_data(buf); 9529 qdf_mem_zero(buf_ptr, len); 9530 9531 /* Populate the WMI command */ 9532 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 9533 9534 WMITLV_SET_HDR(&cmd->tlv_header, 9535 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 9536 WMITLV_GET_STRUCT_TLVLEN( 9537 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 9538 cmd->enable = cfg_msg->cfg; 9539 cmd->data_len = cfg_msg->frm_len; 9540 9541 buf_ptr += sizeof(*cmd); 9542 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 9543 buf_ptr += WMI_TLV_HDR_SIZE; 9544 9545 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 9546 9547 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9548 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 9549 if (QDF_IS_STATUS_ERROR(ret)) { 9550 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 9551 wmi_buf_free(buf); 9552 } 9553 9554 return ret; 9555 } 9556 9557 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9558 { 9559 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9560 wmi_service_ready_event_fixed_param *ev; 9561 9562 9563 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9564 9565 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9566 if (!ev) 9567 return QDF_STATUS_E_FAILURE; 9568 9569 /*Save fw version from service ready message */ 9570 /*This will be used while sending INIT message */ 9571 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9572 sizeof(wmi_handle->fw_abi_version)); 9573 9574 return QDF_STATUS_SUCCESS; 9575 } 9576 9577 /** 9578 * wmi_unified_save_fw_version_cmd() - save fw version 9579 * @wmi_handle: pointer to wmi handle 9580 * @res_cfg: resource config 9581 * @num_mem_chunks: no of mem chunck 9582 * @mem_chunk: pointer to mem chunck structure 9583 * 9584 * This function sends IE information to firmware 9585 * 9586 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9587 * 9588 */ 9589 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 9590 void *evt_buf) 9591 { 9592 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9593 wmi_ready_event_fixed_param *ev = NULL; 9594 9595 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9596 ev = param_buf->fixed_param; 9597 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 9598 &wmi_handle->final_abi_vers, 9599 &ev->fw_abi_vers)) { 9600 /* 9601 * Error: Our host version and the given firmware version 9602 * are incompatible. 9603 **/ 9604 wmi_debug("Error: Incompatible WMI version." 9605 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 9606 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 9607 abi_version_0), 9608 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 9609 abi_version_0), 9610 wmi_handle->final_abi_vers.abi_version_ns_0, 9611 wmi_handle->final_abi_vers.abi_version_ns_1, 9612 wmi_handle->final_abi_vers.abi_version_ns_2, 9613 wmi_handle->final_abi_vers.abi_version_ns_3, 9614 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 9615 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 9616 ev->fw_abi_vers.abi_version_ns_0, 9617 ev->fw_abi_vers.abi_version_ns_1, 9618 ev->fw_abi_vers.abi_version_ns_2, 9619 ev->fw_abi_vers.abi_version_ns_3); 9620 9621 return QDF_STATUS_E_FAILURE; 9622 } 9623 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 9624 sizeof(wmi_abi_version)); 9625 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9626 sizeof(wmi_abi_version)); 9627 9628 return QDF_STATUS_SUCCESS; 9629 } 9630 9631 /** 9632 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 9633 * @handle: wmi handle 9634 * @event: Event received from FW 9635 * @len: Length of the event 9636 * 9637 * Enables the low frequency events and disables the high frequency 9638 * events. Bit 17 indicates if the event if low/high frequency. 9639 * 1 - high frequency, 0 - low frequency 9640 * 9641 * Return: 0 on successfully enabling/disabling the events 9642 */ 9643 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 9644 uint8_t *event, 9645 uint32_t len) 9646 { 9647 uint32_t num_of_diag_events_logs; 9648 wmi_diag_event_log_config_fixed_param *cmd; 9649 wmi_buf_t buf; 9650 uint8_t *buf_ptr; 9651 uint32_t *cmd_args, *evt_args; 9652 uint32_t buf_len, i; 9653 9654 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 9655 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 9656 9657 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 9658 9659 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 9660 if (!param_buf) { 9661 wmi_err("Invalid log supported event buffer"); 9662 return QDF_STATUS_E_INVAL; 9663 } 9664 wmi_event = param_buf->fixed_param; 9665 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 9666 9667 if (num_of_diag_events_logs > 9668 param_buf->num_diag_events_logs_list) { 9669 wmi_err("message number of events %d is more than tlv hdr content %d", 9670 num_of_diag_events_logs, 9671 param_buf->num_diag_events_logs_list); 9672 return QDF_STATUS_E_INVAL; 9673 } 9674 9675 evt_args = param_buf->diag_events_logs_list; 9676 if (!evt_args) { 9677 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 9678 num_of_diag_events_logs); 9679 return QDF_STATUS_E_INVAL; 9680 } 9681 9682 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 9683 9684 /* Free any previous allocation */ 9685 if (wmi_handle->events_logs_list) { 9686 qdf_mem_free(wmi_handle->events_logs_list); 9687 wmi_handle->events_logs_list = NULL; 9688 } 9689 9690 if (num_of_diag_events_logs > 9691 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 9692 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 9693 QDF_ASSERT(0); 9694 return QDF_STATUS_E_INVAL; 9695 } 9696 /* Store the event list for run time enable/disable */ 9697 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 9698 sizeof(uint32_t)); 9699 if (!wmi_handle->events_logs_list) 9700 return QDF_STATUS_E_NOMEM; 9701 9702 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 9703 9704 /* Prepare the send buffer */ 9705 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9706 (num_of_diag_events_logs * sizeof(uint32_t)); 9707 9708 buf = wmi_buf_alloc(wmi_handle, buf_len); 9709 if (!buf) { 9710 qdf_mem_free(wmi_handle->events_logs_list); 9711 wmi_handle->events_logs_list = NULL; 9712 return QDF_STATUS_E_NOMEM; 9713 } 9714 9715 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9716 buf_ptr = (uint8_t *) cmd; 9717 9718 WMITLV_SET_HDR(&cmd->tlv_header, 9719 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9720 WMITLV_GET_STRUCT_TLVLEN( 9721 wmi_diag_event_log_config_fixed_param)); 9722 9723 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 9724 9725 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9726 9727 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9728 (num_of_diag_events_logs * sizeof(uint32_t))); 9729 9730 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9731 9732 /* Populate the events */ 9733 for (i = 0; i < num_of_diag_events_logs; i++) { 9734 /* Low freq (0) - Enable (1) the event 9735 * High freq (1) - Disable (0) the event 9736 */ 9737 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 9738 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 9739 /* Set the event ID */ 9740 WMI_DIAG_ID_SET(cmd_args[i], 9741 WMI_DIAG_ID_GET(evt_args[i])); 9742 /* Set the type */ 9743 WMI_DIAG_TYPE_SET(cmd_args[i], 9744 WMI_DIAG_TYPE_GET(evt_args[i])); 9745 /* Storing the event/log list in WMI */ 9746 wmi_handle->events_logs_list[i] = evt_args[i]; 9747 } 9748 9749 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9750 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 9751 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9752 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9753 wmi_buf_free(buf); 9754 /* Not clearing events_logs_list, though wmi cmd failed. 9755 * Host can still have this list 9756 */ 9757 return QDF_STATUS_E_INVAL; 9758 } 9759 9760 return 0; 9761 } 9762 9763 /** 9764 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 9765 * @wmi_handle: wmi handle 9766 * @start_log: Start logging related parameters 9767 * 9768 * Send the command to the FW based on which specific logging of diag 9769 * event/log id can be started/stopped 9770 * 9771 * Return: None 9772 */ 9773 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 9774 struct wmi_wifi_start_log *start_log) 9775 { 9776 wmi_diag_event_log_config_fixed_param *cmd; 9777 wmi_buf_t buf; 9778 uint8_t *buf_ptr; 9779 uint32_t len, count, log_level, i; 9780 uint32_t *cmd_args; 9781 uint32_t total_len; 9782 count = 0; 9783 9784 if (!wmi_handle->events_logs_list) { 9785 wmi_debug("Not received event/log list from FW, yet"); 9786 return QDF_STATUS_E_NOMEM; 9787 } 9788 /* total_len stores the number of events where BITS 17 and 18 are set. 9789 * i.e., events of high frequency (17) and for extended debugging (18) 9790 */ 9791 total_len = 0; 9792 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 9793 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 9794 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 9795 total_len++; 9796 } 9797 9798 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9799 (total_len * sizeof(uint32_t)); 9800 9801 buf = wmi_buf_alloc(wmi_handle, len); 9802 if (!buf) 9803 return QDF_STATUS_E_NOMEM; 9804 9805 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9806 buf_ptr = (uint8_t *) cmd; 9807 9808 WMITLV_SET_HDR(&cmd->tlv_header, 9809 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9810 WMITLV_GET_STRUCT_TLVLEN( 9811 wmi_diag_event_log_config_fixed_param)); 9812 9813 cmd->num_of_diag_events_logs = total_len; 9814 9815 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9816 9817 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9818 (total_len * sizeof(uint32_t))); 9819 9820 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9821 9822 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 9823 log_level = 1; 9824 else 9825 log_level = 0; 9826 9827 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 9828 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 9829 uint32_t val = wmi_handle->events_logs_list[i]; 9830 if ((WMI_DIAG_FREQUENCY_GET(val)) && 9831 (WMI_DIAG_EXT_FEATURE_GET(val))) { 9832 9833 WMI_DIAG_ID_SET(cmd_args[count], 9834 WMI_DIAG_ID_GET(val)); 9835 WMI_DIAG_TYPE_SET(cmd_args[count], 9836 WMI_DIAG_TYPE_GET(val)); 9837 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 9838 log_level); 9839 wmi_debug("Idx:%d, val:%x", i, val); 9840 count++; 9841 } 9842 } 9843 9844 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9845 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9846 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9847 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9848 wmi_buf_free(buf); 9849 return QDF_STATUS_E_INVAL; 9850 } 9851 9852 return QDF_STATUS_SUCCESS; 9853 } 9854 9855 /** 9856 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 9857 * @wmi_handle: WMI handle 9858 * 9859 * This function is used to send the flush command to the FW, 9860 * that will flush the fw logs that are residue in the FW 9861 * 9862 * Return: None 9863 */ 9864 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9865 { 9866 wmi_debug_mesg_flush_fixed_param *cmd; 9867 wmi_buf_t buf; 9868 int len = sizeof(*cmd); 9869 QDF_STATUS ret; 9870 9871 buf = wmi_buf_alloc(wmi_handle, len); 9872 if (!buf) 9873 return QDF_STATUS_E_NOMEM; 9874 9875 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 9876 WMITLV_SET_HDR(&cmd->tlv_header, 9877 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 9878 WMITLV_GET_STRUCT_TLVLEN( 9879 wmi_debug_mesg_flush_fixed_param)); 9880 cmd->reserved0 = 0; 9881 9882 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 9883 ret = wmi_unified_cmd_send(wmi_handle, 9884 buf, 9885 len, 9886 WMI_DEBUG_MESG_FLUSH_CMDID); 9887 if (QDF_IS_STATUS_ERROR(ret)) { 9888 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 9889 wmi_buf_free(buf); 9890 return QDF_STATUS_E_INVAL; 9891 } 9892 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 9893 9894 return ret; 9895 } 9896 9897 #ifdef BIG_ENDIAN_HOST 9898 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9899 /** 9900 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 9901 * @param - fips extend param related parameters 9902 * 9903 * Return: QDF_STATUS - success or error status 9904 */ 9905 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 9906 struct fips_extend_params *param) 9907 { 9908 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 9909 int c; 9910 u_int8_t *key_aligned = NULL; 9911 u_int8_t *nonce_iv_aligned = NULL; 9912 u_int8_t *data_aligned = NULL; 9913 int ret = QDF_STATUS_SUCCESS; 9914 9915 /* Assigning unaligned space to copy the key */ 9916 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9917 param->cmd_params.key_len + FIPS_ALIGN); 9918 /* Checking if kmalloc is successful to allocate space */ 9919 if (!key_unaligned) 9920 return QDF_STATUS_E_INVAL; 9921 9922 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 9923 FIPS_ALIGN); 9924 /* Checking if kmalloc is successful to allocate space */ 9925 if (!data_unaligned) { 9926 ret = QDF_STATUS_E_INVAL; 9927 goto fips_align_fail_data; 9928 } 9929 9930 /* Checking if space is aligned */ 9931 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9932 /* align to 4 */ 9933 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 9934 FIPS_ALIGN); 9935 } else { 9936 key_aligned = (u_int8_t *)key_unaligned; 9937 } 9938 9939 /* memset and copy content from key to key aligned */ 9940 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 9941 OS_MEMCPY(key_aligned, param->cmd_params.key, 9942 param->cmd_params.key_len); 9943 9944 /* print a hexdump for host debug */ 9945 wmi_debug("Aligned and Copied Key: "); 9946 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9947 key_aligned, param->cmd_params.key_len); 9948 9949 /* Checking of space is aligned */ 9950 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9951 /* align to 4 */ 9952 data_aligned = 9953 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 9954 } else { 9955 data_aligned = (u_int8_t *)data_unaligned; 9956 } 9957 9958 /* memset and copy content from data to data aligned */ 9959 OS_MEMSET(data_aligned, 0, param->data_len); 9960 OS_MEMCPY(data_aligned, param->data, param->data_len); 9961 9962 /* print a hexdump for host debug */ 9963 wmi_debug("\t Properly Aligned and Copied Data: "); 9964 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9965 data_aligned, param->data_len); 9966 9967 /* converting to little Endian */ 9968 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 9969 *((u_int32_t *)key_aligned + c) = 9970 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 9971 } 9972 for (c = 0; c < param->data_len / 4; c++) { 9973 *((u_int32_t *)data_aligned + c) = 9974 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 9975 } 9976 9977 /* update endian data */ 9978 OS_MEMCPY(param->cmd_params.key, key_aligned, 9979 param->cmd_params.key_len); 9980 OS_MEMCPY(param->data, data_aligned, param->data_len); 9981 9982 if (param->cmd_params.nonce_iv_len) { 9983 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9984 param->cmd_params.nonce_iv_len + 9985 FIPS_ALIGN); 9986 9987 /* Checking if kmalloc is successful to allocate space */ 9988 if (!nonce_iv_unaligned) { 9989 ret = QDF_STATUS_E_INVAL; 9990 goto fips_align_fail_nonce_iv; 9991 } 9992 /* Checking if space is aligned */ 9993 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 9994 /* align to 4 */ 9995 nonce_iv_aligned = 9996 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 9997 FIPS_ALIGN); 9998 } else { 9999 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10000 } 10001 10002 /* memset and copy content from iv to iv aligned */ 10003 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10004 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10005 param->cmd_params.nonce_iv_len); 10006 10007 /* print a hexdump for host debug */ 10008 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10009 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10010 nonce_iv_aligned, 10011 param->cmd_params.nonce_iv_len); 10012 10013 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10014 *((u_int32_t *)nonce_iv_aligned + c) = 10015 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10016 } 10017 } 10018 10019 /* clean up allocated spaces */ 10020 qdf_mem_free(nonce_iv_unaligned); 10021 nonce_iv_unaligned = NULL; 10022 nonce_iv_aligned = NULL; 10023 10024 fips_align_fail_nonce_iv: 10025 qdf_mem_free(data_unaligned); 10026 data_unaligned = NULL; 10027 data_aligned = NULL; 10028 10029 fips_align_fail_data: 10030 qdf_mem_free(key_unaligned); 10031 key_unaligned = NULL; 10032 key_aligned = NULL; 10033 10034 return ret; 10035 } 10036 #endif 10037 10038 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10039 struct fips_params *param) 10040 { 10041 unsigned char *key_unaligned, *data_unaligned; 10042 int c; 10043 u_int8_t *key_aligned = NULL; 10044 u_int8_t *data_aligned = NULL; 10045 10046 /* Assigning unaligned space to copy the key */ 10047 key_unaligned = qdf_mem_malloc( 10048 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10049 data_unaligned = qdf_mem_malloc( 10050 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10051 10052 /* Checking if kmalloc is successful to allocate space */ 10053 if (!key_unaligned) 10054 return QDF_STATUS_SUCCESS; 10055 /* Checking if space is aligned */ 10056 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10057 /* align to 4 */ 10058 key_aligned = 10059 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10060 FIPS_ALIGN); 10061 } else { 10062 key_aligned = (u_int8_t *)key_unaligned; 10063 } 10064 10065 /* memset and copy content from key to key aligned */ 10066 OS_MEMSET(key_aligned, 0, param->key_len); 10067 OS_MEMCPY(key_aligned, param->key, param->key_len); 10068 10069 /* print a hexdump for host debug */ 10070 print_hex_dump(KERN_DEBUG, 10071 "\t Aligned and Copied Key:@@@@ ", 10072 DUMP_PREFIX_NONE, 10073 16, 1, key_aligned, param->key_len, true); 10074 10075 /* Checking if kmalloc is successful to allocate space */ 10076 if (!data_unaligned) 10077 return QDF_STATUS_SUCCESS; 10078 /* Checking of space is aligned */ 10079 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10080 /* align to 4 */ 10081 data_aligned = 10082 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10083 FIPS_ALIGN); 10084 } else { 10085 data_aligned = (u_int8_t *)data_unaligned; 10086 } 10087 10088 /* memset and copy content from data to data aligned */ 10089 OS_MEMSET(data_aligned, 0, param->data_len); 10090 OS_MEMCPY(data_aligned, param->data, param->data_len); 10091 10092 /* print a hexdump for host debug */ 10093 print_hex_dump(KERN_DEBUG, 10094 "\t Properly Aligned and Copied Data:@@@@ ", 10095 DUMP_PREFIX_NONE, 10096 16, 1, data_aligned, param->data_len, true); 10097 10098 /* converting to little Endian both key_aligned and 10099 * data_aligned*/ 10100 for (c = 0; c < param->key_len/4; c++) { 10101 *((u_int32_t *)key_aligned+c) = 10102 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10103 } 10104 for (c = 0; c < param->data_len/4; c++) { 10105 *((u_int32_t *)data_aligned+c) = 10106 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10107 } 10108 10109 /* update endian data to key and data vectors */ 10110 OS_MEMCPY(param->key, key_aligned, param->key_len); 10111 OS_MEMCPY(param->data, data_aligned, param->data_len); 10112 10113 /* clean up allocated spaces */ 10114 qdf_mem_free(key_unaligned); 10115 key_unaligned = NULL; 10116 key_aligned = NULL; 10117 10118 qdf_mem_free(data_unaligned); 10119 data_unaligned = NULL; 10120 data_aligned = NULL; 10121 10122 return QDF_STATUS_SUCCESS; 10123 } 10124 #else 10125 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10126 /** 10127 * fips_extend_align_data_be() - DUMMY for LE platform 10128 * 10129 * Return: QDF_STATUS - success 10130 */ 10131 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10132 struct fips_extend_params *param) 10133 { 10134 return QDF_STATUS_SUCCESS; 10135 } 10136 #endif 10137 10138 /** 10139 * fips_align_data_be() - DUMMY for LE platform 10140 * 10141 * Return: QDF_STATUS - success 10142 */ 10143 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10144 struct fips_params *param) 10145 { 10146 return QDF_STATUS_SUCCESS; 10147 } 10148 #endif 10149 10150 #ifdef WLAN_FEATURE_DISA 10151 /** 10152 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 10153 * @wmi_handle: wmi handle 10154 * @params: encrypt/decrypt params 10155 * 10156 * Return: QDF_STATUS_SUCCESS for success or error code 10157 */ 10158 static QDF_STATUS 10159 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10160 struct disa_encrypt_decrypt_req_params 10161 *encrypt_decrypt_params) 10162 { 10163 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10164 wmi_buf_t wmi_buf; 10165 uint8_t *buf_ptr; 10166 QDF_STATUS ret; 10167 uint32_t len; 10168 10169 wmi_debug("Send encrypt decrypt cmd"); 10170 10171 len = sizeof(*cmd) + 10172 encrypt_decrypt_params->data_len + 10173 WMI_TLV_HDR_SIZE; 10174 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10175 if (!wmi_buf) 10176 return QDF_STATUS_E_NOMEM; 10177 10178 buf_ptr = wmi_buf_data(wmi_buf); 10179 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10180 10181 WMITLV_SET_HDR(&cmd->tlv_header, 10182 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10183 WMITLV_GET_STRUCT_TLVLEN( 10184 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10185 10186 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10187 cmd->key_flag = encrypt_decrypt_params->key_flag; 10188 cmd->key_idx = encrypt_decrypt_params->key_idx; 10189 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10190 cmd->key_len = encrypt_decrypt_params->key_len; 10191 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10192 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10193 10194 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10195 encrypt_decrypt_params->key_len); 10196 10197 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10198 MAX_MAC_HEADER_LEN); 10199 10200 cmd->data_len = encrypt_decrypt_params->data_len; 10201 10202 if (cmd->data_len) { 10203 buf_ptr += sizeof(*cmd); 10204 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10205 roundup(encrypt_decrypt_params->data_len, 10206 sizeof(uint32_t))); 10207 buf_ptr += WMI_TLV_HDR_SIZE; 10208 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10209 encrypt_decrypt_params->data_len); 10210 } 10211 10212 /* This conversion is to facilitate data to FW in little endian */ 10213 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10214 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10215 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10216 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10217 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10218 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10219 10220 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10221 ret = wmi_unified_cmd_send(wmi_handle, 10222 wmi_buf, len, 10223 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10224 if (QDF_IS_STATUS_ERROR(ret)) { 10225 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10226 wmi_buf_free(wmi_buf); 10227 } 10228 10229 return ret; 10230 } 10231 #endif /* WLAN_FEATURE_DISA */ 10232 10233 /** 10234 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10235 * @wmi_handle: wmi handle 10236 * @param: pointer to hold pdev fips param 10237 * 10238 * Return: 0 for success or error code 10239 */ 10240 static QDF_STATUS 10241 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10242 struct fips_params *param) 10243 { 10244 wmi_pdev_fips_cmd_fixed_param *cmd; 10245 wmi_buf_t buf; 10246 uint8_t *buf_ptr; 10247 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10248 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10249 10250 /* Length TLV placeholder for array of bytes */ 10251 len += WMI_TLV_HDR_SIZE; 10252 if (param->data_len) 10253 len += (param->data_len*sizeof(uint8_t)); 10254 10255 /* 10256 * Data length must be multiples of 16 bytes - checked against 0xF - 10257 * and must be less than WMI_SVC_MSG_SIZE - static size of 10258 * wmi_pdev_fips_cmd structure 10259 */ 10260 10261 /* do sanity on the input */ 10262 if (!(((param->data_len & 0xF) == 0) && 10263 ((param->data_len > 0) && 10264 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10265 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10266 return QDF_STATUS_E_INVAL; 10267 } 10268 10269 buf = wmi_buf_alloc(wmi_handle, len); 10270 if (!buf) 10271 return QDF_STATUS_E_FAILURE; 10272 10273 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10274 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10275 WMITLV_SET_HDR(&cmd->tlv_header, 10276 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10277 WMITLV_GET_STRUCT_TLVLEN 10278 (wmi_pdev_fips_cmd_fixed_param)); 10279 10280 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10281 wmi_handle, 10282 param->pdev_id); 10283 if (param->key && param->data) { 10284 cmd->key_len = param->key_len; 10285 cmd->data_len = param->data_len; 10286 cmd->fips_cmd = !!(param->op); 10287 10288 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10289 return QDF_STATUS_E_FAILURE; 10290 10291 qdf_mem_copy(cmd->key, param->key, param->key_len); 10292 10293 if (param->mode == FIPS_ENGINE_AES_CTR || 10294 param->mode == FIPS_ENGINE_AES_MIC) { 10295 cmd->mode = param->mode; 10296 } else { 10297 cmd->mode = FIPS_ENGINE_AES_CTR; 10298 } 10299 qdf_print("Key len = %d, Data len = %d", 10300 cmd->key_len, cmd->data_len); 10301 10302 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10303 cmd->key, cmd->key_len, true); 10304 buf_ptr += sizeof(*cmd); 10305 10306 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10307 10308 buf_ptr += WMI_TLV_HDR_SIZE; 10309 if (param->data_len) 10310 qdf_mem_copy(buf_ptr, 10311 (uint8_t *) param->data, param->data_len); 10312 10313 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10314 16, 1, buf_ptr, cmd->data_len, true); 10315 10316 buf_ptr += param->data_len; 10317 10318 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10319 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10320 WMI_PDEV_FIPS_CMDID); 10321 qdf_print("%s return value %d", __func__, retval); 10322 } else { 10323 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10324 wmi_buf_free(buf); 10325 retval = -QDF_STATUS_E_BADMSG; 10326 } 10327 10328 return retval; 10329 } 10330 10331 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10332 /** 10333 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10334 * @wmi_handle: wmi handle 10335 * @param: pointer to hold pdev fips param 10336 * 10337 * Return: 0 for success or error code 10338 */ 10339 static QDF_STATUS 10340 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 10341 struct fips_extend_params *param) 10342 { 10343 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 10344 wmi_buf_t buf; 10345 uint8_t *buf_ptr; 10346 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 10347 uint32_t data_len_aligned; 10348 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10349 10350 len += WMI_TLV_HDR_SIZE; 10351 if (param->frag_idx == 0) 10352 len += sizeof(wmi_fips_extend_cmd_init_params); 10353 10354 /* Length TLV placeholder for array of bytes */ 10355 len += WMI_TLV_HDR_SIZE; 10356 if (param->data_len) { 10357 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 10358 len += (data_len_aligned * sizeof(uint8_t)); 10359 } 10360 10361 buf = wmi_buf_alloc(wmi_handle, len); 10362 if (!buf) 10363 return QDF_STATUS_E_FAILURE; 10364 10365 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10366 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 10367 WMITLV_SET_HDR(&cmd->tlv_header, 10368 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 10369 WMITLV_GET_STRUCT_TLVLEN 10370 (wmi_pdev_fips_extend_cmd_fixed_param)); 10371 10372 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10373 wmi_handle, 10374 param->pdev_id); 10375 10376 cmd->fips_cookie = param->cookie; 10377 cmd->frag_idx = param->frag_idx; 10378 cmd->more_bit = param->more_bit; 10379 cmd->data_len = param->data_len; 10380 10381 if (fips_extend_align_data_be(wmi_handle, param) != 10382 QDF_STATUS_SUCCESS) { 10383 wmi_buf_free(buf); 10384 return QDF_STATUS_E_FAILURE; 10385 } 10386 10387 buf_ptr = (uint8_t *)(cmd + 1); 10388 if (cmd->frag_idx == 0) { 10389 wmi_fips_extend_cmd_init_params *cmd_params; 10390 10391 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10392 sizeof(wmi_fips_extend_cmd_init_params)); 10393 buf_ptr += WMI_TLV_HDR_SIZE; 10394 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 10395 WMITLV_SET_HDR(buf_ptr, 10396 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 10397 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 10398 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 10399 cmd_params->key_cipher = param->cmd_params.key_cipher; 10400 cmd_params->key_len = param->cmd_params.key_len; 10401 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 10402 cmd_params->tag_len = param->cmd_params.tag_len; 10403 cmd_params->aad_len = param->cmd_params.aad_len; 10404 cmd_params->payload_len = param->cmd_params.payload_len; 10405 10406 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 10407 param->cmd_params.key_len); 10408 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 10409 param->cmd_params.nonce_iv_len); 10410 10411 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 10412 cmd_params->key_len, cmd_params->nonce_iv_len, 10413 cmd_params->tag_len, cmd_params->aad_len, 10414 cmd_params->payload_len); 10415 10416 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 10417 } else { 10418 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10419 buf_ptr += WMI_TLV_HDR_SIZE; 10420 } 10421 10422 if (param->data_len && param->data) { 10423 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10424 data_len_aligned); 10425 10426 buf_ptr += WMI_TLV_HDR_SIZE; 10427 if (param->data_len) 10428 qdf_mem_copy(buf_ptr, 10429 (uint8_t *)param->data, param->data_len); 10430 10431 wmi_debug("Data: "); 10432 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10433 buf_ptr, cmd->data_len); 10434 10435 if (param->data_len) 10436 buf_ptr += param->data_len; 10437 } else { 10438 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 10439 buf_ptr += WMI_TLV_HDR_SIZE; 10440 } 10441 10442 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 10443 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10444 WMI_PDEV_FIPS_EXTEND_CMDID); 10445 10446 if (retval) { 10447 wmi_err("Failed to send FIPS cmd"); 10448 wmi_buf_free(buf); 10449 } 10450 10451 return retval; 10452 } 10453 10454 /** 10455 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 10456 * @wmi_handle: wmi handle 10457 * @param: pointer to hold pdev fips param 10458 * 10459 * Return: 0 for success or error code 10460 */ 10461 static QDF_STATUS 10462 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 10463 struct fips_mode_set_params *param) 10464 { 10465 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 10466 wmi_buf_t buf; 10467 uint8_t *buf_ptr; 10468 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 10469 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10470 10471 buf = wmi_buf_alloc(wmi_handle, len); 10472 if (!buf) 10473 return QDF_STATUS_E_FAILURE; 10474 10475 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10476 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 10477 WMITLV_SET_HDR(&cmd->tlv_header, 10478 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 10479 WMITLV_GET_STRUCT_TLVLEN 10480 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 10481 10482 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10483 wmi_handle, 10484 param->pdev_id); 10485 10486 cmd->fips_mode_set = param->mode; 10487 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 10488 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10489 WMI_PDEV_FIPS_MODE_SET_CMDID); 10490 if (retval) { 10491 wmi_err("Failed to send FIPS mode enable cmd"); 10492 wmi_buf_free(buf); 10493 } 10494 return retval; 10495 } 10496 #endif 10497 10498 /** 10499 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 10500 * to fw 10501 * @wmi_handle: wmi handle 10502 * @param: pointer to wlan profile param 10503 * 10504 * Return: 0 for success or error code 10505 */ 10506 static QDF_STATUS 10507 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 10508 struct wlan_profile_params *param) 10509 { 10510 wmi_buf_t buf; 10511 uint16_t len; 10512 QDF_STATUS ret; 10513 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 10514 10515 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 10516 buf = wmi_buf_alloc(wmi_handle, len); 10517 if (!buf) { 10518 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 10519 return QDF_STATUS_E_NOMEM; 10520 } 10521 10522 profile_enable_cmd = 10523 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 10524 wmi_buf_data(buf); 10525 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 10526 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 10527 WMITLV_GET_STRUCT_TLVLEN 10528 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 10529 10530 profile_enable_cmd->profile_id = param->profile_id; 10531 profile_enable_cmd->enable = param->enable; 10532 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 10533 NO_SESSION, 0); 10534 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10535 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 10536 if (ret) { 10537 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 10538 wmi_buf_free(buf); 10539 } 10540 return ret; 10541 } 10542 10543 /** 10544 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 10545 * to fw 10546 * @wmi_handle: wmi handle 10547 * @param: pointer to wlan profile param 10548 * 10549 * Return: 0 for success or error code 10550 */ 10551 static QDF_STATUS 10552 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 10553 struct wlan_profile_params *param) 10554 { 10555 wmi_buf_t buf; 10556 uint16_t len; 10557 QDF_STATUS ret; 10558 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 10559 10560 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 10561 buf = wmi_buf_alloc(wmi_handle, len); 10562 if (!buf) { 10563 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10564 return QDF_STATUS_E_NOMEM; 10565 } 10566 10567 prof_trig_cmd = 10568 (wmi_wlan_profile_trigger_cmd_fixed_param *) 10569 wmi_buf_data(buf); 10570 10571 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 10572 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 10573 WMITLV_GET_STRUCT_TLVLEN 10574 (wmi_wlan_profile_trigger_cmd_fixed_param)); 10575 10576 prof_trig_cmd->enable = param->enable; 10577 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 10578 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10579 WMI_WLAN_PROFILE_TRIGGER_CMDID); 10580 if (ret) { 10581 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10582 wmi_buf_free(buf); 10583 } 10584 return ret; 10585 } 10586 10587 /** 10588 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 10589 * to fw 10590 * @wmi_handle: wmi handle 10591 * @param: pointer to wlan profile param 10592 * 10593 * Return: 0 for success or error code 10594 */ 10595 static QDF_STATUS 10596 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 10597 struct wlan_profile_params *param) 10598 { 10599 wmi_buf_t buf; 10600 int32_t len = 0; 10601 QDF_STATUS ret; 10602 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 10603 10604 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 10605 buf = wmi_buf_alloc(wmi_handle, len); 10606 if (!buf) { 10607 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 10608 return QDF_STATUS_E_NOMEM; 10609 } 10610 10611 hist_intvl_cmd = 10612 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 10613 wmi_buf_data(buf); 10614 10615 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 10616 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 10617 WMITLV_GET_STRUCT_TLVLEN 10618 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 10619 10620 hist_intvl_cmd->profile_id = param->profile_id; 10621 hist_intvl_cmd->value = param->enable; 10622 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 10623 NO_SESSION, 0); 10624 10625 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10626 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 10627 if (ret) { 10628 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 10629 wmi_buf_free(buf); 10630 } 10631 return ret; 10632 } 10633 10634 /** 10635 * send_fw_test_cmd_tlv() - send fw test command to fw. 10636 * @wmi_handle: wmi handle 10637 * @wmi_fwtest: fw test command 10638 * 10639 * This function sends fw test command to fw. 10640 * 10641 * Return: CDF STATUS 10642 */ 10643 static 10644 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 10645 struct set_fwtest_params *wmi_fwtest) 10646 { 10647 wmi_fwtest_set_param_cmd_fixed_param *cmd; 10648 wmi_buf_t wmi_buf; 10649 uint16_t len; 10650 10651 len = sizeof(*cmd); 10652 10653 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10654 if (!wmi_buf) 10655 return QDF_STATUS_E_NOMEM; 10656 10657 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10658 WMITLV_SET_HDR(&cmd->tlv_header, 10659 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 10660 WMITLV_GET_STRUCT_TLVLEN( 10661 wmi_fwtest_set_param_cmd_fixed_param)); 10662 cmd->param_id = wmi_fwtest->arg; 10663 cmd->param_value = wmi_fwtest->value; 10664 10665 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 10666 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10667 WMI_FWTEST_CMDID)) { 10668 wmi_err("Failed to send fw test command"); 10669 wmi_buf_free(wmi_buf); 10670 return QDF_STATUS_E_FAILURE; 10671 } 10672 10673 return QDF_STATUS_SUCCESS; 10674 } 10675 10676 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 10677 { 10678 uint16_t len = 0; 10679 10680 if (config == WFA_CONFIG_RXNE) 10681 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 10682 else 10683 len += WMI_TLV_HDR_SIZE; 10684 10685 if (config == WFA_CONFIG_CSA) 10686 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 10687 else 10688 len += WMI_TLV_HDR_SIZE; 10689 10690 if (config == WFA_CONFIG_OCV) 10691 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 10692 else 10693 len += WMI_TLV_HDR_SIZE; 10694 10695 if (config == WFA_CONFIG_SA_QUERY) 10696 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 10697 else 10698 len += WMI_TLV_HDR_SIZE; 10699 10700 return len; 10701 } 10702 10703 /** 10704 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 10705 * @host_frmtype: Host defined OCV frame type 10706 * @ocv_frmtype: Pointer to hold WMI OCV frame type 10707 * 10708 * This function converts and fills host defined OCV frame type into WMI OCV 10709 * frame type. 10710 * 10711 * Return: CDF STATUS 10712 */ 10713 static QDF_STATUS 10714 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 10715 { 10716 switch (host_frmtype) { 10717 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 10718 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 10719 break; 10720 10721 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 10722 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 10723 break; 10724 10725 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 10726 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 10727 break; 10728 10729 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 10730 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 10731 break; 10732 10733 default: 10734 wmi_err("Invalid command type cmd %d", host_frmtype); 10735 return QDF_STATUS_E_FAILURE; 10736 } 10737 10738 return QDF_STATUS_SUCCESS; 10739 } 10740 10741 /** 10742 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 10743 * @wmi_handle: wmi handle 10744 * @wmi_wfatest: wfa test command 10745 * 10746 * This function sends wfa test command to fw. 10747 * 10748 * Return: CDF STATUS 10749 */ 10750 static 10751 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 10752 struct set_wfatest_params *wmi_wfatest) 10753 { 10754 wmi_wfa_config_cmd_fixed_param *cmd; 10755 wmi_wfa_config_rsnxe *rxne; 10756 wmi_wfa_config_csa *csa; 10757 wmi_wfa_config_ocv *ocv; 10758 wmi_wfa_config_saquery *saquery; 10759 wmi_buf_t wmi_buf; 10760 uint16_t len = sizeof(*cmd); 10761 uint8_t *buf_ptr; 10762 10763 len += wfa_config_param_len(wmi_wfatest->cmd); 10764 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10765 if (!wmi_buf) 10766 return QDF_STATUS_E_NOMEM; 10767 10768 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 10769 WMITLV_SET_HDR(&cmd->tlv_header, 10770 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 10771 WMITLV_GET_STRUCT_TLVLEN( 10772 wmi_wfa_config_cmd_fixed_param)); 10773 10774 cmd->vdev_id = wmi_wfatest->vdev_id; 10775 buf_ptr = (uint8_t *)(cmd + 1); 10776 10777 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 10778 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10779 sizeof(wmi_wfa_config_rsnxe)); 10780 buf_ptr += WMI_TLV_HDR_SIZE; 10781 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 10782 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 10783 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 10784 rxne->rsnxe_param = wmi_wfatest->value; 10785 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 10786 } else { 10787 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10788 buf_ptr += WMI_TLV_HDR_SIZE; 10789 } 10790 10791 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 10792 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10793 sizeof(wmi_wfa_config_csa)); 10794 buf_ptr += WMI_TLV_HDR_SIZE; 10795 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 10796 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 10797 csa = (wmi_wfa_config_csa *)buf_ptr; 10798 csa->ignore_csa = wmi_wfatest->value; 10799 buf_ptr += sizeof(wmi_wfa_config_csa); 10800 } else { 10801 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10802 buf_ptr += WMI_TLV_HDR_SIZE; 10803 } 10804 10805 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 10806 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10807 sizeof(wmi_wfa_config_ocv)); 10808 buf_ptr += WMI_TLV_HDR_SIZE; 10809 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 10810 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 10811 ocv = (wmi_wfa_config_ocv *)buf_ptr; 10812 10813 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 10814 &ocv->frame_types)) 10815 goto error; 10816 10817 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 10818 buf_ptr += sizeof(wmi_wfa_config_ocv); 10819 } else { 10820 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10821 buf_ptr += WMI_TLV_HDR_SIZE; 10822 } 10823 10824 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 10825 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10826 sizeof(wmi_wfa_config_saquery)); 10827 buf_ptr += WMI_TLV_HDR_SIZE; 10828 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 10829 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 10830 10831 saquery = (wmi_wfa_config_saquery *)buf_ptr; 10832 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 10833 } else { 10834 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10835 buf_ptr += WMI_TLV_HDR_SIZE; 10836 } 10837 10838 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 10839 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10840 WMI_WFA_CONFIG_CMDID)) { 10841 wmi_err("Failed to send wfa test command"); 10842 goto error; 10843 } 10844 10845 return QDF_STATUS_SUCCESS; 10846 10847 error: 10848 wmi_buf_free(wmi_buf); 10849 return QDF_STATUS_E_FAILURE; 10850 } 10851 10852 /** 10853 * send_unit_test_cmd_tlv() - send unit test command to fw. 10854 * @wmi_handle: wmi handle 10855 * @wmi_utest: unit test command 10856 * 10857 * This function send unit test command to fw. 10858 * 10859 * Return: CDF STATUS 10860 */ 10861 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 10862 struct wmi_unit_test_cmd *wmi_utest) 10863 { 10864 wmi_unit_test_cmd_fixed_param *cmd; 10865 wmi_buf_t wmi_buf; 10866 uint8_t *buf_ptr; 10867 int i; 10868 uint16_t len, args_tlv_len; 10869 uint32_t *unit_test_cmd_args; 10870 10871 args_tlv_len = 10872 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 10873 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 10874 10875 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10876 if (!wmi_buf) 10877 return QDF_STATUS_E_NOMEM; 10878 10879 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10880 buf_ptr = (uint8_t *) cmd; 10881 WMITLV_SET_HDR(&cmd->tlv_header, 10882 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 10883 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 10884 cmd->vdev_id = wmi_utest->vdev_id; 10885 cmd->module_id = wmi_utest->module_id; 10886 cmd->num_args = wmi_utest->num_args; 10887 cmd->diag_token = wmi_utest->diag_token; 10888 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 10889 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10890 (wmi_utest->num_args * sizeof(uint32_t))); 10891 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10892 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 10893 cmd->vdev_id, cmd->module_id, cmd->diag_token); 10894 wmi_debug("%d num of args = ", wmi_utest->num_args); 10895 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 10896 unit_test_cmd_args[i] = wmi_utest->args[i]; 10897 wmi_debug("%d,", wmi_utest->args[i]); 10898 } 10899 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 10900 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10901 WMI_UNIT_TEST_CMDID)) { 10902 wmi_err("Failed to send unit test command"); 10903 wmi_buf_free(wmi_buf); 10904 return QDF_STATUS_E_FAILURE; 10905 } 10906 10907 return QDF_STATUS_SUCCESS; 10908 } 10909 10910 /** 10911 * send_power_dbg_cmd_tlv() - send power debug commands 10912 * @wmi_handle: wmi handle 10913 * @param: wmi power debug parameter 10914 * 10915 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 10916 * 10917 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10918 */ 10919 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 10920 struct wmi_power_dbg_params *param) 10921 { 10922 wmi_buf_t buf = NULL; 10923 QDF_STATUS status; 10924 int len, args_tlv_len; 10925 uint8_t *buf_ptr; 10926 uint8_t i; 10927 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 10928 uint32_t *cmd_args; 10929 10930 /* Prepare and send power debug cmd parameters */ 10931 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 10932 len = sizeof(*cmd) + args_tlv_len; 10933 buf = wmi_buf_alloc(wmi_handle, len); 10934 if (!buf) 10935 return QDF_STATUS_E_NOMEM; 10936 10937 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10938 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 10939 WMITLV_SET_HDR(&cmd->tlv_header, 10940 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 10941 WMITLV_GET_STRUCT_TLVLEN 10942 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 10943 10944 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10945 wmi_handle, 10946 param->pdev_id); 10947 cmd->module_id = param->module_id; 10948 cmd->num_args = param->num_args; 10949 buf_ptr += sizeof(*cmd); 10950 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10951 (param->num_args * sizeof(uint32_t))); 10952 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10953 wmi_debug("%d num of args = ", param->num_args); 10954 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 10955 cmd_args[i] = param->args[i]; 10956 wmi_debug("%d,", param->args[i]); 10957 } 10958 10959 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 10960 status = wmi_unified_cmd_send(wmi_handle, buf, 10961 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 10962 if (QDF_IS_STATUS_ERROR(status)) { 10963 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 10964 status); 10965 goto error; 10966 } 10967 10968 return QDF_STATUS_SUCCESS; 10969 error: 10970 wmi_buf_free(buf); 10971 10972 return status; 10973 } 10974 10975 /** 10976 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 10977 * @wmi_handle: wmi handle 10978 * @pdev_id: pdev id 10979 * 10980 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 10981 * 10982 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10983 */ 10984 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 10985 uint32_t pdev_id) 10986 { 10987 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 10988 wmi_buf_t buf; 10989 uint16_t len; 10990 QDF_STATUS ret; 10991 10992 len = sizeof(*cmd); 10993 buf = wmi_buf_alloc(wmi_handle, len); 10994 10995 wmi_debug("pdev_id=%d", pdev_id); 10996 10997 if (!buf) 10998 return QDF_STATUS_E_NOMEM; 10999 11000 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11001 wmi_buf_data(buf); 11002 11003 WMITLV_SET_HDR(&cmd->tlv_header, 11004 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11005 WMITLV_GET_STRUCT_TLVLEN( 11006 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11007 11008 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11009 wmi_handle, 11010 pdev_id); 11011 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11012 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11013 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11014 if (QDF_IS_STATUS_ERROR(ret)) { 11015 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11016 ret, pdev_id); 11017 wmi_buf_free(buf); 11018 return QDF_STATUS_E_FAILURE; 11019 } 11020 11021 return QDF_STATUS_SUCCESS; 11022 } 11023 11024 /** 11025 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11026 * @wmi_handle: wmi handle 11027 * @pdev_id: pdev id 11028 * 11029 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11030 * 11031 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11032 */ 11033 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11034 uint32_t pdev_id) 11035 { 11036 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11037 wmi_buf_t buf; 11038 uint16_t len; 11039 QDF_STATUS ret; 11040 11041 len = sizeof(*cmd); 11042 buf = wmi_buf_alloc(wmi_handle, len); 11043 11044 wmi_debug("pdev_id=%d", pdev_id); 11045 11046 if (!buf) 11047 return QDF_STATUS_E_NOMEM; 11048 11049 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11050 wmi_buf_data(buf); 11051 11052 WMITLV_SET_HDR(&cmd->tlv_header, 11053 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11054 WMITLV_GET_STRUCT_TLVLEN( 11055 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11056 11057 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11058 wmi_handle, 11059 pdev_id); 11060 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11061 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11062 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11063 if (QDF_IS_STATUS_ERROR(ret)) { 11064 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11065 ret, pdev_id); 11066 wmi_buf_free(buf); 11067 return QDF_STATUS_E_FAILURE; 11068 } 11069 11070 return QDF_STATUS_SUCCESS; 11071 } 11072 11073 #ifdef QCA_SUPPORT_AGILE_DFS 11074 static 11075 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11076 struct vdev_adfs_ch_cfg_params *param) 11077 { 11078 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11079 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11080 wmi_buf_t buf; 11081 QDF_STATUS ret; 11082 uint16_t len; 11083 11084 len = sizeof(*cmd); 11085 buf = wmi_buf_alloc(wmi_handle, len); 11086 11087 if (!buf) { 11088 wmi_err("wmi_buf_alloc failed"); 11089 return QDF_STATUS_E_NOMEM; 11090 } 11091 11092 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11093 wmi_buf_data(buf); 11094 11095 WMITLV_SET_HDR(&cmd->tlv_header, 11096 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11097 WMITLV_GET_STRUCT_TLVLEN 11098 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11099 11100 cmd->vdev_id = param->vdev_id; 11101 cmd->ocac_mode = param->ocac_mode; 11102 cmd->center_freq1 = param->center_freq1; 11103 cmd->center_freq2 = param->center_freq2; 11104 cmd->chan_freq = param->chan_freq; 11105 cmd->chan_width = param->chan_width; 11106 cmd->min_duration_ms = param->min_duration_ms; 11107 cmd->max_duration_ms = param->max_duration_ms; 11108 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11109 cmd->vdev_id, cmd->ocac_mode, 11110 cmd->center_freq); 11111 11112 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11113 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11114 WMI_VDEV_ADFS_CH_CFG_CMDID); 11115 11116 if (QDF_IS_STATUS_ERROR(ret)) { 11117 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11118 wmi_buf_free(buf); 11119 return QDF_STATUS_E_FAILURE; 11120 } 11121 11122 return QDF_STATUS_SUCCESS; 11123 } 11124 11125 static 11126 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11127 struct vdev_adfs_abort_params *param) 11128 { 11129 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11130 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11131 wmi_buf_t buf; 11132 QDF_STATUS ret; 11133 uint16_t len; 11134 11135 len = sizeof(*cmd); 11136 buf = wmi_buf_alloc(wmi_handle, len); 11137 11138 if (!buf) { 11139 wmi_err("wmi_buf_alloc failed"); 11140 return QDF_STATUS_E_NOMEM; 11141 } 11142 11143 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11144 wmi_buf_data(buf); 11145 11146 WMITLV_SET_HDR 11147 (&cmd->tlv_header, 11148 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11149 WMITLV_GET_STRUCT_TLVLEN 11150 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11151 11152 cmd->vdev_id = param->vdev_id; 11153 11154 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11155 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11156 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11157 11158 if (QDF_IS_STATUS_ERROR(ret)) { 11159 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11160 wmi_buf_free(buf); 11161 return QDF_STATUS_E_FAILURE; 11162 } 11163 11164 return QDF_STATUS_SUCCESS; 11165 } 11166 #endif 11167 11168 /** 11169 * init_cmd_send_tlv() - send initialization cmd to fw 11170 * @wmi_handle: wmi handle 11171 * @param param: pointer to wmi init param 11172 * 11173 * Return: QDF_STATUS_SUCCESS for success or error code 11174 */ 11175 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11176 struct wmi_init_cmd_param *param) 11177 { 11178 wmi_buf_t buf; 11179 wmi_init_cmd_fixed_param *cmd; 11180 uint8_t *buf_ptr; 11181 wmi_resource_config *resource_cfg; 11182 wlan_host_memory_chunk *host_mem_chunks; 11183 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11184 uint16_t idx; 11185 int len; 11186 QDF_STATUS ret; 11187 11188 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11189 WMI_TLV_HDR_SIZE; 11190 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11191 11192 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11193 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11194 WMI_TLV_HDR_SIZE + 11195 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11196 11197 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11198 if (!buf) 11199 return QDF_STATUS_E_FAILURE; 11200 11201 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11202 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11203 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11204 11205 host_mem_chunks = (wlan_host_memory_chunk *) 11206 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11207 + WMI_TLV_HDR_SIZE); 11208 11209 WMITLV_SET_HDR(&cmd->tlv_header, 11210 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11211 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11212 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11213 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11214 WMITLV_TAG_STRUC_wmi_resource_config, 11215 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11216 11217 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11218 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11219 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11220 WMITLV_GET_STRUCT_TLVLEN 11221 (wlan_host_memory_chunk)); 11222 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11223 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11224 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11225 if (is_service_enabled_tlv(wmi_handle, 11226 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11227 host_mem_chunks[idx].ptr_high = 11228 qdf_get_upper_32_bits( 11229 param->mem_chunks[idx].paddr); 11230 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11231 "chunk %d len %d requested ,ptr 0x%x ", 11232 idx, host_mem_chunks[idx].size, 11233 host_mem_chunks[idx].ptr); 11234 } 11235 cmd->num_host_mem_chunks = param->num_mem_chunks; 11236 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11237 11238 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11239 WMITLV_TAG_ARRAY_STRUC, 11240 (sizeof(wlan_host_memory_chunk) * 11241 param->num_mem_chunks)); 11242 11243 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", 11244 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11245 resource_cfg->num_vdevs, resource_cfg->num_tids, 11246 resource_cfg->num_tdls_conn_table_entries, 11247 resource_cfg->num_tdls_vdevs); 11248 11249 /* Fill hw mode id config */ 11250 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11251 11252 /* Fill fw_abi_vers */ 11253 copy_fw_abi_version_tlv(wmi_handle, cmd); 11254 11255 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11256 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11257 if (QDF_IS_STATUS_ERROR(ret)) { 11258 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11259 ret); 11260 wmi_buf_free(buf); 11261 } 11262 11263 return ret; 11264 11265 } 11266 11267 /** 11268 * send_addba_send_cmd_tlv() - send addba send command to fw 11269 * @wmi_handle: wmi handle 11270 * @param: pointer to delba send params 11271 * @macaddr: peer mac address 11272 * 11273 * Send WMI_ADDBA_SEND_CMDID command to firmware 11274 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11275 */ 11276 static QDF_STATUS 11277 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11278 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11279 struct addba_send_params *param) 11280 { 11281 wmi_addba_send_cmd_fixed_param *cmd; 11282 wmi_buf_t buf; 11283 uint16_t len; 11284 QDF_STATUS ret; 11285 11286 len = sizeof(*cmd); 11287 11288 buf = wmi_buf_alloc(wmi_handle, len); 11289 if (!buf) 11290 return QDF_STATUS_E_NOMEM; 11291 11292 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11293 11294 WMITLV_SET_HDR(&cmd->tlv_header, 11295 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11296 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11297 11298 cmd->vdev_id = param->vdev_id; 11299 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11300 cmd->tid = param->tidno; 11301 cmd->buffersize = param->buffersize; 11302 11303 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11304 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11305 if (QDF_IS_STATUS_ERROR(ret)) { 11306 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11307 wmi_buf_free(buf); 11308 return QDF_STATUS_E_FAILURE; 11309 } 11310 11311 return QDF_STATUS_SUCCESS; 11312 } 11313 11314 /** 11315 * send_delba_send_cmd_tlv() - send delba send command to fw 11316 * @wmi_handle: wmi handle 11317 * @param: pointer to delba send params 11318 * @macaddr: peer mac address 11319 * 11320 * Send WMI_DELBA_SEND_CMDID command to firmware 11321 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11322 */ 11323 static QDF_STATUS 11324 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11325 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11326 struct delba_send_params *param) 11327 { 11328 wmi_delba_send_cmd_fixed_param *cmd; 11329 wmi_buf_t buf; 11330 uint16_t len; 11331 QDF_STATUS ret; 11332 11333 len = sizeof(*cmd); 11334 11335 buf = wmi_buf_alloc(wmi_handle, len); 11336 if (!buf) 11337 return QDF_STATUS_E_NOMEM; 11338 11339 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 11340 11341 WMITLV_SET_HDR(&cmd->tlv_header, 11342 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 11343 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 11344 11345 cmd->vdev_id = param->vdev_id; 11346 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11347 cmd->tid = param->tidno; 11348 cmd->initiator = param->initiator; 11349 cmd->reasoncode = param->reasoncode; 11350 11351 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 11352 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 11353 if (QDF_IS_STATUS_ERROR(ret)) { 11354 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11355 wmi_buf_free(buf); 11356 return QDF_STATUS_E_FAILURE; 11357 } 11358 11359 return QDF_STATUS_SUCCESS; 11360 } 11361 11362 /** 11363 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 11364 * to fw 11365 * @wmi_handle: wmi handle 11366 * @param: pointer to addba clearresp params 11367 * @macaddr: peer mac address 11368 * Return: 0 for success or error code 11369 */ 11370 static QDF_STATUS 11371 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 11372 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11373 struct addba_clearresponse_params *param) 11374 { 11375 wmi_addba_clear_resp_cmd_fixed_param *cmd; 11376 wmi_buf_t buf; 11377 uint16_t len; 11378 QDF_STATUS ret; 11379 11380 len = sizeof(*cmd); 11381 11382 buf = wmi_buf_alloc(wmi_handle, len); 11383 if (!buf) 11384 return QDF_STATUS_E_FAILURE; 11385 11386 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 11387 11388 WMITLV_SET_HDR(&cmd->tlv_header, 11389 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 11390 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 11391 11392 cmd->vdev_id = param->vdev_id; 11393 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11394 11395 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 11396 ret = wmi_unified_cmd_send(wmi_handle, 11397 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 11398 if (QDF_IS_STATUS_ERROR(ret)) { 11399 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11400 wmi_buf_free(buf); 11401 return QDF_STATUS_E_FAILURE; 11402 } 11403 11404 return QDF_STATUS_SUCCESS; 11405 } 11406 11407 #ifdef OBSS_PD 11408 /** 11409 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 11410 * def thresh to fw 11411 * @wmi_handle: wmi handle 11412 * @thresh: pointer to obss_spatial_reuse_def_thresh 11413 * 11414 * Return: QDF_STATUS_SUCCESS for success or error code 11415 */ 11416 static 11417 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 11418 wmi_unified_t wmi_handle, 11419 struct wmi_host_obss_spatial_reuse_set_def_thresh 11420 *thresh) 11421 { 11422 wmi_buf_t buf; 11423 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 11424 QDF_STATUS ret; 11425 uint32_t cmd_len; 11426 uint32_t tlv_len; 11427 11428 cmd_len = sizeof(*cmd); 11429 11430 buf = wmi_buf_alloc(wmi_handle, cmd_len); 11431 if (!buf) 11432 return QDF_STATUS_E_NOMEM; 11433 11434 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 11435 wmi_buf_data(buf); 11436 11437 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 11438 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 11439 11440 WMITLV_SET_HDR(&cmd->tlv_header, 11441 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 11442 tlv_len); 11443 11444 cmd->obss_min = thresh->obss_min; 11445 cmd->obss_max = thresh->obss_max; 11446 cmd->vdev_type = thresh->vdev_type; 11447 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 11448 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 11449 if (QDF_IS_STATUS_ERROR(ret)) 11450 wmi_buf_free(buf); 11451 11452 return ret; 11453 } 11454 11455 /** 11456 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 11457 * @wmi_handle: wmi handle 11458 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 11459 * 11460 * Return: QDF_STATUS_SUCCESS for success or error code 11461 */ 11462 static 11463 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 11464 struct wmi_host_obss_spatial_reuse_set_param 11465 *obss_spatial_reuse_param) 11466 { 11467 wmi_buf_t buf; 11468 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 11469 QDF_STATUS ret; 11470 uint32_t len; 11471 11472 len = sizeof(*cmd); 11473 11474 buf = wmi_buf_alloc(wmi_handle, len); 11475 if (!buf) 11476 return QDF_STATUS_E_FAILURE; 11477 11478 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 11479 WMITLV_SET_HDR(&cmd->tlv_header, 11480 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 11481 WMITLV_GET_STRUCT_TLVLEN 11482 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 11483 11484 cmd->enable = obss_spatial_reuse_param->enable; 11485 cmd->obss_min = obss_spatial_reuse_param->obss_min; 11486 cmd->obss_max = obss_spatial_reuse_param->obss_max; 11487 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 11488 11489 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11490 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 11491 11492 if (QDF_IS_STATUS_ERROR(ret)) { 11493 wmi_err( 11494 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 11495 ret); 11496 wmi_buf_free(buf); 11497 } 11498 11499 return ret; 11500 } 11501 11502 /** 11503 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 11504 * to be used by SRG based Spatial Reuse feature to the FW 11505 * @wmi_handle: wmi handle 11506 * @bitmap_0: lower 32 bits in BSS color bitmap 11507 * @bitmap_1: upper 32 bits in BSS color bitmap 11508 * @pdev_id: pdev ID 11509 * 11510 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11511 */ 11512 static QDF_STATUS 11513 send_self_srg_bss_color_bitmap_set_cmd_tlv( 11514 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11515 uint32_t bitmap_1, uint8_t pdev_id) 11516 { 11517 wmi_buf_t buf; 11518 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 11519 QDF_STATUS ret; 11520 uint32_t len; 11521 11522 len = sizeof(*cmd); 11523 11524 buf = wmi_buf_alloc(wmi_handle, len); 11525 if (!buf) 11526 return QDF_STATUS_E_FAILURE; 11527 11528 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 11529 wmi_buf_data(buf); 11530 11531 WMITLV_SET_HDR( 11532 &cmd->tlv_header, 11533 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 11534 WMITLV_GET_STRUCT_TLVLEN 11535 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 11536 11537 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11538 wmi_handle, pdev_id); 11539 cmd->srg_bss_color_bitmap[0] = bitmap_0; 11540 cmd->srg_bss_color_bitmap[1] = bitmap_1; 11541 11542 ret = wmi_unified_cmd_send( 11543 wmi_handle, buf, len, 11544 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 11545 11546 if (QDF_IS_STATUS_ERROR(ret)) { 11547 wmi_err( 11548 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 11549 ret); 11550 wmi_buf_free(buf); 11551 } 11552 11553 return ret; 11554 } 11555 11556 /** 11557 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 11558 * bitmap to be used by SRG based Spatial Reuse feature to the FW 11559 * @wmi_handle: wmi handle 11560 * @bitmap_0: lower 32 bits in partial BSSID bitmap 11561 * @bitmap_1: upper 32 bits in partial BSSID bitmap 11562 * @pdev_id: pdev ID 11563 * 11564 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11565 */ 11566 static QDF_STATUS 11567 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 11568 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11569 uint32_t bitmap_1, uint8_t pdev_id) 11570 { 11571 wmi_buf_t buf; 11572 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 11573 QDF_STATUS ret; 11574 uint32_t len; 11575 11576 len = sizeof(*cmd); 11577 11578 buf = wmi_buf_alloc(wmi_handle, len); 11579 if (!buf) 11580 return QDF_STATUS_E_FAILURE; 11581 11582 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 11583 wmi_buf_data(buf); 11584 11585 WMITLV_SET_HDR( 11586 &cmd->tlv_header, 11587 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 11588 WMITLV_GET_STRUCT_TLVLEN 11589 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 11590 11591 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11592 wmi_handle, pdev_id); 11593 11594 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 11595 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 11596 11597 ret = wmi_unified_cmd_send( 11598 wmi_handle, buf, len, 11599 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 11600 11601 if (QDF_IS_STATUS_ERROR(ret)) { 11602 wmi_err( 11603 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 11604 ret); 11605 wmi_buf_free(buf); 11606 } 11607 11608 return ret; 11609 } 11610 11611 /** 11612 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11613 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11614 * @wmi_handle: wmi handle 11615 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11616 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11617 * @pdev_id: pdev ID 11618 * 11619 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11620 */ 11621 static QDF_STATUS 11622 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 11623 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11624 uint32_t bitmap_1, uint8_t pdev_id) 11625 { 11626 wmi_buf_t buf; 11627 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11628 QDF_STATUS ret; 11629 uint32_t len; 11630 11631 len = sizeof(*cmd); 11632 11633 buf = wmi_buf_alloc(wmi_handle, len); 11634 if (!buf) 11635 return QDF_STATUS_E_FAILURE; 11636 11637 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11638 wmi_buf_data(buf); 11639 11640 WMITLV_SET_HDR( 11641 &cmd->tlv_header, 11642 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 11643 WMITLV_GET_STRUCT_TLVLEN 11644 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11645 11646 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11647 wmi_handle, pdev_id); 11648 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 11649 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 11650 11651 ret = wmi_unified_cmd_send( 11652 wmi_handle, buf, len, 11653 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11654 11655 if (QDF_IS_STATUS_ERROR(ret)) { 11656 wmi_err( 11657 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11658 ret); 11659 wmi_buf_free(buf); 11660 } 11661 11662 return ret; 11663 } 11664 11665 /** 11666 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11667 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11668 * @wmi_handle: wmi handle 11669 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11670 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11671 * @pdev_id: pdev ID 11672 * 11673 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11674 */ 11675 static QDF_STATUS 11676 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 11677 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11678 uint32_t bitmap_1, uint8_t pdev_id) 11679 { 11680 wmi_buf_t buf; 11681 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11682 QDF_STATUS ret; 11683 uint32_t len; 11684 11685 len = sizeof(*cmd); 11686 11687 buf = wmi_buf_alloc(wmi_handle, len); 11688 if (!buf) 11689 return QDF_STATUS_E_FAILURE; 11690 11691 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11692 wmi_buf_data(buf); 11693 11694 WMITLV_SET_HDR( 11695 &cmd->tlv_header, 11696 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11697 WMITLV_GET_STRUCT_TLVLEN 11698 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11699 11700 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11701 wmi_handle, pdev_id); 11702 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 11703 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 11704 11705 ret = wmi_unified_cmd_send( 11706 wmi_handle, buf, len, 11707 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11708 11709 if (QDF_IS_STATUS_ERROR(ret)) { 11710 wmi_err( 11711 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11712 ret); 11713 wmi_buf_free(buf); 11714 } 11715 11716 return ret; 11717 } 11718 11719 /** 11720 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11721 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11722 * @wmi_handle: wmi handle 11723 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11724 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11725 * @pdev_id: pdev ID 11726 * 11727 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11728 */ 11729 static QDF_STATUS 11730 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 11731 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11732 uint32_t bitmap_1, uint8_t pdev_id) 11733 { 11734 wmi_buf_t buf; 11735 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11736 QDF_STATUS ret; 11737 uint32_t len; 11738 11739 len = sizeof(*cmd); 11740 11741 buf = wmi_buf_alloc(wmi_handle, len); 11742 if (!buf) 11743 return QDF_STATUS_E_FAILURE; 11744 11745 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11746 wmi_buf_data(buf); 11747 11748 WMITLV_SET_HDR( 11749 &cmd->tlv_header, 11750 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 11751 WMITLV_GET_STRUCT_TLVLEN 11752 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11753 11754 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11755 wmi_handle, pdev_id); 11756 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 11757 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 11758 11759 ret = wmi_unified_cmd_send( 11760 wmi_handle, buf, len, 11761 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11762 11763 if (QDF_IS_STATUS_ERROR(ret)) { 11764 wmi_err( 11765 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11766 ret); 11767 wmi_buf_free(buf); 11768 } 11769 11770 return ret; 11771 } 11772 11773 /** 11774 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11775 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11776 * @wmi_handle: wmi handle 11777 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11778 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11779 * @pdev_id: pdev ID 11780 * 11781 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11782 */ 11783 static QDF_STATUS 11784 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 11785 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11786 uint32_t bitmap_1, uint8_t pdev_id) 11787 { 11788 wmi_buf_t buf; 11789 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11790 QDF_STATUS ret; 11791 uint32_t len; 11792 11793 len = sizeof(*cmd); 11794 11795 buf = wmi_buf_alloc(wmi_handle, len); 11796 if (!buf) 11797 return QDF_STATUS_E_FAILURE; 11798 11799 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11800 wmi_buf_data(buf); 11801 11802 WMITLV_SET_HDR( 11803 &cmd->tlv_header, 11804 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11805 WMITLV_GET_STRUCT_TLVLEN 11806 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11807 11808 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11809 wmi_handle, pdev_id); 11810 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 11811 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 11812 11813 ret = wmi_unified_cmd_send( 11814 wmi_handle, buf, len, 11815 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11816 11817 if (QDF_IS_STATUS_ERROR(ret)) { 11818 wmi_err( 11819 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11820 ret); 11821 wmi_buf_free(buf); 11822 } 11823 11824 return ret; 11825 } 11826 #endif 11827 11828 static 11829 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 11830 struct wmi_host_injector_frame_params *inject_config_params) 11831 { 11832 wmi_buf_t buf; 11833 wmi_frame_inject_cmd_fixed_param *cmd; 11834 QDF_STATUS ret; 11835 uint32_t len; 11836 11837 len = sizeof(*cmd); 11838 11839 buf = wmi_buf_alloc(wmi_handle, len); 11840 if (!buf) 11841 return QDF_STATUS_E_NOMEM; 11842 11843 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 11844 WMITLV_SET_HDR(&cmd->tlv_header, 11845 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 11846 WMITLV_GET_STRUCT_TLVLEN 11847 (wmi_frame_inject_cmd_fixed_param)); 11848 11849 cmd->vdev_id = inject_config_params->vdev_id; 11850 cmd->enable = inject_config_params->enable; 11851 cmd->frame_type = inject_config_params->frame_type; 11852 cmd->frame_inject_period = inject_config_params->frame_inject_period; 11853 cmd->fc_duration = inject_config_params->frame_duration; 11854 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 11855 &cmd->frame_addr1); 11856 11857 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11858 WMI_PDEV_FRAME_INJECT_CMDID); 11859 11860 if (QDF_IS_STATUS_ERROR(ret)) { 11861 wmi_err( 11862 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 11863 ret); 11864 wmi_buf_free(buf); 11865 } 11866 11867 return ret; 11868 } 11869 #ifdef QCA_SUPPORT_CP_STATS 11870 /** 11871 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 11872 * @wmi_handle: wma handle 11873 * @evt_buf: event buffer 11874 * @out_buff: buffer to populated after stats extraction 11875 * 11876 * Return: status of operation 11877 */ 11878 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 11879 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 11880 { 11881 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11882 wmi_congestion_stats *congestion_stats; 11883 11884 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 11885 congestion_stats = param_buf->congestion_stats; 11886 if (!congestion_stats) 11887 return QDF_STATUS_E_INVAL; 11888 11889 out_buff->vdev_id = congestion_stats->vdev_id; 11890 out_buff->congestion = congestion_stats->congestion; 11891 11892 wmi_debug("cca stats event processed"); 11893 return QDF_STATUS_SUCCESS; 11894 } 11895 #endif /* QCA_SUPPORT_CP_STATS */ 11896 11897 /** 11898 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 11899 * event 11900 * @wmi_handle: wmi handle 11901 * @param evt_buf: pointer to event buffer 11902 * @param param: Pointer to hold peer ctl data 11903 * 11904 * Return: QDF_STATUS_SUCCESS for success or error code 11905 */ 11906 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 11907 wmi_unified_t wmi_handle, 11908 void *evt_buf, 11909 struct wmi_host_pdev_ctl_failsafe_event *param) 11910 { 11911 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 11912 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 11913 11914 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 11915 if (!param_buf) { 11916 wmi_err("Invalid ctl_failsafe event buffer"); 11917 return QDF_STATUS_E_INVAL; 11918 } 11919 11920 fix_param = param_buf->fixed_param; 11921 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 11922 11923 return QDF_STATUS_SUCCESS; 11924 } 11925 11926 /** 11927 * save_service_bitmap_tlv() - save service bitmap 11928 * @wmi_handle: wmi handle 11929 * @param evt_buf: pointer to event buffer 11930 * @param bitmap_buf: bitmap buffer, for converged legacy support 11931 * 11932 * Return: QDF_STATUS 11933 */ 11934 static 11935 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11936 void *bitmap_buf) 11937 { 11938 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11939 struct wmi_soc *soc = wmi_handle->soc; 11940 11941 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11942 11943 /* If it is already allocated, use that buffer. This can happen 11944 * during target stop/start scenarios where host allocation is skipped. 11945 */ 11946 if (!soc->wmi_service_bitmap) { 11947 soc->wmi_service_bitmap = 11948 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 11949 if (!soc->wmi_service_bitmap) 11950 return QDF_STATUS_E_NOMEM; 11951 } 11952 11953 qdf_mem_copy(soc->wmi_service_bitmap, 11954 param_buf->wmi_service_bitmap, 11955 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 11956 11957 if (bitmap_buf) 11958 qdf_mem_copy(bitmap_buf, 11959 param_buf->wmi_service_bitmap, 11960 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 11961 11962 return QDF_STATUS_SUCCESS; 11963 } 11964 11965 /** 11966 * save_ext_service_bitmap_tlv() - save extendend service bitmap 11967 * @wmi_handle: wmi handle 11968 * @param evt_buf: pointer to event buffer 11969 * @param bitmap_buf: bitmap buffer, for converged legacy support 11970 * 11971 * Return: QDF_STATUS 11972 */ 11973 static 11974 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11975 void *bitmap_buf) 11976 { 11977 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 11978 wmi_service_available_event_fixed_param *ev; 11979 struct wmi_soc *soc = wmi_handle->soc; 11980 uint32_t i = 0; 11981 11982 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 11983 11984 ev = param_buf->fixed_param; 11985 11986 /* If it is already allocated, use that buffer. This can happen 11987 * during target stop/start scenarios where host allocation is skipped. 11988 */ 11989 if (!soc->wmi_ext_service_bitmap) { 11990 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 11991 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 11992 if (!soc->wmi_ext_service_bitmap) 11993 return QDF_STATUS_E_NOMEM; 11994 } 11995 11996 qdf_mem_copy(soc->wmi_ext_service_bitmap, 11997 ev->wmi_service_segment_bitmap, 11998 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 11999 12000 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12001 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12002 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12003 12004 if (bitmap_buf) 12005 qdf_mem_copy(bitmap_buf, 12006 soc->wmi_ext_service_bitmap, 12007 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12008 12009 if (!param_buf->wmi_service_ext_bitmap) { 12010 wmi_debug("wmi_service_ext_bitmap not available"); 12011 return QDF_STATUS_SUCCESS; 12012 } 12013 12014 if (!soc->wmi_ext2_service_bitmap) { 12015 soc->wmi_ext2_service_bitmap = 12016 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12017 sizeof(uint32_t)); 12018 if (!soc->wmi_ext2_service_bitmap) 12019 return QDF_STATUS_E_NOMEM; 12020 } 12021 12022 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12023 param_buf->wmi_service_ext_bitmap, 12024 (param_buf->num_wmi_service_ext_bitmap * 12025 sizeof(uint32_t))); 12026 12027 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12028 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12029 i, soc->wmi_ext2_service_bitmap[i]); 12030 } 12031 12032 return QDF_STATUS_SUCCESS; 12033 } 12034 12035 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12036 struct wlan_psoc_target_capability_info *cap) 12037 { 12038 /* except LDPC all flags are common betwen legacy and here 12039 * also IBFEER is not defined for TLV 12040 */ 12041 cap->ht_cap_info |= ev_target_cap & ( 12042 WMI_HT_CAP_ENABLED 12043 | WMI_HT_CAP_HT20_SGI 12044 | WMI_HT_CAP_DYNAMIC_SMPS 12045 | WMI_HT_CAP_TX_STBC 12046 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12047 | WMI_HT_CAP_RX_STBC 12048 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12049 | WMI_HT_CAP_LDPC 12050 | WMI_HT_CAP_L_SIG_TXOP_PROT 12051 | WMI_HT_CAP_MPDU_DENSITY 12052 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12053 | WMI_HT_CAP_HT40_SGI); 12054 if (ev_target_cap & WMI_HT_CAP_LDPC) 12055 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12056 WMI_HOST_HT_CAP_TX_LDPC; 12057 } 12058 /** 12059 * extract_service_ready_tlv() - extract service ready event 12060 * @wmi_handle: wmi handle 12061 * @param evt_buf: pointer to received event buffer 12062 * @param cap: pointer to hold target capability information extracted from even 12063 * 12064 * Return: QDF_STATUS_SUCCESS for success or error code 12065 */ 12066 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12067 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12068 { 12069 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12070 wmi_service_ready_event_fixed_param *ev; 12071 12072 12073 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12074 12075 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12076 if (!ev) { 12077 qdf_print("%s: wmi_buf_alloc failed", __func__); 12078 return QDF_STATUS_E_FAILURE; 12079 } 12080 12081 cap->phy_capability = ev->phy_capability; 12082 cap->max_frag_entry = ev->max_frag_entry; 12083 cap->num_rf_chains = ev->num_rf_chains; 12084 copy_ht_cap_info(ev->ht_cap_info, cap); 12085 cap->vht_cap_info = ev->vht_cap_info; 12086 cap->vht_supp_mcs = ev->vht_supp_mcs; 12087 cap->hw_min_tx_power = ev->hw_min_tx_power; 12088 cap->hw_max_tx_power = ev->hw_max_tx_power; 12089 cap->sys_cap_info = ev->sys_cap_info; 12090 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12091 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12092 cap->max_num_scan_channels = ev->max_num_scan_channels; 12093 cap->max_supported_macs = ev->max_supported_macs; 12094 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12095 cap->txrx_chainmask = ev->txrx_chainmask; 12096 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12097 cap->num_msdu_desc = ev->num_msdu_desc; 12098 cap->fw_version = ev->fw_build_vers; 12099 /* fw_version_1 is not available in TLV. */ 12100 cap->fw_version_1 = 0; 12101 12102 return QDF_STATUS_SUCCESS; 12103 } 12104 12105 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12106 * to host internal HOST_REGDMN_MODE values. 12107 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12108 * host currently. Add this in the future if required. 12109 * 11AX (Phase II) : 11ax related values are not currently 12110 * advertised separately by FW. As part of phase II regulatory bring-up, 12111 * finalize the advertisement mechanism. 12112 * @target_wireless_mode: target wireless mode received in message 12113 * 12114 * Return: returns the host internal wireless mode. 12115 */ 12116 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12117 { 12118 12119 uint32_t wireless_modes = 0; 12120 12121 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12122 12123 if (target_wireless_mode & REGDMN_MODE_11A) 12124 wireless_modes |= HOST_REGDMN_MODE_11A; 12125 12126 if (target_wireless_mode & REGDMN_MODE_TURBO) 12127 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12128 12129 if (target_wireless_mode & REGDMN_MODE_11B) 12130 wireless_modes |= HOST_REGDMN_MODE_11B; 12131 12132 if (target_wireless_mode & REGDMN_MODE_PUREG) 12133 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12134 12135 if (target_wireless_mode & REGDMN_MODE_11G) 12136 wireless_modes |= HOST_REGDMN_MODE_11G; 12137 12138 if (target_wireless_mode & REGDMN_MODE_108G) 12139 wireless_modes |= HOST_REGDMN_MODE_108G; 12140 12141 if (target_wireless_mode & REGDMN_MODE_108A) 12142 wireless_modes |= HOST_REGDMN_MODE_108A; 12143 12144 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12145 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12146 12147 if (target_wireless_mode & REGDMN_MODE_XR) 12148 wireless_modes |= HOST_REGDMN_MODE_XR; 12149 12150 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12151 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12152 12153 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12154 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12155 12156 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12157 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12158 12159 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12160 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12161 12162 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12163 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12164 12165 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12166 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12167 12168 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12169 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12170 12171 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12172 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12173 12174 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12175 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12176 12177 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12178 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12179 12180 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12181 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12182 12183 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12184 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12185 12186 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12187 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12188 12189 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12190 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12191 12192 return wireless_modes; 12193 } 12194 12195 /** 12196 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12197 * to regulatory flags. 12198 * @target_phybitmap: target phybitmap. 12199 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12200 * phybitmap. 12201 * 12202 * Return: None 12203 */ 12204 12205 #ifdef WLAN_FEATURE_11BE 12206 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12207 uint32_t *phybitmap) 12208 { 12209 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12210 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12211 } 12212 #else 12213 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12214 uint32_t *phybitmap) 12215 { 12216 } 12217 #endif 12218 12219 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12220 * target to host internal REGULATORY_PHYMODE values. 12221 * 12222 * @target_target_phybitmap: target phybitmap received in the message. 12223 * 12224 * Return: returns the host internal REGULATORY_PHYMODE. 12225 */ 12226 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12227 { 12228 uint32_t phybitmap = 0; 12229 12230 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12231 12232 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12233 phybitmap |= REGULATORY_PHYMODE_NO11A; 12234 12235 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12236 phybitmap |= REGULATORY_PHYMODE_NO11B; 12237 12238 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12239 phybitmap |= REGULATORY_PHYMODE_NO11G; 12240 12241 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12242 phybitmap |= REGULATORY_CHAN_NO11N; 12243 12244 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12245 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12246 12247 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12248 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12249 12250 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12251 12252 return phybitmap; 12253 } 12254 12255 /** 12256 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12257 * advertised by the target to wireless mode ext flags. 12258 * @target_wireless_modes_ext: Target wireless mode 12259 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12260 * 12261 * Return: None 12262 */ 12263 #ifdef WLAN_FEATURE_11BE 12264 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12265 uint64_t *wireless_modes_ext) 12266 { 12267 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12268 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12269 12270 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12271 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12272 12273 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12274 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12275 12276 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12277 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12278 12279 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12280 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12281 12282 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12283 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12284 12285 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12286 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12287 12288 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12289 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12290 12291 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12292 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12293 } 12294 #else 12295 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12296 uint64_t *wireless_modes_ext) 12297 { 12298 } 12299 #endif 12300 12301 static inline uint64_t convert_wireless_modes_ext_tlv( 12302 uint32_t target_wireless_modes_ext) 12303 { 12304 uint64_t wireless_modes_ext = 0; 12305 12306 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12307 12308 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12309 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12310 12311 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12312 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12313 12314 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12315 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12316 12317 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12318 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12319 12320 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12321 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12322 12323 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12324 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12325 12326 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 12327 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 12328 12329 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 12330 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 12331 12332 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 12333 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 12334 12335 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 12336 &wireless_modes_ext); 12337 12338 return wireless_modes_ext; 12339 } 12340 12341 /** 12342 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 12343 * @wmi_handle: wmi handle 12344 * @param evt_buf: Pointer to event buffer 12345 * @param cap: pointer to hold HAL reg capabilities 12346 * 12347 * Return: QDF_STATUS_SUCCESS for success or error code 12348 */ 12349 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 12350 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 12351 { 12352 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12353 12354 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12355 if (!param_buf || !param_buf->hal_reg_capabilities) { 12356 wmi_err("Invalid arguments"); 12357 return QDF_STATUS_E_FAILURE; 12358 } 12359 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 12360 sizeof(uint32_t)), 12361 sizeof(struct wlan_psoc_hal_reg_capability)); 12362 12363 cap->wireless_modes = convert_wireless_modes_tlv( 12364 param_buf->hal_reg_capabilities->wireless_modes); 12365 12366 return QDF_STATUS_SUCCESS; 12367 } 12368 12369 /** 12370 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 12371 * @wmi_handle: wmi handle 12372 * @param evt_buf: Pointer to event buffer 12373 * @param cap: pointer to hold HAL reg capabilities 12374 * 12375 * Return: QDF_STATUS_SUCCESS for success or error code 12376 */ 12377 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 12378 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 12379 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 12380 { 12381 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12382 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 12383 12384 if (!evt_buf) { 12385 wmi_err("null evt_buf"); 12386 return QDF_STATUS_E_INVAL; 12387 } 12388 12389 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 12390 12391 if (!param_buf->num_hal_reg_caps) 12392 return QDF_STATUS_SUCCESS; 12393 12394 if (phy_idx >= param_buf->num_hal_reg_caps) 12395 return QDF_STATUS_E_INVAL; 12396 12397 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 12398 12399 param->phy_id = reg_caps->phy_id; 12400 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12401 reg_caps->wireless_modes_ext); 12402 12403 return QDF_STATUS_SUCCESS; 12404 } 12405 12406 /** 12407 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 12408 * @wmi_handle: wmi handle 12409 * @evt_buf: pointer to event buffer 12410 * 12411 * Return: Number of entries requested 12412 */ 12413 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 12414 void *evt_buf) 12415 { 12416 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12417 wmi_service_ready_event_fixed_param *ev; 12418 12419 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12420 12421 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12422 if (!ev) { 12423 qdf_print("%s: wmi_buf_alloc failed", __func__); 12424 return 0; 12425 } 12426 12427 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 12428 wmi_err("Invalid num_mem_reqs %d:%d", 12429 ev->num_mem_reqs, param_buf->num_mem_reqs); 12430 return 0; 12431 } 12432 12433 return ev->num_mem_reqs; 12434 } 12435 12436 /** 12437 * extract_host_mem_req_tlv() - Extract host memory required from 12438 * service ready event 12439 * @wmi_handle: wmi handle 12440 * @evt_buf: pointer to event buffer 12441 * @mem_reqs: pointer to host memory request structure 12442 * @num_active_peers: number of active peers for peer cache 12443 * @num_peers: number of peers 12444 * @fw_prio: FW priority 12445 * @idx: index for memory request 12446 * 12447 * Return: Host memory request parameters requested by target 12448 */ 12449 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 12450 void *evt_buf, 12451 host_mem_req *mem_reqs, 12452 uint32_t num_active_peers, 12453 uint32_t num_peers, 12454 enum wmi_fw_mem_prio fw_prio, 12455 uint16_t idx) 12456 { 12457 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12458 12459 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 12460 12461 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 12462 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 12463 mem_reqs->num_unit_info = 12464 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 12465 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 12466 mem_reqs->tgt_num_units = 0; 12467 12468 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 12469 (mem_reqs->num_unit_info & 12470 REQ_TO_HOST_FOR_CONT_MEMORY)) || 12471 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 12472 (!(mem_reqs->num_unit_info & 12473 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 12474 /* First allocate the memory that requires contiguous memory */ 12475 mem_reqs->tgt_num_units = mem_reqs->num_units; 12476 if (mem_reqs->num_unit_info) { 12477 if (mem_reqs->num_unit_info & 12478 NUM_UNITS_IS_NUM_PEERS) { 12479 /* 12480 * number of units allocated is equal to number 12481 * of peers, 1 extra for self peer on target. 12482 * this needs to be fixed, host and target can 12483 * get out of sync 12484 */ 12485 mem_reqs->tgt_num_units = num_peers + 1; 12486 } 12487 if (mem_reqs->num_unit_info & 12488 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 12489 /* 12490 * Requesting allocation of memory using 12491 * num_active_peers in qcache. if qcache is 12492 * disabled in host, then it should allocate 12493 * memory for num_peers instead of 12494 * num_active_peers. 12495 */ 12496 if (num_active_peers) 12497 mem_reqs->tgt_num_units = 12498 num_active_peers + 1; 12499 else 12500 mem_reqs->tgt_num_units = 12501 num_peers + 1; 12502 } 12503 } 12504 12505 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 12506 "unit size %d actual units %d", 12507 idx, mem_reqs->req_id, 12508 mem_reqs->num_units, 12509 mem_reqs->num_unit_info, 12510 mem_reqs->unit_size, 12511 mem_reqs->tgt_num_units); 12512 } 12513 12514 return QDF_STATUS_SUCCESS; 12515 } 12516 12517 /** 12518 * save_fw_version_in_service_ready_tlv() - Save fw version in service 12519 * ready function 12520 * @wmi_handle: wmi handle 12521 * @param evt_buf: pointer to event buffer 12522 * 12523 * Return: QDF_STATUS_SUCCESS for success or error code 12524 */ 12525 static QDF_STATUS 12526 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12527 { 12528 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12529 wmi_service_ready_event_fixed_param *ev; 12530 12531 12532 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12533 12534 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12535 if (!ev) { 12536 qdf_print("%s: wmi_buf_alloc failed", __func__); 12537 return QDF_STATUS_E_FAILURE; 12538 } 12539 12540 /*Save fw version from service ready message */ 12541 /*This will be used while sending INIT message */ 12542 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12543 sizeof(wmi_handle->fw_abi_version)); 12544 12545 return QDF_STATUS_SUCCESS; 12546 } 12547 12548 /** 12549 * ready_extract_init_status_tlv() - Extract init status from ready event 12550 * @wmi_handle: wmi handle 12551 * @param evt_buf: Pointer to event buffer 12552 * 12553 * Return: ready status 12554 */ 12555 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 12556 void *evt_buf) 12557 { 12558 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12559 wmi_ready_event_fixed_param *ev = NULL; 12560 12561 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12562 ev = param_buf->fixed_param; 12563 12564 qdf_print("%s:%d", __func__, ev->status); 12565 12566 return ev->status; 12567 } 12568 12569 /** 12570 * ready_extract_mac_addr_tlv() - extract mac address from ready event 12571 * @wmi_handle: wmi handle 12572 * @param evt_buf: pointer to event buffer 12573 * @param macaddr: Pointer to hold MAC address 12574 * 12575 * Return: QDF_STATUS_SUCCESS for success or error code 12576 */ 12577 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 12578 void *evt_buf, uint8_t *macaddr) 12579 { 12580 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12581 wmi_ready_event_fixed_param *ev = NULL; 12582 12583 12584 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12585 ev = param_buf->fixed_param; 12586 12587 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 12588 12589 return QDF_STATUS_SUCCESS; 12590 } 12591 12592 /** 12593 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 12594 * @wmi_handle: wmi handle 12595 * @param evt_buf: pointer to event buffer 12596 * @param macaddr: Pointer to hold number of MAC addresses 12597 * 12598 * Return: Pointer to addr list 12599 */ 12600 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 12601 void *evt_buf, uint8_t *num_mac) 12602 { 12603 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12604 wmi_ready_event_fixed_param *ev = NULL; 12605 12606 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12607 ev = param_buf->fixed_param; 12608 12609 *num_mac = ev->num_extra_mac_addr; 12610 12611 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 12612 } 12613 12614 /** 12615 * extract_ready_params_tlv() - Extract data from ready event apart from 12616 * status, macaddr and version. 12617 * @wmi_handle: Pointer to WMI handle. 12618 * @evt_buf: Pointer to Ready event buffer. 12619 * @ev_param: Pointer to host defined struct to copy the data from event. 12620 * 12621 * Return: QDF_STATUS_SUCCESS on success. 12622 */ 12623 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 12624 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 12625 { 12626 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12627 wmi_ready_event_fixed_param *ev = NULL; 12628 12629 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12630 ev = param_buf->fixed_param; 12631 12632 ev_param->status = ev->status; 12633 ev_param->num_dscp_table = ev->num_dscp_table; 12634 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 12635 ev_param->num_total_peer = ev->num_total_peers; 12636 ev_param->num_extra_peer = ev->num_extra_peers; 12637 /* Agile_capability in ready event is supported in TLV target, 12638 * as per aDFS FR 12639 */ 12640 ev_param->max_ast_index = ev->max_ast_index; 12641 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 12642 ev_param->agile_capability = 1; 12643 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 12644 12645 return QDF_STATUS_SUCCESS; 12646 } 12647 12648 /** 12649 * extract_dbglog_data_len_tlv() - extract debuglog data length 12650 * @wmi_handle: wmi handle 12651 * @param evt_buf: pointer to event buffer 12652 * 12653 * Return: length 12654 */ 12655 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 12656 void *evt_buf, uint32_t *len) 12657 { 12658 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 12659 12660 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 12661 12662 *len = param_buf->num_bufp; 12663 12664 return param_buf->bufp; 12665 } 12666 12667 12668 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 12669 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 12670 #else 12671 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 12672 ((_status) & WMI_RXERR_DECRYPT) 12673 #endif 12674 12675 /** 12676 * extract_mgmt_rx_params_tlv() - extract management rx params from event 12677 * @wmi_handle: wmi handle 12678 * @param evt_buf: pointer to event buffer 12679 * @param hdr: Pointer to hold header 12680 * @param bufp: Pointer to hold pointer to rx param buffer 12681 * 12682 * Return: QDF_STATUS_SUCCESS for success or error code 12683 */ 12684 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 12685 void *evt_buf, struct mgmt_rx_event_params *hdr, 12686 uint8_t **bufp) 12687 { 12688 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 12689 wmi_mgmt_rx_hdr *ev_hdr = NULL; 12690 int i; 12691 12692 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12693 if (!param_tlvs) { 12694 wmi_err("Get NULL point message from FW"); 12695 return QDF_STATUS_E_INVAL; 12696 } 12697 12698 ev_hdr = param_tlvs->hdr; 12699 if (!hdr) { 12700 wmi_err("Rx event is NULL"); 12701 return QDF_STATUS_E_INVAL; 12702 } 12703 12704 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 12705 wmi_err("RX mgmt frame decrypt error, discard it"); 12706 return QDF_STATUS_E_INVAL; 12707 } 12708 12709 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 12710 wmi_err("Rx mgmt frame length mismatch, discard it"); 12711 return QDF_STATUS_E_INVAL; 12712 } 12713 12714 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12715 wmi_handle, 12716 ev_hdr->pdev_id); 12717 hdr->chan_freq = ev_hdr->chan_freq; 12718 hdr->channel = ev_hdr->channel; 12719 hdr->snr = ev_hdr->snr; 12720 hdr->rate = ev_hdr->rate; 12721 hdr->phy_mode = ev_hdr->phy_mode; 12722 hdr->buf_len = ev_hdr->buf_len; 12723 hdr->status = ev_hdr->status; 12724 hdr->flags = ev_hdr->flags; 12725 hdr->rssi = ev_hdr->rssi; 12726 hdr->tsf_delta = ev_hdr->tsf_delta; 12727 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 12728 for (i = 0; i < ATH_MAX_ANTENNA; i++) 12729 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 12730 12731 *bufp = param_tlvs->bufp; 12732 12733 return QDF_STATUS_SUCCESS; 12734 } 12735 12736 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 12737 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 12738 { 12739 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12740 wmi_mgmt_rx_params_ext *ext_params_tlv; 12741 wmi_mgmt_rx_hdr *ev_hdr; 12742 12743 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12744 if (!param_tlvs) { 12745 wmi_err("param_tlvs is NULL"); 12746 return QDF_STATUS_E_INVAL; 12747 } 12748 12749 ev_hdr = param_tlvs->hdr; 12750 if (!ev_hdr) { 12751 wmi_err("Rx event is NULL"); 12752 return QDF_STATUS_E_INVAL; 12753 } 12754 12755 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 12756 if (ext_params_tlv) { 12757 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 12758 ext_params_tlv->mgmt_rx_params_ext_dword1); 12759 if (ext_params->ba_win_size > 1024) { 12760 wmi_err("ba win size from TLV is Invalid"); 12761 return QDF_STATUS_E_INVAL; 12762 } 12763 12764 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 12765 ext_params_tlv->mgmt_rx_params_ext_dword1); 12766 if (ext_params->reo_win_size > 2048) { 12767 wmi_err("reo win size from TLV is Invalid"); 12768 return QDF_STATUS_E_INVAL; 12769 } 12770 } else { 12771 ext_params->ba_win_size = 0; 12772 ext_params->reo_win_size = 0; 12773 } 12774 12775 return QDF_STATUS_SUCCESS; 12776 } 12777 12778 #ifdef WLAN_MGMT_RX_REO_SUPPORT 12779 /** 12780 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 12781 * @wmi_handle: wmi handle 12782 * @evt_buf: pointer to event buffer 12783 * @params: Pointer to MGMT Rx REO parameters 12784 * 12785 * Return: QDF_STATUS_SUCCESS for success or error code 12786 */ 12787 static QDF_STATUS 12788 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 12789 void *evt_buf, 12790 struct mgmt_rx_reo_params *params) 12791 { 12792 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 12793 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 12794 12795 param_tlvs = evt_buf; 12796 if (!param_tlvs) { 12797 wmi_err("param_tlvs is NULL"); 12798 return QDF_STATUS_E_INVAL; 12799 } 12800 12801 ev_hdr = param_tlvs->hdr; 12802 if (!params) { 12803 wmi_err("Rx REO parameters is NULL"); 12804 return QDF_STATUS_E_INVAL; 12805 } 12806 12807 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12808 wmi_handle, 12809 ev_hdr->pdev_id); 12810 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 12811 ev_hdr->mgmt_pkt_ctr_info); 12812 params->global_timestamp = ev_hdr->global_timestamp; 12813 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 12814 ev_hdr->mgmt_pkt_ctr_info); 12815 params->duration_us = ev_hdr->rx_ppdu_duration_us; 12816 params->start_timestamp = params->global_timestamp; 12817 params->end_timestamp = params->start_timestamp + 12818 params->duration_us; 12819 12820 return QDF_STATUS_SUCCESS; 12821 } 12822 12823 /** 12824 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 12825 * MGMT_RX_EVENT_ID 12826 * @wmi_handle: wmi handle 12827 * @evt_buf: pointer to event buffer 12828 * @params: Pointer to MGMT Rx REO parameters 12829 * 12830 * Return: QDF_STATUS_SUCCESS for success or error code 12831 */ 12832 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 12833 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 12834 { 12835 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12836 wmi_mgmt_rx_reo_params *reo_params_tlv; 12837 wmi_mgmt_rx_hdr *ev_hdr; 12838 12839 param_tlvs = evt_buf; 12840 if (!param_tlvs) { 12841 wmi_err("param_tlvs is NULL"); 12842 return QDF_STATUS_E_INVAL; 12843 } 12844 12845 ev_hdr = param_tlvs->hdr; 12846 if (!ev_hdr) { 12847 wmi_err("Rx event is NULL"); 12848 return QDF_STATUS_E_INVAL; 12849 } 12850 12851 reo_params_tlv = param_tlvs->reo_params; 12852 if (!reo_params_tlv) { 12853 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 12854 return QDF_STATUS_E_INVAL; 12855 } 12856 12857 if (!reo_params) { 12858 wmi_err("MGMT Rx REO params is NULL"); 12859 return QDF_STATUS_E_INVAL; 12860 } 12861 12862 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12863 wmi_handle, 12864 ev_hdr->pdev_id); 12865 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 12866 reo_params_tlv->mgmt_pkt_ctr_link_info); 12867 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 12868 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 12869 reo_params_tlv->mgmt_pkt_ctr_link_info); 12870 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 12871 reo_params->start_timestamp = reo_params->global_timestamp; 12872 reo_params->end_timestamp = reo_params->start_timestamp + 12873 reo_params->duration_us; 12874 12875 return QDF_STATUS_SUCCESS; 12876 } 12877 12878 /** 12879 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 12880 * configuration command 12881 * @wmi_handle: wmi handle 12882 * @pdev_id: pdev ID of the radio 12883 * @filter: Pointer to MGMT Rx REO filter 12884 * 12885 * Return: QDF_STATUS_SUCCESS for success or error code 12886 */ 12887 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 12888 wmi_unified_t wmi_handle, 12889 uint8_t pdev_id, 12890 struct mgmt_rx_reo_filter *filter) 12891 { 12892 QDF_STATUS ret; 12893 wmi_buf_t buf; 12894 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 12895 size_t len = sizeof(*cmd); 12896 12897 if (!filter) { 12898 wmi_err("mgmt_rx_reo_filter is NULL"); 12899 return QDF_STATUS_E_INVAL; 12900 } 12901 12902 buf = wmi_buf_alloc(wmi_handle, len); 12903 if (!buf) { 12904 wmi_err("wmi_buf_alloc failed"); 12905 return QDF_STATUS_E_NOMEM; 12906 } 12907 12908 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 12909 wmi_buf_data(buf); 12910 12911 WMITLV_SET_HDR(&cmd->tlv_header, 12912 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 12913 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 12914 12915 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 12916 wmi_handle, 12917 pdev_id); 12918 cmd->filter_low = filter->low; 12919 cmd->filter_high = filter->high; 12920 12921 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 12922 ret = wmi_unified_cmd_send( 12923 wmi_handle, buf, len, 12924 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 12925 12926 if (QDF_IS_STATUS_ERROR(ret)) { 12927 wmi_err("Failed to send WMI command"); 12928 wmi_buf_free(buf); 12929 } 12930 12931 return ret; 12932 } 12933 #endif 12934 12935 /** 12936 * extract_frame_pn_params_tlv() - extract PN params from event 12937 * @wmi_handle: wmi handle 12938 * @evt_buf: pointer to event buffer 12939 * @pn_params: Pointer to Frame PN params 12940 * 12941 * Return: QDF_STATUS_SUCCESS for success or error code 12942 */ 12943 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 12944 void *evt_buf, 12945 struct frame_pn_params *pn_params) 12946 { 12947 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12948 wmi_frame_pn_params *pn_params_tlv; 12949 12950 if (!is_service_enabled_tlv(wmi_handle, 12951 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 12952 return QDF_STATUS_SUCCESS; 12953 12954 param_tlvs = evt_buf; 12955 if (!param_tlvs) { 12956 wmi_err("Got NULL point message from FW"); 12957 return QDF_STATUS_E_INVAL; 12958 } 12959 12960 if (!pn_params) { 12961 wmi_err("PN Params is NULL"); 12962 return QDF_STATUS_E_INVAL; 12963 } 12964 12965 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 12966 * found by target 12967 */ 12968 pn_params_tlv = param_tlvs->pn_params; 12969 if (!pn_params_tlv) 12970 return QDF_STATUS_SUCCESS; 12971 12972 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 12973 sizeof(pn_params->curr_pn)); 12974 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 12975 sizeof(pn_params->prev_pn)); 12976 12977 return QDF_STATUS_SUCCESS; 12978 } 12979 12980 /** 12981 * extract_is_conn_ap_param_tlv() - extract is_conn_ap_frame param from event 12982 * @wmi_handle: wmi handle 12983 * @evt_buf: pointer to event buffer 12984 * @is_conn_ap: Pointer for is_conn_ap frame 12985 * 12986 * Return: QDF_STATUS_SUCCESS for success or error code 12987 */ 12988 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 12989 wmi_unified_t wmi_handle, 12990 void *evt_buf, 12991 struct frm_conn_ap *is_conn_ap) 12992 { 12993 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12994 wmi_is_my_mgmt_frame *my_frame_tlv; 12995 12996 param_tlvs = evt_buf; 12997 if (!param_tlvs) { 12998 wmi_err("Got NULL point message from FW"); 12999 return QDF_STATUS_E_INVAL; 13000 } 13001 13002 if (!is_conn_ap) { 13003 wmi_err(" is connected ap param is NULL"); 13004 return QDF_STATUS_E_INVAL; 13005 } 13006 13007 my_frame_tlv = param_tlvs->my_frame; 13008 if (!my_frame_tlv) 13009 return QDF_STATUS_SUCCESS; 13010 13011 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13012 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13013 13014 return QDF_STATUS_SUCCESS; 13015 } 13016 13017 /** 13018 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13019 * @wmi_handle: wmi handle 13020 * @param evt_buf: pointer to event buffer 13021 * @param param: Pointer to hold roam param 13022 * 13023 * Return: QDF_STATUS_SUCCESS for success or error code 13024 */ 13025 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13026 void *evt_buf, wmi_host_roam_event *param) 13027 { 13028 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13029 wmi_roam_event_fixed_param *evt; 13030 13031 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13032 if (!param_buf) { 13033 wmi_err("Invalid roam event buffer"); 13034 return QDF_STATUS_E_INVAL; 13035 } 13036 13037 evt = param_buf->fixed_param; 13038 qdf_mem_zero(param, sizeof(*param)); 13039 13040 param->vdev_id = evt->vdev_id; 13041 param->reason = evt->reason; 13042 param->rssi = evt->rssi; 13043 13044 return QDF_STATUS_SUCCESS; 13045 } 13046 13047 /** 13048 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13049 * @wmi_handle: wmi handle 13050 * @param evt_buf: pointer to event buffer 13051 * @param param: Pointer to hold vdev scan param 13052 * 13053 * Return: QDF_STATUS_SUCCESS for success or error code 13054 */ 13055 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13056 void *evt_buf, struct scan_event *param) 13057 { 13058 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13059 wmi_scan_event_fixed_param *evt = NULL; 13060 13061 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13062 evt = param_buf->fixed_param; 13063 13064 qdf_mem_zero(param, sizeof(*param)); 13065 13066 switch (evt->event) { 13067 case WMI_SCAN_EVENT_STARTED: 13068 param->type = SCAN_EVENT_TYPE_STARTED; 13069 break; 13070 case WMI_SCAN_EVENT_COMPLETED: 13071 param->type = SCAN_EVENT_TYPE_COMPLETED; 13072 break; 13073 case WMI_SCAN_EVENT_BSS_CHANNEL: 13074 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13075 break; 13076 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13077 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13078 break; 13079 case WMI_SCAN_EVENT_DEQUEUED: 13080 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13081 break; 13082 case WMI_SCAN_EVENT_PREEMPTED: 13083 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13084 break; 13085 case WMI_SCAN_EVENT_START_FAILED: 13086 param->type = SCAN_EVENT_TYPE_START_FAILED; 13087 break; 13088 case WMI_SCAN_EVENT_RESTARTED: 13089 param->type = SCAN_EVENT_TYPE_RESTARTED; 13090 break; 13091 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13092 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13093 break; 13094 case WMI_SCAN_EVENT_MAX: 13095 default: 13096 param->type = SCAN_EVENT_TYPE_MAX; 13097 break; 13098 }; 13099 13100 switch (evt->reason) { 13101 case WMI_SCAN_REASON_NONE: 13102 param->reason = SCAN_REASON_NONE; 13103 break; 13104 case WMI_SCAN_REASON_COMPLETED: 13105 param->reason = SCAN_REASON_COMPLETED; 13106 break; 13107 case WMI_SCAN_REASON_CANCELLED: 13108 param->reason = SCAN_REASON_CANCELLED; 13109 break; 13110 case WMI_SCAN_REASON_PREEMPTED: 13111 param->reason = SCAN_REASON_PREEMPTED; 13112 break; 13113 case WMI_SCAN_REASON_TIMEDOUT: 13114 param->reason = SCAN_REASON_TIMEDOUT; 13115 break; 13116 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13117 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13118 break; 13119 case WMI_SCAN_REASON_SUSPENDED: 13120 param->reason = SCAN_REASON_SUSPENDED; 13121 break; 13122 case WMI_SCAN_REASON_DFS_VIOLATION: 13123 param->reason = SCAN_REASON_DFS_VIOLATION; 13124 break; 13125 case WMI_SCAN_REASON_MAX: 13126 param->reason = SCAN_REASON_MAX; 13127 break; 13128 default: 13129 param->reason = SCAN_REASON_MAX; 13130 break; 13131 }; 13132 13133 param->chan_freq = evt->channel_freq; 13134 param->requester = evt->requestor; 13135 param->scan_id = evt->scan_id; 13136 param->vdev_id = evt->vdev_id; 13137 param->timestamp = evt->tsf_timestamp; 13138 13139 return QDF_STATUS_SUCCESS; 13140 } 13141 13142 #ifdef FEATURE_WLAN_SCAN_PNO 13143 /** 13144 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13145 * @wmi_handle: pointer to WMI handle 13146 * @evt_buf: pointer to WMI event buffer 13147 * @param: pointer to scan event param for NLO match 13148 * 13149 * Return: QDF_STATUS_SUCCESS for success or error code 13150 */ 13151 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13152 void *evt_buf, 13153 struct scan_event *param) 13154 { 13155 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13156 wmi_nlo_event *evt = param_buf->fixed_param; 13157 13158 qdf_mem_zero(param, sizeof(*param)); 13159 13160 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13161 param->vdev_id = evt->vdev_id; 13162 13163 return QDF_STATUS_SUCCESS; 13164 } 13165 13166 /** 13167 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13168 * @wmi_handle: pointer to WMI handle 13169 * @evt_buf: pointer to WMI event buffer 13170 * @param: pointer to scan event param for NLO complete 13171 * 13172 * Return: QDF_STATUS_SUCCESS for success or error code 13173 */ 13174 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13175 void *evt_buf, 13176 struct scan_event *param) 13177 { 13178 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13179 wmi_nlo_event *evt = param_buf->fixed_param; 13180 13181 qdf_mem_zero(param, sizeof(*param)); 13182 13183 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13184 param->vdev_id = evt->vdev_id; 13185 13186 return QDF_STATUS_SUCCESS; 13187 } 13188 #endif 13189 13190 /** 13191 * extract_unit_test_tlv() - extract unit test data 13192 * @wmi_handle: wmi handle 13193 * @param evt_buf: pointer to event buffer 13194 * @param unit_test: pointer to hold unit test data 13195 * @param maxspace: Amount of space in evt_buf 13196 * 13197 * Return: QDF_STATUS_SUCCESS for success or error code 13198 */ 13199 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13200 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13201 { 13202 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13203 wmi_unit_test_event_fixed_param *ev_param; 13204 uint32_t num_bufp; 13205 uint32_t copy_size; 13206 uint8_t *bufp; 13207 13208 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13209 ev_param = param_buf->fixed_param; 13210 bufp = param_buf->bufp; 13211 num_bufp = param_buf->num_bufp; 13212 unit_test->vdev_id = ev_param->vdev_id; 13213 unit_test->module_id = ev_param->module_id; 13214 unit_test->diag_token = ev_param->diag_token; 13215 unit_test->flag = ev_param->flag; 13216 unit_test->payload_len = ev_param->payload_len; 13217 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13218 ev_param->vdev_id, 13219 ev_param->module_id, 13220 ev_param->diag_token, 13221 ev_param->flag); 13222 wmi_debug("Unit-test data given below %d", num_bufp); 13223 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13224 bufp, num_bufp); 13225 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13226 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13227 unit_test->buffer_len = copy_size; 13228 13229 return QDF_STATUS_SUCCESS; 13230 } 13231 13232 /** 13233 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13234 * @wmi_handle: wmi handle 13235 * @param evt_buf: pointer to event buffer 13236 * @param index: Index into extended pdev stats 13237 * @param pdev_ext_stats: Pointer to hold extended pdev stats 13238 * 13239 * Return: QDF_STATUS_SUCCESS for success or error code 13240 */ 13241 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13242 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13243 { 13244 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13245 wmi_pdev_extd_stats *ev; 13246 13247 param_buf = evt_buf; 13248 if (!param_buf) 13249 return QDF_STATUS_E_FAILURE; 13250 13251 if (!param_buf->pdev_extd_stats) 13252 return QDF_STATUS_E_FAILURE; 13253 13254 ev = param_buf->pdev_extd_stats + index; 13255 13256 pdev_ext_stats->pdev_id = 13257 wmi_handle->ops->convert_target_pdev_id_to_host( 13258 wmi_handle, 13259 ev->pdev_id); 13260 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13261 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13262 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13263 13264 return QDF_STATUS_SUCCESS; 13265 } 13266 13267 /** 13268 * extract_bcn_stats_tlv() - extract bcn stats from event 13269 * @wmi_handle: wmi handle 13270 * @param evt_buf: pointer to event buffer 13271 * @param index: Index into vdev stats 13272 * @param bcn_stats: Pointer to hold bcn stats 13273 * 13274 * Return: QDF_STATUS_SUCCESS for success or error code 13275 */ 13276 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13277 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13278 { 13279 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13280 wmi_stats_event_fixed_param *ev_param; 13281 uint8_t *data; 13282 13283 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13284 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13285 data = (uint8_t *) param_buf->data; 13286 13287 if (index < ev_param->num_bcn_stats) { 13288 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 13289 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13290 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13291 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13292 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 13293 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 13294 (index * sizeof(wmi_bcn_stats))); 13295 13296 bcn_stats->vdev_id = ev->vdev_id; 13297 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 13298 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 13299 } 13300 13301 return QDF_STATUS_SUCCESS; 13302 } 13303 13304 /** 13305 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 13306 * stats from event 13307 * @wmi_handle: wmi handle 13308 * @param evt_buf: pointer to event buffer 13309 * @param index: Index into vdev stats 13310 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 13311 * 13312 * Return: QDF_STATUS_SUCCESS for success or error code 13313 */ 13314 static QDF_STATUS 13315 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 13316 void *evt_buf, uint32_t index, 13317 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 13318 { 13319 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13320 wmi_vdev_extd_stats *ev; 13321 13322 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 13323 13324 if (param_buf->vdev_extd_stats) { 13325 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 13326 index); 13327 vdev_stats->vdev_id = ev->vdev_id; 13328 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 13329 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 13330 vdev_stats->unsolicited_prb_succ_cnt = 13331 ev->unsolicited_prb_succ_cnt; 13332 vdev_stats->unsolicited_prb_fail_cnt = 13333 ev->unsolicited_prb_fail_cnt; 13334 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 13335 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 13336 ev->unsolicited_prb_succ_cnt, 13337 ev->unsolicited_prb_fail_cnt); 13338 } 13339 13340 return QDF_STATUS_SUCCESS; 13341 } 13342 13343 /** 13344 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 13345 * @wmi_handle: wmi handle 13346 * @param evt_buf: pointer to event buffer 13347 * @param index: Index into bcn fault stats 13348 * @param bcnflt_stats: Pointer to hold bcn fault stats 13349 * 13350 * Return: QDF_STATUS_SUCCESS for success or error code 13351 */ 13352 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 13353 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 13354 { 13355 return QDF_STATUS_SUCCESS; 13356 } 13357 13358 /** 13359 * extract_chan_stats_tlv() - extract chan stats from event 13360 * @wmi_handle: wmi handle 13361 * @param evt_buf: pointer to event buffer 13362 * @param index: Index into chan stats 13363 * @param vdev_extd_stats: Pointer to hold chan stats 13364 * 13365 * Return: QDF_STATUS_SUCCESS for success or error code 13366 */ 13367 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 13368 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 13369 { 13370 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13371 wmi_stats_event_fixed_param *ev_param; 13372 uint8_t *data; 13373 13374 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13375 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13376 data = (uint8_t *) param_buf->data; 13377 13378 if (index < ev_param->num_chan_stats) { 13379 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 13380 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13381 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13382 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13383 (index * sizeof(wmi_chan_stats))); 13384 13385 13386 /* Non-TLV doesn't have num_chan_stats */ 13387 chan_stats->chan_mhz = ev->chan_mhz; 13388 chan_stats->sampling_period_us = ev->sampling_period_us; 13389 chan_stats->rx_clear_count = ev->rx_clear_count; 13390 chan_stats->tx_duration_us = ev->tx_duration_us; 13391 chan_stats->rx_duration_us = ev->rx_duration_us; 13392 } 13393 13394 return QDF_STATUS_SUCCESS; 13395 } 13396 13397 /** 13398 * extract_profile_ctx_tlv() - extract profile context from event 13399 * @wmi_handle: wmi handle 13400 * @param evt_buf: pointer to event buffer 13401 * @idx: profile stats index to extract 13402 * @param profile_ctx: Pointer to hold profile context 13403 * 13404 * Return: QDF_STATUS_SUCCESS for success or error code 13405 */ 13406 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 13407 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 13408 { 13409 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13410 13411 wmi_wlan_profile_ctx_t *ev; 13412 13413 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13414 if (!param_buf) { 13415 wmi_err("Invalid profile data event buf"); 13416 return QDF_STATUS_E_INVAL; 13417 } 13418 13419 ev = param_buf->profile_ctx; 13420 13421 profile_ctx->tot = ev->tot; 13422 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 13423 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 13424 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 13425 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 13426 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 13427 profile_ctx->bin_count = ev->bin_count; 13428 13429 return QDF_STATUS_SUCCESS; 13430 } 13431 13432 /** 13433 * extract_profile_data_tlv() - extract profile data from event 13434 * @wmi_handle: wmi handle 13435 * @param evt_buf: pointer to event buffer 13436 * @param profile_data: Pointer to hold profile data 13437 * 13438 * Return: QDF_STATUS_SUCCESS for success or error code 13439 */ 13440 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 13441 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 13442 { 13443 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13444 wmi_wlan_profile_t *ev; 13445 13446 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13447 if (!param_buf) { 13448 wmi_err("Invalid profile data event buf"); 13449 return QDF_STATUS_E_INVAL; 13450 } 13451 13452 ev = ¶m_buf->profile_data[idx]; 13453 profile_data->id = ev->id; 13454 profile_data->cnt = ev->cnt; 13455 profile_data->tot = ev->tot; 13456 profile_data->min = ev->min; 13457 profile_data->max = ev->max; 13458 profile_data->hist_intvl = ev->hist_intvl; 13459 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 13460 13461 return QDF_STATUS_SUCCESS; 13462 } 13463 13464 /** 13465 * extract_pdev_utf_event_tlv() - extract UTF data info from event 13466 * @wmi_handle: WMI handle 13467 * @param evt_buf: Pointer to event buffer 13468 * @param param: Pointer to hold data 13469 * 13470 * Return : QDF_STATUS_SUCCESS for success or error code 13471 */ 13472 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 13473 uint8_t *evt_buf, 13474 struct wmi_host_pdev_utf_event *event) 13475 { 13476 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 13477 struct wmi_host_utf_seg_header_info *seg_hdr; 13478 13479 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 13480 event->data = param_buf->data; 13481 event->datalen = param_buf->num_data; 13482 13483 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 13484 wmi_err("Invalid datalen: %d", event->datalen); 13485 return QDF_STATUS_E_INVAL; 13486 } 13487 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 13488 /* Set pdev_id=1 until FW adds support to include pdev_id */ 13489 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13490 wmi_handle, 13491 seg_hdr->pdev_id); 13492 13493 return QDF_STATUS_SUCCESS; 13494 } 13495 13496 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13497 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13498 uint8_t *event, 13499 uint32_t *num_rf_characterization_entries) 13500 { 13501 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13502 13503 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13504 if (!param_buf) 13505 return QDF_STATUS_E_INVAL; 13506 13507 *num_rf_characterization_entries = 13508 param_buf->num_wmi_chan_rf_characterization_info; 13509 13510 return QDF_STATUS_SUCCESS; 13511 } 13512 13513 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13514 uint8_t *event, 13515 uint32_t num_rf_characterization_entries, 13516 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 13517 { 13518 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13519 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 13520 uint8_t ix; 13521 13522 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13523 if (!param_buf) 13524 return QDF_STATUS_E_INVAL; 13525 13526 wmi_rf_characterization_entry = 13527 param_buf->wmi_chan_rf_characterization_info; 13528 if (!wmi_rf_characterization_entry) 13529 return QDF_STATUS_E_INVAL; 13530 13531 /* 13532 * Using num_wmi_chan_rf_characterization instead of param_buf value 13533 * since memory for rf_characterization_entries was allocated using 13534 * the former. 13535 */ 13536 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 13537 rf_characterization_entries[ix].freq = 13538 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 13539 &wmi_rf_characterization_entry[ix]); 13540 13541 rf_characterization_entries[ix].bw = 13542 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 13543 &wmi_rf_characterization_entry[ix]); 13544 13545 rf_characterization_entries[ix].chan_metric = 13546 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 13547 &wmi_rf_characterization_entry[ix]); 13548 13549 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 13550 "bw: %u, chan_metric: %u", 13551 ix, rf_characterization_entries[ix].freq, 13552 rf_characterization_entries[ix].bw, 13553 rf_characterization_entries[ix].chan_metric); 13554 } 13555 13556 return QDF_STATUS_SUCCESS; 13557 } 13558 #endif 13559 13560 #ifdef WLAN_FEATURE_11BE 13561 static void 13562 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13563 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13564 { 13565 cap->supports_chan_width_320 = 13566 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 13567 } 13568 #else 13569 static void 13570 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13571 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13572 { 13573 } 13574 #endif /* WLAN_FEATURE_11BE */ 13575 13576 /** 13577 * extract_chainmask_tables_tlv() - extract chain mask tables from event 13578 * @wmi_handle: wmi handle 13579 * @param evt_buf: pointer to event buffer 13580 * @param param: Pointer to hold evt buf 13581 * 13582 * Return: QDF_STATUS_SUCCESS for success or error code 13583 */ 13584 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 13585 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 13586 { 13587 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13588 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 13589 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13590 uint8_t i = 0, j = 0; 13591 uint32_t num_mac_phy_chainmask_caps = 0; 13592 13593 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13594 if (!param_buf) 13595 return QDF_STATUS_E_INVAL; 13596 13597 hw_caps = param_buf->soc_hw_mode_caps; 13598 if (!hw_caps) 13599 return QDF_STATUS_E_INVAL; 13600 13601 if ((!hw_caps->num_chainmask_tables) || 13602 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 13603 (hw_caps->num_chainmask_tables > 13604 param_buf->num_mac_phy_chainmask_combo)) 13605 return QDF_STATUS_E_INVAL; 13606 13607 chainmask_caps = param_buf->mac_phy_chainmask_caps; 13608 13609 if (!chainmask_caps) 13610 return QDF_STATUS_E_INVAL; 13611 13612 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13613 if (chainmask_table[i].num_valid_chainmasks > 13614 (UINT_MAX - num_mac_phy_chainmask_caps)) { 13615 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 13616 num_mac_phy_chainmask_caps, i, 13617 chainmask_table[i].num_valid_chainmasks); 13618 return QDF_STATUS_E_INVAL; 13619 } 13620 num_mac_phy_chainmask_caps += 13621 chainmask_table[i].num_valid_chainmasks; 13622 } 13623 13624 if (num_mac_phy_chainmask_caps > 13625 param_buf->num_mac_phy_chainmask_caps) { 13626 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 13627 num_mac_phy_chainmask_caps, 13628 param_buf->num_mac_phy_chainmask_caps); 13629 return QDF_STATUS_E_INVAL; 13630 } 13631 13632 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13633 13634 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 13635 i); 13636 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 13637 13638 chainmask_table[i].cap_list[j].chainmask = 13639 chainmask_caps->chainmask; 13640 13641 chainmask_table[i].cap_list[j].supports_chan_width_20 = 13642 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 13643 13644 chainmask_table[i].cap_list[j].supports_chan_width_40 = 13645 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 13646 13647 chainmask_table[i].cap_list[j].supports_chan_width_80 = 13648 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 13649 13650 chainmask_table[i].cap_list[j].supports_chan_width_160 = 13651 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 13652 13653 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 13654 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 13655 13656 chainmask_table[i].cap_list[j].chain_mask_2G = 13657 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 13658 13659 chainmask_table[i].cap_list[j].chain_mask_5G = 13660 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 13661 13662 chainmask_table[i].cap_list[j].chain_mask_tx = 13663 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 13664 13665 chainmask_table[i].cap_list[j].chain_mask_rx = 13666 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 13667 13668 chainmask_table[i].cap_list[j].supports_aDFS = 13669 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 13670 13671 chainmask_table[i].cap_list[j].supports_aSpectral = 13672 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 13673 13674 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 13675 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 13676 13677 chainmask_table[i].cap_list[j].supports_aDFS_160 = 13678 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 13679 13680 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 13681 chainmask_caps); 13682 13683 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 13684 chainmask_caps->supported_flags, 13685 chainmask_caps->chainmask); 13686 chainmask_caps++; 13687 } 13688 } 13689 13690 return QDF_STATUS_SUCCESS; 13691 } 13692 13693 /** 13694 * extract_service_ready_ext_tlv() - extract basic extended service ready params 13695 * from event 13696 * @wmi_handle: wmi handle 13697 * @param evt_buf: pointer to event buffer 13698 * @param param: Pointer to hold evt buf 13699 * 13700 * Return: QDF_STATUS_SUCCESS for success or error code 13701 */ 13702 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 13703 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 13704 { 13705 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13706 wmi_service_ready_ext_event_fixed_param *ev; 13707 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13708 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13709 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 13710 uint8_t i = 0; 13711 13712 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13713 if (!param_buf) 13714 return QDF_STATUS_E_INVAL; 13715 13716 ev = param_buf->fixed_param; 13717 if (!ev) 13718 return QDF_STATUS_E_INVAL; 13719 13720 /* Move this to host based bitmap */ 13721 param->default_conc_scan_config_bits = 13722 ev->default_conc_scan_config_bits; 13723 param->default_fw_config_bits = ev->default_fw_config_bits; 13724 param->he_cap_info = ev->he_cap_info; 13725 param->mpdu_density = ev->mpdu_density; 13726 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 13727 param->fw_build_vers_ext = ev->fw_build_vers_ext; 13728 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13729 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 13730 param->max_bssid_indicator = ev->max_bssid_indicator; 13731 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 13732 13733 hw_caps = param_buf->soc_hw_mode_caps; 13734 if (hw_caps) 13735 param->num_hw_modes = hw_caps->num_hw_modes; 13736 else 13737 param->num_hw_modes = 0; 13738 13739 reg_caps = param_buf->soc_hal_reg_caps; 13740 if (reg_caps) 13741 param->num_phy = reg_caps->num_phy; 13742 else 13743 param->num_phy = 0; 13744 13745 if (hw_caps) { 13746 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 13747 wmi_nofl_debug("Num chain mask tables: %d", 13748 hw_caps->num_chainmask_tables); 13749 } else 13750 param->num_chainmask_tables = 0; 13751 13752 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 13753 param->num_chainmask_tables > 13754 param_buf->num_mac_phy_chainmask_combo) { 13755 wmi_err_rl("num_chainmask_tables is OOB: %u", 13756 param->num_chainmask_tables); 13757 return QDF_STATUS_E_INVAL; 13758 } 13759 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 13760 13761 if (!chain_mask_combo) 13762 return QDF_STATUS_SUCCESS; 13763 13764 wmi_nofl_debug("Dumping chain mask combo data"); 13765 13766 for (i = 0; i < param->num_chainmask_tables; i++) { 13767 13768 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 13769 chain_mask_combo->chainmask_table_id, 13770 chain_mask_combo->num_valid_chainmask); 13771 13772 param->chainmask_table[i].table_id = 13773 chain_mask_combo->chainmask_table_id; 13774 param->chainmask_table[i].num_valid_chainmasks = 13775 chain_mask_combo->num_valid_chainmask; 13776 chain_mask_combo++; 13777 } 13778 wmi_nofl_debug("chain mask combo end"); 13779 13780 return QDF_STATUS_SUCCESS; 13781 } 13782 13783 #if defined(CONFIG_AFC_SUPPORT) 13784 /** 13785 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 13786 * type from event 13787 * @ev: pointer to event fixed param 13788 * @param: Pointer to hold the params 13789 * 13790 * Return: void 13791 */ 13792 static void 13793 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 13794 struct wlan_psoc_host_service_ext2_param *param) 13795 { 13796 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 13797 enum reg_afc_dev_deploy_type reg_afc_dev_type; 13798 13799 tgt_afc_dev_type = ev->afc_deployment_type; 13800 switch (tgt_afc_dev_type) { 13801 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 13802 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 13803 break; 13804 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 13805 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 13806 break; 13807 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 13808 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 13809 break; 13810 default: 13811 wmi_err("invalid afc deloyment %d", tgt_afc_dev_type); 13812 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 13813 break; 13814 } 13815 param->afc_dev_type = reg_afc_dev_type; 13816 13817 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 13818 } 13819 #else 13820 static inline void 13821 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 13822 struct wlan_psoc_host_service_ext2_param *param) 13823 { 13824 } 13825 #endif 13826 13827 /** 13828 * extract_ul_mumimo_support) - extract UL-MUMIMO capability from target cap 13829 * @param: Pointer to hold the params 13830 * 13831 * Return: Void 13832 */ 13833 static void 13834 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 13835 { 13836 uint32_t tgt_cap = param->target_cap_flags; 13837 13838 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 13839 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 13840 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 13841 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 13842 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 13843 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 13844 } 13845 13846 /** 13847 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 13848 * event 13849 * @wmi_handle: wmi handle 13850 * @event: pointer to event buffer 13851 * @param: Pointer to hold the params 13852 * 13853 * Return: QDF_STATUS_SUCCESS for success or error code 13854 */ 13855 static QDF_STATUS 13856 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 13857 struct wlan_psoc_host_service_ext2_param *param) 13858 { 13859 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13860 wmi_service_ready_ext2_event_fixed_param *ev; 13861 13862 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13863 if (!param_buf) 13864 return QDF_STATUS_E_INVAL; 13865 13866 ev = param_buf->fixed_param; 13867 if (!ev) 13868 return QDF_STATUS_E_INVAL; 13869 13870 param->reg_db_version_major = 13871 WMI_REG_DB_VERSION_MAJOR_GET( 13872 ev->reg_db_version); 13873 param->reg_db_version_minor = 13874 WMI_REG_DB_VERSION_MINOR_GET( 13875 ev->reg_db_version); 13876 param->bdf_reg_db_version_major = 13877 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 13878 ev->reg_db_version); 13879 param->bdf_reg_db_version_minor = 13880 WMI_BDF_REG_DB_VERSION_MINOR_GET( 13881 ev->reg_db_version); 13882 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 13883 13884 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13885 13886 if (param_buf->nan_cap) 13887 param->max_ndp_sessions = 13888 param_buf->nan_cap->max_ndp_sessions; 13889 else 13890 param->max_ndp_sessions = 0; 13891 13892 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 13893 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 13894 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 13895 ev->max_user_per_ppdu_ofdma); 13896 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 13897 ev->max_user_per_ppdu_ofdma); 13898 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 13899 ev->max_user_per_ppdu_mumimo); 13900 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 13901 ev->max_user_per_ppdu_mumimo); 13902 param->target_cap_flags = ev->target_cap_flags; 13903 extract_ul_mumimo_support(param); 13904 wmi_debug("htt peer data :%d", ev->target_cap_flags); 13905 13906 extract_svc_rdy_ext2_afc_tlv(ev, param); 13907 13908 return QDF_STATUS_SUCCESS; 13909 } 13910 13911 /* 13912 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 13913 * service ready ext 2 13914 * 13915 * @wmi_handle: wmi handle 13916 * @event: pointer to event buffer 13917 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 13918 * it indicates async SBS mode is supported, and 13919 * lower-band/higher band to MAC mapping is 13920 * switch-able. unit: mhz. examples 5180, 5320 13921 * 13922 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 13923 */ 13924 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 13925 wmi_unified_t wmi_handle, uint8_t *event, 13926 uint32_t *sbs_lower_band_end_freq) 13927 { 13928 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13929 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 13930 13931 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13932 if (!param_buf) 13933 return QDF_STATUS_E_INVAL; 13934 13935 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 13936 if (!dbs_or_sbs_caps) 13937 return QDF_STATUS_E_INVAL; 13938 13939 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 13940 13941 return QDF_STATUS_SUCCESS; 13942 } 13943 13944 /** 13945 * extract_sar_cap_service_ready_ext_tlv() - 13946 * extract SAR cap from service ready event 13947 * @wmi_handle: wmi handle 13948 * @event: pointer to event buffer 13949 * @ext_param: extended target info 13950 * 13951 * Return: QDF_STATUS_SUCCESS for success or error code 13952 */ 13953 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 13954 wmi_unified_t wmi_handle, 13955 uint8_t *event, 13956 struct wlan_psoc_host_service_ext_param *ext_param) 13957 { 13958 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13959 WMI_SAR_CAPABILITIES *sar_caps; 13960 13961 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 13962 13963 if (!param_buf) 13964 return QDF_STATUS_E_INVAL; 13965 13966 sar_caps = param_buf->sar_caps; 13967 if (sar_caps) 13968 ext_param->sar_version = sar_caps->active_version; 13969 else 13970 ext_param->sar_version = 0; 13971 13972 return QDF_STATUS_SUCCESS; 13973 } 13974 13975 /** 13976 * extract_hw_mode_cap_service_ready_ext_tlv() - 13977 * extract HW mode cap from service ready event 13978 * @wmi_handle: wmi handle 13979 * @param evt_buf: pointer to event buffer 13980 * @param param: Pointer to hold evt buf 13981 * @param hw_mode_idx: hw mode idx should be less than num_mode 13982 * 13983 * Return: QDF_STATUS_SUCCESS for success or error code 13984 */ 13985 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 13986 wmi_unified_t wmi_handle, 13987 uint8_t *event, uint8_t hw_mode_idx, 13988 struct wlan_psoc_host_hw_mode_caps *param) 13989 { 13990 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13991 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13992 13993 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13994 if (!param_buf) 13995 return QDF_STATUS_E_INVAL; 13996 13997 hw_caps = param_buf->soc_hw_mode_caps; 13998 if (!hw_caps) 13999 return QDF_STATUS_E_INVAL; 14000 14001 if (!hw_caps->num_hw_modes || 14002 !param_buf->hw_mode_caps || 14003 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14004 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14005 return QDF_STATUS_E_INVAL; 14006 14007 if (hw_mode_idx >= hw_caps->num_hw_modes) 14008 return QDF_STATUS_E_INVAL; 14009 14010 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14011 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14012 14013 param->hw_mode_config_type = 14014 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14015 14016 return QDF_STATUS_SUCCESS; 14017 } 14018 14019 /** 14020 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 14021 * @param param: host mac phy capabilities 14022 * @param mac_phy_caps: mac phy capabilities 14023 * 14024 * Return: void 14025 */ 14026 #ifdef WLAN_FEATURE_11BE 14027 static void 14028 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14029 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14030 { 14031 param->supports_11be = 14032 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14033 14034 wmi_debug("11be support %d", param->supports_11be); 14035 } 14036 #else 14037 static void 14038 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14039 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14040 { 14041 } 14042 #endif 14043 14044 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14045 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14046 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14047 { 14048 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14049 } 14050 #else 14051 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14052 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14053 { 14054 } 14055 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14056 14057 /** 14058 * extract_mac_phy_cap_service_ready_ext_tlv() - 14059 * extract MAC phy cap from service ready event 14060 * @wmi_handle: wmi handle 14061 * @param evt_buf: pointer to event buffer 14062 * @param param: Pointer to hold evt buf 14063 * @param hw_mode_idx: hw mode idx should be less than num_mode 14064 * @param phy_id: phy id within hw_mode 14065 * 14066 * Return: QDF_STATUS_SUCCESS for success or error code 14067 */ 14068 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14069 wmi_unified_t wmi_handle, 14070 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14071 struct wlan_psoc_host_mac_phy_caps *param) 14072 { 14073 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14074 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14075 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14076 uint32_t phy_map; 14077 uint8_t hw_idx, phy_idx = 0, pdev_id; 14078 14079 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14080 if (!param_buf) 14081 return QDF_STATUS_E_INVAL; 14082 14083 hw_caps = param_buf->soc_hw_mode_caps; 14084 if (!hw_caps) 14085 return QDF_STATUS_E_INVAL; 14086 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14087 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14088 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14089 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14090 return QDF_STATUS_E_INVAL; 14091 } 14092 14093 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14094 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14095 break; 14096 14097 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14098 while (phy_map) { 14099 phy_map >>= 1; 14100 phy_idx++; 14101 } 14102 } 14103 14104 if (hw_idx == hw_caps->num_hw_modes) 14105 return QDF_STATUS_E_INVAL; 14106 14107 phy_idx += phy_id; 14108 if (phy_idx >= param_buf->num_mac_phy_caps) 14109 return QDF_STATUS_E_INVAL; 14110 14111 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14112 14113 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14114 param->phy_idx = phy_idx; 14115 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14116 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14117 wmi_handle, 14118 pdev_id); 14119 param->tgt_pdev_id = pdev_id; 14120 extract_hw_link_id(param, mac_phy_caps); 14121 param->phy_id = mac_phy_caps->phy_id; 14122 param->supports_11b = 14123 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14124 param->supports_11g = 14125 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14126 param->supports_11a = 14127 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14128 param->supports_11n = 14129 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14130 param->supports_11ac = 14131 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14132 param->supports_11ax = 14133 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14134 14135 extract_service_ready_11be_support(param, mac_phy_caps); 14136 14137 param->supported_bands = mac_phy_caps->supported_bands; 14138 param->ampdu_density = mac_phy_caps->ampdu_density; 14139 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14140 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14141 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 14142 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 14143 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 14144 mac_phy_caps->he_cap_info_2G; 14145 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 14146 mac_phy_caps->he_cap_info_2G_ext; 14147 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 14148 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 14149 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 14150 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 14151 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 14152 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 14153 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 14154 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 14155 mac_phy_caps->he_cap_info_5G; 14156 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 14157 mac_phy_caps->he_cap_info_5G_ext; 14158 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 14159 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 14160 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 14161 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 14162 qdf_mem_copy(¶m->he_cap_phy_info_2G, 14163 &mac_phy_caps->he_cap_phy_info_2G, 14164 sizeof(param->he_cap_phy_info_2G)); 14165 qdf_mem_copy(¶m->he_cap_phy_info_5G, 14166 &mac_phy_caps->he_cap_phy_info_5G, 14167 sizeof(param->he_cap_phy_info_5G)); 14168 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 14169 sizeof(param->he_ppet2G)); 14170 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 14171 sizeof(param->he_ppet5G)); 14172 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 14173 param->lmac_id = mac_phy_caps->lmac_id; 14174 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 14175 (mac_phy_caps->wireless_modes); 14176 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 14177 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 14178 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 14179 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 14180 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 14181 mac_phy_caps->nss_ratio); 14182 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 14183 14184 return QDF_STATUS_SUCCESS; 14185 } 14186 14187 #ifdef WLAN_FEATURE_11BE_MLO 14188 /** 14189 * extract_mac_phy_emlcap() - API to extract EML Capabilities 14190 * @param: host ext2 mac phy capabilities 14191 * @mac_phy_caps: ext mac phy capabilities 14192 * 14193 * Return: void 14194 */ 14195 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14196 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14197 { 14198 if (!param || !mac_phy_caps) 14199 return; 14200 14201 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 14202 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 14203 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 14204 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 14205 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 14206 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 14207 } 14208 14209 /** 14210 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 14211 * @param: host ext2 mac phy capabilities 14212 * @mac_phy_caps: ext mac phy capabilities 14213 * 14214 * Return: void 14215 */ 14216 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14217 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14218 { 14219 if (!param || !mac_phy_caps) 14220 return; 14221 14222 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 14223 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 14224 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 14225 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 14226 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 14227 } 14228 #else 14229 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14230 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14231 { 14232 } 14233 14234 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14235 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14236 { 14237 } 14238 #endif 14239 14240 /** 14241 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 14242 * @param param: host ext2 mac phy capabilities 14243 * @param mac_phy_caps: ext mac phy capabilities 14244 * 14245 * Return: void 14246 */ 14247 #ifdef WLAN_FEATURE_11BE 14248 static void extract_mac_phy_cap_ehtcaps( 14249 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14250 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14251 { 14252 uint32_t i; 14253 14254 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 14255 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 14256 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 14257 14258 qdf_mem_copy(¶m->eht_cap_info_2G, 14259 &mac_phy_caps->eht_cap_mac_info_2G, 14260 sizeof(param->eht_cap_info_2G)); 14261 qdf_mem_copy(¶m->eht_cap_info_5G, 14262 &mac_phy_caps->eht_cap_mac_info_5G, 14263 sizeof(param->eht_cap_info_5G)); 14264 14265 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 14266 &mac_phy_caps->eht_cap_phy_info_2G, 14267 sizeof(param->eht_cap_phy_info_2G)); 14268 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 14269 &mac_phy_caps->eht_cap_phy_info_5G, 14270 sizeof(param->eht_cap_phy_info_5G)); 14271 14272 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 14273 &mac_phy_caps->eht_supp_mcs_ext_2G, 14274 sizeof(param->eht_supp_mcs_ext_2G)); 14275 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 14276 &mac_phy_caps->eht_supp_mcs_ext_5G, 14277 sizeof(param->eht_supp_mcs_ext_5G)); 14278 14279 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 14280 sizeof(param->eht_ppet2G)); 14281 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 14282 sizeof(param->eht_ppet5G)); 14283 14284 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", 14285 mac_phy_caps->eht_cap_mac_info_2G[0], 14286 mac_phy_caps->eht_cap_mac_info_5G[0], 14287 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 14288 mac_phy_caps->eht_cap_info_internal); 14289 14290 wmi_nofl_debug("EHT phy caps: "); 14291 14292 wmi_nofl_debug("2G:"); 14293 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14294 wmi_nofl_debug("index %d value %x", 14295 i, param->eht_cap_phy_info_2G[i]); 14296 } 14297 wmi_nofl_debug("5G:"); 14298 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14299 wmi_nofl_debug("index %d value %x", 14300 i, param->eht_cap_phy_info_5G[i]); 14301 } 14302 wmi_nofl_debug("2G MCS ext Map:"); 14303 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 14304 wmi_nofl_debug("index %d value %x", 14305 i, param->eht_supp_mcs_ext_2G[i]); 14306 } 14307 wmi_nofl_debug("5G MCS ext Map:"); 14308 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 14309 wmi_nofl_debug("index %d value %x", 14310 i, param->eht_supp_mcs_ext_5G[i]); 14311 } 14312 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 14313 param->eht_ppet2G.numss_m1, 14314 param->eht_ppet2G.ru_bit_mask); 14315 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14316 wmi_nofl_debug("index %d value %x", 14317 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 14318 } 14319 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 14320 param->eht_ppet5G.numss_m1, 14321 param->eht_ppet5G.ru_bit_mask); 14322 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14323 wmi_nofl_debug("index %d value %x", 14324 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 14325 } 14326 } 14327 #else 14328 static void extract_mac_phy_cap_ehtcaps( 14329 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14330 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14331 { 14332 } 14333 #endif 14334 14335 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 14336 wmi_unified_t wmi_handle, 14337 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14338 uint8_t phy_idx, 14339 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 14340 { 14341 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14342 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 14343 14344 if (!event) { 14345 wmi_err("null evt_buf"); 14346 return QDF_STATUS_E_INVAL; 14347 } 14348 14349 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14350 14351 if (!param_buf->num_mac_phy_caps) 14352 return QDF_STATUS_SUCCESS; 14353 14354 if (phy_idx >= param_buf->num_mac_phy_caps) 14355 return QDF_STATUS_E_INVAL; 14356 14357 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14358 14359 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 14360 (phy_id != mac_phy_caps->phy_id)) 14361 return QDF_STATUS_E_INVAL; 14362 14363 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14364 param->phy_id = mac_phy_caps->phy_id; 14365 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14366 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 14367 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 14368 mac_phy_caps->wireless_modes_ext); 14369 14370 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 14371 extract_mac_phy_emlcap(param, mac_phy_caps); 14372 extract_mac_phy_mldcap(param, mac_phy_caps); 14373 14374 return QDF_STATUS_SUCCESS; 14375 } 14376 14377 /** 14378 * extract_reg_cap_service_ready_ext_tlv() - 14379 * extract REG cap from service ready event 14380 * @wmi_handle: wmi handle 14381 * @param evt_buf: pointer to event buffer 14382 * @param param: Pointer to hold evt buf 14383 * @param phy_idx: phy idx should be less than num_mode 14384 * 14385 * Return: QDF_STATUS_SUCCESS for success or error code 14386 */ 14387 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 14388 wmi_unified_t wmi_handle, 14389 uint8_t *event, uint8_t phy_idx, 14390 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 14391 { 14392 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14393 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14394 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 14395 14396 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14397 if (!param_buf) 14398 return QDF_STATUS_E_INVAL; 14399 14400 reg_caps = param_buf->soc_hal_reg_caps; 14401 if (!reg_caps) 14402 return QDF_STATUS_E_INVAL; 14403 14404 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 14405 return QDF_STATUS_E_INVAL; 14406 14407 if (phy_idx >= reg_caps->num_phy) 14408 return QDF_STATUS_E_INVAL; 14409 14410 if (!param_buf->hal_reg_caps) 14411 return QDF_STATUS_E_INVAL; 14412 14413 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 14414 14415 param->phy_id = ext_reg_cap->phy_id; 14416 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 14417 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 14418 param->regcap1 = ext_reg_cap->regcap1; 14419 param->regcap2 = ext_reg_cap->regcap2; 14420 param->wireless_modes = convert_wireless_modes_tlv( 14421 ext_reg_cap->wireless_modes); 14422 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 14423 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 14424 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 14425 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 14426 14427 return QDF_STATUS_SUCCESS; 14428 } 14429 14430 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 14431 uint8_t num_dma_ring_caps) 14432 { 14433 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 14434 if (!num_dma_ring_caps) { 14435 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 14436 return QDF_STATUS_E_INVAL; 14437 } 14438 if (idx >= num_dma_ring_caps) { 14439 wmi_err("Index %d exceeds range", idx); 14440 return QDF_STATUS_E_INVAL; 14441 } 14442 return QDF_STATUS_SUCCESS; 14443 } 14444 14445 static void 14446 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 14447 struct wlan_psoc_host_dbr_ring_caps *param, 14448 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 14449 { 14450 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 14451 wmi_handle, 14452 dbr_ring_caps->pdev_id); 14453 param->mod_id = dbr_ring_caps->mod_id; 14454 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 14455 param->min_buf_size = dbr_ring_caps->min_buf_size; 14456 param->min_buf_align = dbr_ring_caps->min_buf_align; 14457 } 14458 14459 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 14460 wmi_unified_t wmi_handle, 14461 uint8_t *event, uint8_t idx, 14462 struct wlan_psoc_host_dbr_ring_caps *param) 14463 { 14464 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14465 QDF_STATUS status; 14466 14467 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14468 if (!param_buf) 14469 return QDF_STATUS_E_INVAL; 14470 14471 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14472 if (status != QDF_STATUS_SUCCESS) 14473 return status; 14474 14475 populate_dbr_ring_cap_elems(wmi_handle, param, 14476 ¶m_buf->dma_ring_caps[idx]); 14477 return QDF_STATUS_SUCCESS; 14478 } 14479 14480 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 14481 wmi_unified_t wmi_handle, 14482 uint8_t *event, uint8_t idx, 14483 struct wlan_psoc_host_dbr_ring_caps *param) 14484 { 14485 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14486 QDF_STATUS status; 14487 14488 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14489 if (!param_buf) 14490 return QDF_STATUS_E_INVAL; 14491 14492 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14493 if (status != QDF_STATUS_SUCCESS) 14494 return status; 14495 14496 populate_dbr_ring_cap_elems(wmi_handle, param, 14497 ¶m_buf->dma_ring_caps[idx]); 14498 return QDF_STATUS_SUCCESS; 14499 } 14500 14501 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 14502 wmi_unified_t wmi_handle, 14503 uint8_t *event, uint8_t idx, 14504 struct wlan_psoc_host_scan_radio_caps *param) 14505 { 14506 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14507 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 14508 14509 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14510 if (!param_buf) 14511 return QDF_STATUS_E_INVAL; 14512 14513 if (idx >= param_buf->num_wmi_scan_radio_caps) 14514 return QDF_STATUS_E_INVAL; 14515 14516 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 14517 param->phy_id = scan_radio_caps->phy_id; 14518 param->scan_radio_supported = 14519 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 14520 param->dfs_en = 14521 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 14522 14523 return QDF_STATUS_SUCCESS; 14524 } 14525 14526 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 14527 uint8_t *event, 14528 struct wmi_host_sw_cal_ver *cal) 14529 { 14530 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14531 wmi_sw_cal_ver_cap *fw_cap; 14532 14533 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14534 if (!param_buf) 14535 return QDF_STATUS_E_INVAL; 14536 14537 fw_cap = param_buf->sw_cal_ver_cap; 14538 if (!fw_cap) 14539 return QDF_STATUS_E_INVAL; 14540 14541 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 14542 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 14543 cal->status = fw_cap->status; 14544 14545 return QDF_STATUS_SUCCESS; 14546 } 14547 14548 /** 14549 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 14550 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 14551 * 14552 * Return: host thermal throt level 14553 */ 14554 static enum thermal_throttle_level 14555 wmi_tgt_thermal_level_to_host(uint32_t level) 14556 { 14557 switch (level) { 14558 case WMI_THERMAL_FULLPERF: 14559 return THERMAL_FULLPERF; 14560 case WMI_THERMAL_MITIGATION: 14561 return THERMAL_MITIGATION; 14562 case WMI_THERMAL_SHUTOFF: 14563 return THERMAL_SHUTOFF; 14564 case WMI_THERMAL_SHUTDOWN_TGT: 14565 return THERMAL_SHUTDOWN_TARGET; 14566 default: 14567 return THERMAL_UNKNOWN; 14568 } 14569 } 14570 14571 #ifdef THERMAL_STATS_SUPPORT 14572 static void 14573 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14574 uint32_t *therm_throt_levels, 14575 struct thermal_throt_level_stats *tt_temp_range_stats) 14576 { 14577 uint8_t lvl_idx; 14578 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14579 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 14580 14581 tt_stats_event = param_buf->fixed_param; 14582 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 14583 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 14584 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 14585 tt_stats_event->therm_throt_levels; 14586 14587 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 14588 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 14589 *therm_throt_levels, 14590 param_buf->num_temp_range_stats); 14591 return; 14592 } 14593 14594 wmi_tt_stats = param_buf->temp_range_stats; 14595 if (!wmi_tt_stats) { 14596 wmi_err("wmi_tt_stats Null"); 14597 return; 14598 } 14599 14600 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 14601 tt_temp_range_stats[lvl_idx].start_temp_level = 14602 wmi_tt_stats[lvl_idx].start_temp_level; 14603 tt_temp_range_stats[lvl_idx].end_temp_level = 14604 wmi_tt_stats[lvl_idx].end_temp_level; 14605 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 14606 wmi_tt_stats[lvl_idx].total_time_ms_lo; 14607 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 14608 wmi_tt_stats[lvl_idx].total_time_ms_hi; 14609 tt_temp_range_stats[lvl_idx].num_entry = 14610 wmi_tt_stats[lvl_idx].num_entry; 14611 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 14612 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 14613 wmi_tt_stats[lvl_idx].end_temp_level, 14614 wmi_tt_stats[lvl_idx].total_time_ms_lo, 14615 wmi_tt_stats[lvl_idx].total_time_ms_hi, 14616 wmi_tt_stats[lvl_idx].num_entry); 14617 } 14618 } 14619 #else 14620 static void 14621 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14622 uint32_t *therm_throt_levels, 14623 struct thermal_throt_level_stats *tt_temp_range_stats) 14624 { 14625 } 14626 #endif 14627 14628 /** 14629 * extract_thermal_stats_tlv() - extract thermal stats from event 14630 * @wmi_handle: wmi handle 14631 * @param evt_buf: Pointer to event buffer 14632 * @param temp: Pointer to hold extracted temperature 14633 * @param level: Pointer to hold extracted level in host enum 14634 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 14635 * range 14636 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 14637 * every level 14638 * 14639 * Return: 0 for success or error code 14640 */ 14641 static QDF_STATUS 14642 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 14643 void *evt_buf, uint32_t *temp, 14644 enum thermal_throttle_level *level, 14645 uint32_t *therm_throt_levels, 14646 struct thermal_throt_level_stats *tt_temp_range_stats_event, 14647 uint32_t *pdev_id) 14648 { 14649 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14650 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14651 14652 param_buf = 14653 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14654 if (!param_buf) 14655 return QDF_STATUS_E_INVAL; 14656 14657 tt_stats_event = param_buf->fixed_param; 14658 wmi_debug("thermal temperature %d level %d", 14659 tt_stats_event->temp, tt_stats_event->level); 14660 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14661 wmi_handle, 14662 tt_stats_event->pdev_id); 14663 *temp = tt_stats_event->temp; 14664 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 14665 14666 if (tt_stats_event->therm_throt_levels) 14667 populate_thermal_stats(param_buf, therm_throt_levels, 14668 tt_temp_range_stats_event); 14669 14670 return QDF_STATUS_SUCCESS; 14671 } 14672 14673 /** 14674 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 14675 * @wmi_handle: wmi handle 14676 * @param evt_buf: pointer to event buffer 14677 * @param idx: Index to level stats 14678 * @param levelcount: Pointer to hold levelcount 14679 * @param dccount: Pointer to hold dccount 14680 * 14681 * Return: 0 for success or error code 14682 */ 14683 static QDF_STATUS 14684 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 14685 void *evt_buf, uint8_t idx, uint32_t *levelcount, 14686 uint32_t *dccount) 14687 { 14688 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14689 wmi_therm_throt_level_stats_info *tt_level_info; 14690 14691 param_buf = 14692 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14693 if (!param_buf) 14694 return QDF_STATUS_E_INVAL; 14695 14696 tt_level_info = param_buf->therm_throt_level_stats_info; 14697 14698 if (idx < THERMAL_LEVELS) { 14699 *levelcount = tt_level_info[idx].level_count; 14700 *dccount = tt_level_info[idx].dc_count; 14701 return QDF_STATUS_SUCCESS; 14702 } 14703 14704 return QDF_STATUS_E_FAILURE; 14705 } 14706 #ifdef BIG_ENDIAN_HOST 14707 /** 14708 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14709 * @param data_len - data length 14710 * @param data - pointer to data 14711 * 14712 * Return: QDF_STATUS - success or error status 14713 */ 14714 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14715 { 14716 uint8_t *data_aligned = NULL; 14717 int c; 14718 unsigned char *data_unaligned; 14719 14720 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 14721 FIPS_ALIGN)); 14722 /* Assigning unaligned space to copy the data */ 14723 /* Checking if kmalloc does successful allocation */ 14724 if (!data_unaligned) 14725 return QDF_STATUS_E_FAILURE; 14726 14727 /* Checking if space is alligned */ 14728 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 14729 /* align the data space */ 14730 data_aligned = 14731 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 14732 } else { 14733 data_aligned = (u_int8_t *)data_unaligned; 14734 } 14735 14736 /* memset and copy content from data to data aligned */ 14737 OS_MEMSET(data_aligned, 0, data_len); 14738 OS_MEMCPY(data_aligned, data, data_len); 14739 /* Endianness to LE */ 14740 for (c = 0; c < data_len/4; c++) { 14741 *((u_int32_t *)data_aligned + c) = 14742 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 14743 } 14744 14745 /* Copy content to event->data */ 14746 OS_MEMCPY(data, data_aligned, data_len); 14747 14748 /* clean up allocated space */ 14749 qdf_mem_free(data_unaligned); 14750 data_aligned = NULL; 14751 data_unaligned = NULL; 14752 14753 /*************************************************************/ 14754 14755 return QDF_STATUS_SUCCESS; 14756 } 14757 #else 14758 /** 14759 * fips_conv_data_be() - DUMMY for LE platform 14760 * 14761 * Return: QDF_STATUS - success 14762 */ 14763 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14764 { 14765 return QDF_STATUS_SUCCESS; 14766 } 14767 #endif 14768 14769 /** 14770 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 14771 * @wmi_handle - wmi handle 14772 * @params - PN request params for peer 14773 * 14774 * Return: QDF_STATUS - success or error status 14775 */ 14776 static QDF_STATUS 14777 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 14778 struct peer_request_pn_param *params) 14779 { 14780 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 14781 wmi_buf_t buf; 14782 uint8_t *buf_ptr; 14783 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 14784 14785 buf = wmi_buf_alloc(wmi_handle, len); 14786 if (!buf) { 14787 wmi_err("wmi_buf_alloc failed"); 14788 return QDF_STATUS_E_FAILURE; 14789 } 14790 14791 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14792 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 14793 14794 WMITLV_SET_HDR(&cmd->tlv_header, 14795 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 14796 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 14797 14798 cmd->vdev_id = params->vdev_id; 14799 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14800 cmd->key_type = params->key_type; 14801 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14802 WMI_PEER_TX_PN_REQUEST_CMDID)) { 14803 wmi_err("Failed to send WMI command"); 14804 wmi_buf_free(buf); 14805 return QDF_STATUS_E_FAILURE; 14806 } 14807 return QDF_STATUS_SUCCESS; 14808 } 14809 14810 /** 14811 * extract_get_pn_data_tlv() - extract pn resp 14812 * @wmi_handle - wmi handle 14813 * @params - PN response params for peer 14814 * 14815 * Return: QDF_STATUS - success or error status 14816 */ 14817 static QDF_STATUS 14818 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14819 struct wmi_host_get_pn_event *param) 14820 { 14821 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14822 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 14823 14824 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 14825 event = 14826 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 14827 14828 param->vdev_id = event->vdev_id; 14829 param->key_type = event->key_type; 14830 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 14831 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 14832 14833 return QDF_STATUS_SUCCESS; 14834 } 14835 14836 /** 14837 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 14838 * @wmi_handle: wmi handle 14839 * @params: Rx PN request params for peer 14840 * 14841 * Return: QDF_STATUS - success or error status 14842 */ 14843 static QDF_STATUS 14844 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 14845 struct peer_request_rxpn_param *params) 14846 { 14847 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 14848 wmi_buf_t buf; 14849 uint8_t *buf_ptr; 14850 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 14851 14852 if (!is_service_enabled_tlv(wmi_handle, 14853 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 14854 wmi_err("Rx PN Replay Check not supported by target"); 14855 return QDF_STATUS_E_NOSUPPORT; 14856 } 14857 14858 buf = wmi_buf_alloc(wmi_handle, len); 14859 if (!buf) { 14860 wmi_err("wmi_buf_alloc failed"); 14861 return QDF_STATUS_E_FAILURE; 14862 } 14863 14864 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14865 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 14866 14867 WMITLV_SET_HDR(&cmd->tlv_header, 14868 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 14869 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 14870 14871 cmd->vdev_id = params->vdev_id; 14872 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14873 cmd->key_ix = params->keyix; 14874 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14875 WMI_PEER_RX_PN_REQUEST_CMDID)) { 14876 wmi_err("Failed to send WMI command"); 14877 wmi_buf_free(buf); 14878 return QDF_STATUS_E_FAILURE; 14879 } 14880 return QDF_STATUS_SUCCESS; 14881 } 14882 14883 /** 14884 * extract_get_rxpn_data_tlv() - extract Rx PN resp 14885 * @wmi_handle: wmi handle 14886 * @params: Rx PN response params for peer 14887 * 14888 * Return: QDF_STATUS - success or error status 14889 */ 14890 static QDF_STATUS 14891 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14892 struct wmi_host_get_rxpn_event *params) 14893 { 14894 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14895 wmi_peer_rx_pn_response_event_fixed_param *event; 14896 14897 param_buf = evt_buf; 14898 event = param_buf->fixed_param; 14899 14900 params->vdev_id = event->vdev_id; 14901 params->keyix = event->key_idx; 14902 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 14903 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 14904 14905 return QDF_STATUS_SUCCESS; 14906 } 14907 14908 /** 14909 * extract_fips_event_data_tlv() - extract fips event data 14910 * @wmi_handle: wmi handle 14911 * @param evt_buf: pointer to event buffer 14912 * @param param: pointer FIPS event params 14913 * 14914 * Return: 0 for success or error code 14915 */ 14916 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 14917 void *evt_buf, struct wmi_host_fips_event_param *param) 14918 { 14919 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 14920 wmi_pdev_fips_event_fixed_param *event; 14921 14922 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 14923 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 14924 14925 if (event->data_len > param_buf->num_data) 14926 return QDF_STATUS_E_FAILURE; 14927 14928 if (fips_conv_data_be(event->data_len, param_buf->data) != 14929 QDF_STATUS_SUCCESS) 14930 return QDF_STATUS_E_FAILURE; 14931 14932 param->data = (uint32_t *)param_buf->data; 14933 param->data_len = event->data_len; 14934 param->error_status = event->error_status; 14935 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14936 wmi_handle, 14937 event->pdev_id); 14938 14939 return QDF_STATUS_SUCCESS; 14940 } 14941 14942 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 14943 /** 14944 * extract_fips_extend_event_data_tlv() - extract fips event data 14945 * @wmi_handle: wmi handle 14946 * @param evt_buf: pointer to event buffer 14947 * @param param: pointer FIPS event params 14948 * 14949 * Return: 0 for success or error code 14950 */ 14951 static QDF_STATUS 14952 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 14953 void *evt_buf, 14954 struct wmi_host_fips_extend_event_param 14955 *param) 14956 { 14957 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 14958 wmi_pdev_fips_extend_event_fixed_param *event; 14959 14960 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 14961 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 14962 14963 if (fips_conv_data_be(event->data_len, param_buf->data) != 14964 QDF_STATUS_SUCCESS) 14965 return QDF_STATUS_E_FAILURE; 14966 14967 param->data = (uint32_t *)param_buf->data; 14968 param->data_len = event->data_len; 14969 param->error_status = event->error_status; 14970 param->fips_cookie = event->fips_cookie; 14971 param->cmd_frag_idx = event->cmd_frag_idx; 14972 param->more_bit = event->more_bit; 14973 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14974 wmi_handle, 14975 event->pdev_id); 14976 14977 return QDF_STATUS_SUCCESS; 14978 } 14979 #endif 14980 14981 #ifdef WLAN_FEATURE_DISA 14982 /** 14983 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 14984 * params from event 14985 * @wmi_handle: wmi handle 14986 * @evt_buf: pointer to event buffer 14987 * @resp: Pointer to hold resp parameters 14988 * 14989 * Return: QDF_STATUS_SUCCESS for success or error code 14990 */ 14991 static QDF_STATUS 14992 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 14993 void *evt_buf, 14994 struct disa_encrypt_decrypt_resp_params 14995 *resp) 14996 { 14997 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 14998 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 14999 15000 param_buf = evt_buf; 15001 if (!param_buf) { 15002 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15003 return QDF_STATUS_E_INVAL; 15004 } 15005 15006 data_event = param_buf->fixed_param; 15007 15008 resp->vdev_id = data_event->vdev_id; 15009 resp->status = data_event->status; 15010 15011 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15012 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15013 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15014 wmi_err("FW msg data_len %d more than TLV hdr %d", 15015 data_event->data_length, 15016 param_buf->num_enc80211_frame); 15017 return QDF_STATUS_E_INVAL; 15018 } 15019 15020 resp->data_len = data_event->data_length; 15021 15022 if (resp->data_len) 15023 resp->data = (uint8_t *)param_buf->enc80211_frame; 15024 15025 return QDF_STATUS_SUCCESS; 15026 } 15027 #endif /* WLAN_FEATURE_DISA */ 15028 15029 static bool is_management_record_tlv(uint32_t cmd_id) 15030 { 15031 switch (cmd_id) { 15032 case WMI_MGMT_TX_SEND_CMDID: 15033 case WMI_MGMT_TX_COMPLETION_EVENTID: 15034 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15035 case WMI_MGMT_RX_EVENTID: 15036 return true; 15037 default: 15038 return false; 15039 } 15040 } 15041 15042 static bool is_diag_event_tlv(uint32_t event_id) 15043 { 15044 if (WMI_DIAG_EVENTID == event_id) 15045 return true; 15046 15047 return false; 15048 } 15049 15050 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 15051 { 15052 uint16_t tag = 0; 15053 15054 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 15055 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 15056 __func__); 15057 return tag; 15058 } 15059 15060 if (wmi_handle->tag_crash_inject) 15061 tag = HTC_TX_PACKET_TAG_AUTO_PM; 15062 15063 wmi_handle->tag_crash_inject = false; 15064 return tag; 15065 } 15066 15067 /** 15068 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 15069 * @wmi_handle: WMI handle 15070 * @buf: WMI buffer 15071 * @cmd_id: WMI command Id 15072 * 15073 * Return htc_tx_tag 15074 */ 15075 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 15076 wmi_buf_t buf, 15077 uint32_t cmd_id) 15078 { 15079 uint16_t htc_tx_tag = 0; 15080 15081 switch (cmd_id) { 15082 case WMI_WOW_ENABLE_CMDID: 15083 case WMI_PDEV_SUSPEND_CMDID: 15084 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 15085 case WMI_PDEV_RESUME_CMDID: 15086 case WMI_HB_SET_ENABLE_CMDID: 15087 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 15088 #ifdef FEATURE_WLAN_D0WOW 15089 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 15090 #endif 15091 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 15092 break; 15093 case WMI_FORCE_FW_HANG_CMDID: 15094 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 15095 break; 15096 default: 15097 break; 15098 } 15099 15100 return htc_tx_tag; 15101 } 15102 15103 #ifdef CONFIG_BAND_6GHZ 15104 #ifdef CONFIG_REG_CLIENT 15105 /** 15106 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 15107 * @num_fcc_rules: Number of FCC rules 15108 * @wmi_fcc_rule: WMI FCC rules TLV 15109 * 15110 * Return fcc_rule_ptr 15111 */ 15112 static struct cur_fcc_rule 15113 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 15114 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 15115 { 15116 struct cur_fcc_rule *fcc_rule_ptr; 15117 uint32_t count; 15118 15119 if (!wmi_fcc_rule) 15120 return NULL; 15121 15122 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 15123 sizeof(*fcc_rule_ptr)); 15124 if (!fcc_rule_ptr) 15125 return NULL; 15126 15127 for (count = 0; count < num_fcc_rules; count++) { 15128 fcc_rule_ptr[count].center_freq = 15129 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 15130 wmi_fcc_rule[count].freq_info); 15131 fcc_rule_ptr[count].tx_power = 15132 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 15133 wmi_fcc_rule[count].freq_info); 15134 } 15135 15136 return fcc_rule_ptr; 15137 } 15138 #endif 15139 15140 static struct cur_reg_rule 15141 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 15142 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 15143 { 15144 struct cur_reg_rule *reg_rule_ptr; 15145 uint32_t count; 15146 15147 if (!num_reg_rules) 15148 return NULL; 15149 15150 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15151 sizeof(*reg_rule_ptr)); 15152 15153 if (!reg_rule_ptr) 15154 return NULL; 15155 15156 for (count = 0; count < num_reg_rules; count++) { 15157 reg_rule_ptr[count].start_freq = 15158 WMI_REG_RULE_START_FREQ_GET( 15159 wmi_reg_rule[count].freq_info); 15160 reg_rule_ptr[count].end_freq = 15161 WMI_REG_RULE_END_FREQ_GET( 15162 wmi_reg_rule[count].freq_info); 15163 reg_rule_ptr[count].max_bw = 15164 WMI_REG_RULE_MAX_BW_GET( 15165 wmi_reg_rule[count].bw_pwr_info); 15166 reg_rule_ptr[count].reg_power = 15167 WMI_REG_RULE_REG_POWER_GET( 15168 wmi_reg_rule[count].bw_pwr_info); 15169 reg_rule_ptr[count].ant_gain = 15170 WMI_REG_RULE_ANTENNA_GAIN_GET( 15171 wmi_reg_rule[count].bw_pwr_info); 15172 reg_rule_ptr[count].flags = 15173 WMI_REG_RULE_FLAGS_GET( 15174 wmi_reg_rule[count].flag_info); 15175 reg_rule_ptr[count].psd_flag = 15176 WMI_REG_RULE_PSD_FLAG_GET( 15177 wmi_reg_rule[count].psd_power_info); 15178 reg_rule_ptr[count].psd_eirp = 15179 WMI_REG_RULE_PSD_EIRP_GET( 15180 wmi_reg_rule[count].psd_power_info); 15181 } 15182 15183 return reg_rule_ptr; 15184 } 15185 #endif 15186 15187 static struct cur_reg_rule 15188 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 15189 wmi_regulatory_rule_struct *wmi_reg_rule) 15190 { 15191 struct cur_reg_rule *reg_rule_ptr; 15192 uint32_t count; 15193 15194 if (!num_reg_rules) 15195 return NULL; 15196 15197 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15198 sizeof(*reg_rule_ptr)); 15199 15200 if (!reg_rule_ptr) 15201 return NULL; 15202 15203 for (count = 0; count < num_reg_rules; count++) { 15204 reg_rule_ptr[count].start_freq = 15205 WMI_REG_RULE_START_FREQ_GET( 15206 wmi_reg_rule[count].freq_info); 15207 reg_rule_ptr[count].end_freq = 15208 WMI_REG_RULE_END_FREQ_GET( 15209 wmi_reg_rule[count].freq_info); 15210 reg_rule_ptr[count].max_bw = 15211 WMI_REG_RULE_MAX_BW_GET( 15212 wmi_reg_rule[count].bw_pwr_info); 15213 reg_rule_ptr[count].reg_power = 15214 WMI_REG_RULE_REG_POWER_GET( 15215 wmi_reg_rule[count].bw_pwr_info); 15216 reg_rule_ptr[count].ant_gain = 15217 WMI_REG_RULE_ANTENNA_GAIN_GET( 15218 wmi_reg_rule[count].bw_pwr_info); 15219 reg_rule_ptr[count].flags = 15220 WMI_REG_RULE_FLAGS_GET( 15221 wmi_reg_rule[count].flag_info); 15222 } 15223 15224 return reg_rule_ptr; 15225 } 15226 15227 static enum cc_setting_code wmi_reg_status_to_reg_status( 15228 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 15229 { 15230 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 15231 return REG_SET_CC_STATUS_PASS; 15232 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 15233 return REG_CURRENT_ALPHA2_NOT_FOUND; 15234 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 15235 return REG_INIT_ALPHA2_NOT_FOUND; 15236 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 15237 return REG_SET_CC_CHANGE_NOT_ALLOWED; 15238 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 15239 return REG_SET_CC_STATUS_NO_MEMORY; 15240 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 15241 return REG_SET_CC_STATUS_FAIL; 15242 15243 wmi_debug("Unknown reg status code from WMI"); 15244 return REG_SET_CC_STATUS_FAIL; 15245 } 15246 15247 #ifdef CONFIG_BAND_6GHZ 15248 15249 #ifdef CONFIG_REG_CLIENT 15250 #define MAX_NUM_FCC_RULES 2 15251 15252 /** 15253 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 15254 * @param_buf - Pointer to WMI params TLV 15255 * @ext_chan_list_event_hdr - Pointer to REG CHAN LIST CC EXT EVENT Fixed 15256 * Params TLV 15257 * @ext_wmi_reg_rule - Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 15258 * @ext_wmi_chan_priority - Pointer to REG CHAN LIST CC EXT EVENT Chan 15259 * Priority TLV 15260 * @evt_buf - Pointer to REG CHAN LIST CC EXT EVENT event buffer 15261 * @reg_info - Pointer to Regulatory Info 15262 * @len - Length of REG CHAN LIST CC EXT EVENT buffer 15263 * 15264 * Return - QDF_STATUS 15265 */ 15266 static QDF_STATUS extract_reg_fcc_rules_tlv( 15267 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15268 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15269 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15270 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15271 uint8_t *evt_buf, 15272 struct cur_regulatory_info *reg_info, 15273 uint32_t len) 15274 { 15275 int i; 15276 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 15277 15278 if (!param_buf) { 15279 wmi_err("invalid channel list event buf"); 15280 return QDF_STATUS_E_INVAL; 15281 } 15282 15283 reg_info->num_fcc_rules = 0; 15284 if (param_buf->reg_fcc_rule) { 15285 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 15286 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 15287 return QDF_STATUS_E_INVAL; 15288 } 15289 15290 ext_wmi_fcc_rule = 15291 (wmi_regulatory_fcc_rule_struct *) 15292 ((uint8_t *)ext_chan_list_event_hdr + 15293 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15294 WMI_TLV_HDR_SIZE + 15295 sizeof(wmi_regulatory_rule_ext_struct) * 15296 param_buf->num_reg_rule_array + 15297 WMI_TLV_HDR_SIZE + 15298 sizeof(wmi_regulatory_chan_priority_struct) * 15299 param_buf->num_reg_chan_priority + 15300 WMI_TLV_HDR_SIZE); 15301 15302 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 15303 param_buf->num_reg_fcc_rule, 15304 ext_wmi_fcc_rule); 15305 15306 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 15307 } 15308 15309 if (reg_info->fcc_rules_ptr) { 15310 for (i = 0; i < reg_info->num_fcc_rules; i++) { 15311 wmi_debug("FCC rule %d center_freq %d tx_power %d", 15312 i, reg_info->fcc_rules_ptr[i].center_freq, 15313 reg_info->fcc_rules_ptr[i].tx_power); 15314 } 15315 } 15316 return QDF_STATUS_SUCCESS; 15317 } 15318 #else 15319 static QDF_STATUS extract_reg_fcc_rules_tlv( 15320 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15321 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15322 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15323 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15324 uint8_t *evt_buf, 15325 struct cur_regulatory_info *reg_info, 15326 uint32_t len) 15327 { 15328 return QDF_STATUS_SUCCESS; 15329 } 15330 #endif 15331 15332 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 15333 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15334 struct cur_regulatory_info *reg_info, uint32_t len) 15335 { 15336 uint32_t i, j, k; 15337 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 15338 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 15339 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 15340 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 15341 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15342 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 15343 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 15344 uint32_t total_reg_rules = 0; 15345 QDF_STATUS status; 15346 15347 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 15348 if (!param_buf) { 15349 wmi_err("invalid channel list event buf"); 15350 return QDF_STATUS_E_FAILURE; 15351 } 15352 15353 ext_chan_list_event_hdr = param_buf->fixed_param; 15354 ext_wmi_chan_priority = param_buf->reg_chan_priority; 15355 15356 if (ext_wmi_chan_priority) 15357 reg_info->reg_6g_thresh_priority_freq = 15358 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 15359 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 15360 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 15361 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 15362 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 15363 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 15364 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 15365 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 15366 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 15367 15368 wmi_debug("num reg rules from fw"); 15369 wmi_debug("AP SP %d, LPI %d, VLP %d", 15370 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15371 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15372 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15373 15374 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15375 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 15376 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 15377 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 15378 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 15379 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 15380 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 15381 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 15382 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 15383 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 15384 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 15385 } 15386 15387 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15388 total_reg_rules += num_2g_reg_rules; 15389 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15390 total_reg_rules += num_5g_reg_rules; 15391 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15392 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 15393 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 15394 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 15395 num_6g_reg_rules_ap[i]); 15396 return QDF_STATUS_E_FAILURE; 15397 } 15398 total_reg_rules += num_6g_reg_rules_ap[i]; 15399 num_6g_reg_rules_client[i] = 15400 reg_info->num_6g_reg_rules_client[i]; 15401 } 15402 15403 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15404 total_reg_rules += 15405 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 15406 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 15407 total_reg_rules += 15408 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 15409 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 15410 MAX_6G_REG_RULES) || 15411 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 15412 MAX_6G_REG_RULES) || 15413 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 15414 MAX_6G_REG_RULES)) { 15415 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", 15416 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 15417 num_6g_reg_rules_client[REG_INDOOR_AP][i], 15418 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 15419 i); 15420 return QDF_STATUS_E_FAILURE; 15421 } 15422 } 15423 15424 if (total_reg_rules != param_buf->num_reg_rule_array) { 15425 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 15426 total_reg_rules, param_buf->num_reg_rule_array); 15427 return QDF_STATUS_E_FAILURE; 15428 } 15429 15430 if ((num_2g_reg_rules > MAX_REG_RULES) || 15431 (num_5g_reg_rules > MAX_REG_RULES)) { 15432 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15433 num_2g_reg_rules, num_5g_reg_rules); 15434 return QDF_STATUS_E_FAILURE; 15435 } 15436 15437 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 15438 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 15439 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 15440 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", 15441 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15442 num_6g_reg_rules_ap[REG_INDOOR_AP], 15443 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15444 return QDF_STATUS_E_FAILURE; 15445 } 15446 15447 if (param_buf->num_reg_rule_array > 15448 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 15449 sizeof(*ext_wmi_reg_rule)) { 15450 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 15451 param_buf->num_reg_rule_array); 15452 return QDF_STATUS_E_FAILURE; 15453 } 15454 15455 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 15456 REG_ALPHA2_LEN); 15457 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 15458 reg_info->phybitmap = convert_phybitmap_tlv( 15459 ext_chan_list_event_hdr->phybitmap); 15460 reg_info->offload_enabled = true; 15461 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 15462 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15463 wmi_handle, ext_chan_list_event_hdr->phy_id); 15464 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 15465 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 15466 15467 reg_info->status_code = 15468 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 15469 status_code); 15470 15471 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 15472 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 15473 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 15474 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 15475 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 15476 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 15477 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 15478 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 15479 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 15480 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 15481 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 15482 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 15483 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15484 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 15485 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15486 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 15487 15488 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15489 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15490 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 15491 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15492 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 15493 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 15494 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 15495 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 15496 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 15497 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15498 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 15499 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15500 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 15501 } 15502 15503 wmi_debug("num_phys = %u and phy_id = %u", 15504 reg_info->num_phy, reg_info->phy_id); 15505 15506 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 15507 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 15508 reg_info->max_bw_2g, reg_info->min_bw_5g, 15509 reg_info->max_bw_5g); 15510 15511 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", 15512 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 15513 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 15514 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 15515 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 15516 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 15517 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 15518 15519 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", 15520 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15521 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15522 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15523 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15524 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 15525 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15526 15527 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", 15528 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15529 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15530 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15531 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15532 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 15533 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15534 15535 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15536 num_2g_reg_rules, num_5g_reg_rules); 15537 15538 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 15539 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15540 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15541 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15542 15543 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", 15544 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15545 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15546 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15547 15548 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", 15549 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15550 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15551 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15552 15553 ext_wmi_reg_rule = 15554 (wmi_regulatory_rule_ext_struct *) 15555 ((uint8_t *)ext_chan_list_event_hdr + 15556 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15557 WMI_TLV_HDR_SIZE); 15558 reg_info->reg_rules_2g_ptr = 15559 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 15560 ext_wmi_reg_rule); 15561 ext_wmi_reg_rule += num_2g_reg_rules; 15562 for (i = 0; i < num_2g_reg_rules; i++) { 15563 if (!reg_info->reg_rules_2g_ptr) 15564 break; 15565 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 15566 i, reg_info->reg_rules_2g_ptr[i].start_freq, 15567 reg_info->reg_rules_2g_ptr[i].end_freq, 15568 reg_info->reg_rules_2g_ptr[i].flags); 15569 } 15570 reg_info->reg_rules_5g_ptr = 15571 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 15572 ext_wmi_reg_rule); 15573 ext_wmi_reg_rule += num_5g_reg_rules; 15574 for (i = 0; i < num_5g_reg_rules; i++) { 15575 if (!reg_info->reg_rules_5g_ptr) 15576 break; 15577 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 15578 i, reg_info->reg_rules_5g_ptr[i].start_freq, 15579 reg_info->reg_rules_5g_ptr[i].end_freq, 15580 reg_info->reg_rules_5g_ptr[i].flags); 15581 } 15582 15583 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15584 reg_info->reg_rules_6g_ap_ptr[i] = 15585 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 15586 ext_wmi_reg_rule); 15587 15588 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 15589 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 15590 if (!reg_info->reg_rules_6g_ap_ptr[i]) 15591 break; 15592 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 15593 i, j, 15594 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 15595 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 15596 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 15597 } 15598 } 15599 15600 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 15601 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15602 reg_info->reg_rules_6g_client_ptr[j][i] = 15603 create_ext_reg_rules_from_wmi( 15604 num_6g_reg_rules_client[j][i], 15605 ext_wmi_reg_rule); 15606 15607 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 15608 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 15609 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 15610 break; 15611 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 15612 j, i, k, 15613 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 15614 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 15615 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 15616 } 15617 } 15618 } 15619 15620 reg_info->client_type = ext_chan_list_event_hdr->client_type; 15621 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 15622 reg_info->unspecified_ap_usable = 15623 ext_chan_list_event_hdr->unspecified_ap_usable; 15624 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 15625 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 15626 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 15627 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 15628 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 15629 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 15630 15631 wmi_debug("client type %d", reg_info->client_type); 15632 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 15633 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 15634 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 15635 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 15636 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 15637 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 15638 15639 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15640 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 15641 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 15642 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 15643 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 15644 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 15645 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 15646 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 15647 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 15648 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 15649 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 15650 } 15651 15652 reg_info->domain_code_6g_super_id = 15653 ext_chan_list_event_hdr->domain_code_6g_super_id; 15654 15655 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 15656 ext_wmi_reg_rule, ext_wmi_chan_priority, 15657 evt_buf, reg_info, len); 15658 if (status != QDF_STATUS_SUCCESS) 15659 return status; 15660 15661 wmi_debug("processed regulatory extended channel list"); 15662 15663 return QDF_STATUS_SUCCESS; 15664 } 15665 15666 #ifdef CONFIG_AFC_SUPPORT 15667 /** 15668 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 15669 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 15670 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 15671 * an index pointer required to store the current index of 15672 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 15673 * @chan_eirp_info: pointer to chan_eirp_info 15674 * @num_chans: Number of channels 15675 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 15676 * @index: Pointer to index 15677 * 15678 * Return: void 15679 */ 15680 static void 15681 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 15682 uint8_t num_chans, 15683 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 15684 uint8_t *index) 15685 { 15686 uint8_t chan_idx; 15687 15688 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 15689 chan_eirp_info[chan_idx].cfi = 15690 chan_eirp_power_info_hdr[*index].channel_cfi; 15691 chan_eirp_info[chan_idx].eirp_power = 15692 chan_eirp_power_info_hdr[*index].eirp_pwr; 15693 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 15694 chan_idx, 15695 chan_eirp_info[chan_idx].cfi, 15696 chan_eirp_info[chan_idx].eirp_power); 15697 } 15698 } 15699 15700 /** 15701 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 15702 * to the internal buffer afc_chan_info. 15703 * @afc_chan_info: pointer to afc_chan_info 15704 * @num_chan_objs: Number of channel objects 15705 * @channel_info_hdr: Pointer to channel_info_hdr 15706 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 15707 * 15708 * Return: void 15709 */ 15710 static void 15711 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 15712 uint8_t num_chan_objs, 15713 wmi_6g_afc_channel_info *channel_info_hdr, 15714 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 15715 { 15716 uint8_t count; 15717 uint8_t src_pwr_index = 0; 15718 15719 for (count = 0; count < num_chan_objs; count++) { 15720 afc_chan_info[count].global_opclass = 15721 channel_info_hdr[count].global_operating_class; 15722 afc_chan_info[count].num_chans = 15723 channel_info_hdr[count].num_channels; 15724 wmi_debug("Chan object count = %d global opclasss = %d", 15725 count, 15726 afc_chan_info[count].global_opclass); 15727 wmi_debug("Number of Channel EIRP objects = %d", 15728 afc_chan_info[count].num_chans); 15729 15730 if (afc_chan_info[count].num_chans > 0) { 15731 struct chan_eirp_obj *chan_eirp_info; 15732 15733 chan_eirp_info = 15734 qdf_mem_malloc(afc_chan_info[count].num_chans * 15735 sizeof(*chan_eirp_info)); 15736 15737 if (!chan_eirp_info) 15738 return; 15739 15740 copy_afc_chan_eirp_info(chan_eirp_info, 15741 afc_chan_info[count].num_chans, 15742 chan_eirp_power_info_hdr, 15743 &src_pwr_index); 15744 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 15745 } else { 15746 wmi_err("Number of channels is zero in object idx %d", 15747 count); 15748 } 15749 } 15750 } 15751 15752 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 15753 uint8_t num_freq_objs, 15754 wmi_6g_afc_frequency_info *freq_info_hdr) 15755 { 15756 uint8_t count; 15757 15758 for (count = 0; count < num_freq_objs; count++) { 15759 afc_freq_info[count].low_freq = 15760 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 15761 afc_freq_info[count].high_freq = 15762 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 15763 afc_freq_info[count].max_psd = 15764 freq_info_hdr[count].psd_power_info; 15765 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 15766 count, 15767 afc_freq_info[count].low_freq, 15768 afc_freq_info[count].high_freq, 15769 afc_freq_info[count].max_psd); 15770 } 15771 } 15772 15773 /** 15774 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 15775 * the power event info from the WMI AFC event buffer to the internal buffer 15776 * power_info. 15777 * @power_info: pointer to power_info 15778 * @afc_power_event_hdr: pointer to afc_power_event_hdr 15779 * 15780 * Return: void 15781 */ 15782 static void 15783 copy_afc_event_fixed_hdr_power_info( 15784 struct reg_fw_afc_power_event *power_info, 15785 wmi_afc_power_event_param *afc_power_event_hdr) 15786 { 15787 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 15788 power_info->resp_id = afc_power_event_hdr->resp_id; 15789 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 15790 power_info->afc_wfa_version = 15791 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 15792 power_info->afc_wfa_version |= 15793 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 15794 15795 power_info->avail_exp_time_d = 15796 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 15797 power_info->avail_exp_time_d |= 15798 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 15799 power_info->avail_exp_time_d |= 15800 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 15801 15802 power_info->avail_exp_time_t = 15803 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 15804 power_info->avail_exp_time_t |= 15805 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 15806 power_info->avail_exp_time_t |= 15807 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 15808 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 15809 power_info->fw_status_code, 15810 power_info->resp_id, 15811 power_info->serv_resp_code); 15812 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 15813 power_info->afc_wfa_version, 15814 power_info->avail_exp_time_d, 15815 power_info->avail_exp_time_t); 15816 } 15817 15818 /** 15819 * copy_power_event() - Copy the power event parameters from the AFC event 15820 * buffer to the power_info within the afc_info. 15821 * @afc_info: pointer to afc_info 15822 * @param_buf: pointer to param_buf 15823 * 15824 * Return: void 15825 */ 15826 static void copy_power_event(struct afc_regulatory_info *afc_info, 15827 WMI_AFC_EVENTID_param_tlvs *param_buf) 15828 { 15829 struct reg_fw_afc_power_event *power_info; 15830 wmi_afc_power_event_param *afc_power_event_hdr; 15831 struct afc_freq_obj *afc_freq_info; 15832 15833 power_info = qdf_mem_malloc(sizeof(*power_info)); 15834 15835 if (!power_info) 15836 return; 15837 15838 afc_power_event_hdr = param_buf->afc_power_event_param; 15839 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 15840 afc_info->power_info = power_info; 15841 15842 power_info->num_freq_objs = param_buf->num_freq_info_array; 15843 wmi_debug("Number of frequency objects = %d", 15844 power_info->num_freq_objs); 15845 if (power_info->num_freq_objs > 0) { 15846 wmi_6g_afc_frequency_info *freq_info_hdr; 15847 15848 freq_info_hdr = param_buf->freq_info_array; 15849 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 15850 sizeof(*afc_freq_info)); 15851 15852 if (!afc_freq_info) 15853 return; 15854 15855 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 15856 freq_info_hdr); 15857 power_info->afc_freq_info = afc_freq_info; 15858 } else { 15859 wmi_err("Number of frequency objects is zero"); 15860 } 15861 15862 power_info->num_chan_objs = param_buf->num_channel_info_array; 15863 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 15864 if (power_info->num_chan_objs > 0) { 15865 struct afc_chan_obj *afc_chan_info; 15866 wmi_6g_afc_channel_info *channel_info_hdr; 15867 15868 channel_info_hdr = param_buf->channel_info_array; 15869 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 15870 sizeof(*afc_chan_info)); 15871 15872 if (!afc_chan_info) 15873 return; 15874 15875 copy_afc_chan_obj_info(afc_chan_info, 15876 power_info->num_chan_objs, 15877 channel_info_hdr, 15878 param_buf->chan_eirp_power_info_array); 15879 power_info->afc_chan_info = afc_chan_info; 15880 } else { 15881 wmi_err("Number of channel objects is zero"); 15882 } 15883 } 15884 15885 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 15886 WMI_AFC_EVENTID_param_tlvs *param_buf) 15887 { 15888 struct reg_afc_expiry_event *expiry_info; 15889 15890 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 15891 15892 if (!expiry_info) 15893 return; 15894 15895 expiry_info->request_id = 15896 param_buf->expiry_event_param->request_id; 15897 expiry_info->event_subtype = 15898 param_buf->expiry_event_param->event_subtype; 15899 wmi_debug("Event subtype %d request ID %d", 15900 expiry_info->event_subtype, 15901 expiry_info->request_id); 15902 afc_info->expiry_info = expiry_info; 15903 } 15904 15905 /** 15906 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 15907 * in the AFC event. 'Common' indicates that these parameters are common for 15908 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 15909 * @wmi_handle: wmi handle 15910 * @afc_info: pointer to afc_info 15911 * @event_fixed_hdr: pointer to event_fixed_hdr 15912 * 15913 * Return: void 15914 */ 15915 static void 15916 copy_afc_event_common_info(wmi_unified_t wmi_handle, 15917 struct afc_regulatory_info *afc_info, 15918 wmi_afc_event_fixed_param *event_fixed_hdr) 15919 { 15920 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15921 wmi_handle, event_fixed_hdr->phy_id); 15922 wmi_debug("phy_id %d", afc_info->phy_id); 15923 afc_info->event_type = event_fixed_hdr->event_type; 15924 } 15925 15926 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 15927 uint8_t *evt_buf, 15928 struct afc_regulatory_info *afc_info, 15929 uint32_t len) 15930 { 15931 WMI_AFC_EVENTID_param_tlvs *param_buf; 15932 wmi_afc_event_fixed_param *event_fixed_hdr; 15933 15934 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 15935 if (!param_buf) { 15936 wmi_err("Invalid AFC event buf"); 15937 return QDF_STATUS_E_FAILURE; 15938 } 15939 15940 event_fixed_hdr = param_buf->fixed_param; 15941 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 15942 wmi_debug("AFC event type %d received", afc_info->event_type); 15943 15944 switch (afc_info->event_type) { 15945 case WMI_AFC_EVENT_POWER_INFO: 15946 copy_power_event(afc_info, param_buf); 15947 break; 15948 case WMI_AFC_EVENT_TIMER_EXPIRY: 15949 copy_expiry_event(afc_info, param_buf); 15950 return QDF_STATUS_SUCCESS; 15951 default: 15952 wmi_err("Invalid event type"); 15953 return QDF_STATUS_E_FAILURE; 15954 } 15955 15956 return QDF_STATUS_SUCCESS; 15957 } 15958 #endif 15959 #endif 15960 15961 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 15962 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15963 struct cur_regulatory_info *reg_info, uint32_t len) 15964 { 15965 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 15966 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 15967 wmi_regulatory_rule_struct *wmi_reg_rule; 15968 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15969 15970 wmi_debug("processing regulatory channel list"); 15971 15972 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 15973 if (!param_buf) { 15974 wmi_err("invalid channel list event buf"); 15975 return QDF_STATUS_E_FAILURE; 15976 } 15977 15978 chan_list_event_hdr = param_buf->fixed_param; 15979 15980 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 15981 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 15982 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15983 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15984 if ((num_2g_reg_rules > MAX_REG_RULES) || 15985 (num_5g_reg_rules > MAX_REG_RULES) || 15986 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 15987 (num_2g_reg_rules + num_5g_reg_rules != 15988 param_buf->num_reg_rule_array)) { 15989 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15990 num_2g_reg_rules, num_5g_reg_rules); 15991 return QDF_STATUS_E_FAILURE; 15992 } 15993 if (param_buf->num_reg_rule_array > 15994 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 15995 sizeof(*wmi_reg_rule)) { 15996 wmi_err_rl("Invalid num_reg_rule_array: %u", 15997 param_buf->num_reg_rule_array); 15998 return QDF_STATUS_E_FAILURE; 15999 } 16000 16001 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 16002 REG_ALPHA2_LEN); 16003 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 16004 reg_info->phybitmap = convert_phybitmap_tlv( 16005 chan_list_event_hdr->phybitmap); 16006 reg_info->offload_enabled = true; 16007 reg_info->num_phy = chan_list_event_hdr->num_phy; 16008 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16009 wmi_handle, chan_list_event_hdr->phy_id); 16010 reg_info->ctry_code = chan_list_event_hdr->country_id; 16011 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 16012 16013 reg_info->status_code = 16014 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 16015 16016 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 16017 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 16018 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 16019 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 16020 16021 wmi_debug("num_phys = %u and phy_id = %u", 16022 reg_info->num_phy, reg_info->phy_id); 16023 16024 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16025 reg_info->alpha2, reg_info->dfs_region, 16026 reg_info->min_bw_2g, reg_info->max_bw_2g, 16027 reg_info->min_bw_5g, reg_info->max_bw_5g); 16028 16029 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16030 num_2g_reg_rules, num_5g_reg_rules); 16031 wmi_reg_rule = 16032 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 16033 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 16034 + WMI_TLV_HDR_SIZE); 16035 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 16036 wmi_reg_rule); 16037 wmi_reg_rule += num_2g_reg_rules; 16038 16039 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 16040 wmi_reg_rule); 16041 16042 wmi_debug("processed regulatory channel list"); 16043 16044 return QDF_STATUS_SUCCESS; 16045 } 16046 16047 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 16048 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16049 struct reg_11d_new_country *reg_11d_country, uint32_t len) 16050 { 16051 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 16052 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 16053 16054 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 16055 if (!param_buf) { 16056 wmi_err("invalid 11d country event buf"); 16057 return QDF_STATUS_E_FAILURE; 16058 } 16059 16060 reg_11d_country_event = param_buf->fixed_param; 16061 16062 qdf_mem_copy(reg_11d_country->alpha2, 16063 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 16064 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 16065 16066 wmi_debug("processed 11d country event, new cc %s", 16067 reg_11d_country->alpha2); 16068 16069 return QDF_STATUS_SUCCESS; 16070 } 16071 16072 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 16073 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16074 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 16075 { 16076 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 16077 wmi_avoid_freq_range_desc *afr_desc; 16078 uint32_t num_freq_ranges, freq_range_idx; 16079 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 16080 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 16081 16082 if (!param_buf) { 16083 wmi_err("Invalid channel avoid event buffer"); 16084 return QDF_STATUS_E_INVAL; 16085 } 16086 16087 afr_fixed_param = param_buf->fixed_param; 16088 if (!afr_fixed_param) { 16089 wmi_err("Invalid channel avoid event fixed param buffer"); 16090 return QDF_STATUS_E_INVAL; 16091 } 16092 16093 if (!ch_avoid_ind) { 16094 wmi_err("Invalid channel avoid indication buffer"); 16095 return QDF_STATUS_E_INVAL; 16096 } 16097 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 16098 wmi_err("no.of freq ranges exceeded the limit"); 16099 return QDF_STATUS_E_INVAL; 16100 } 16101 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 16102 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 16103 afr_fixed_param->num_freq_ranges; 16104 16105 wmi_debug("Channel avoid event received with %d ranges", 16106 num_freq_ranges); 16107 16108 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 16109 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 16110 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 16111 freq_range_idx++) { 16112 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 16113 afr_desc->start_freq; 16114 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 16115 afr_desc->end_freq; 16116 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 16117 freq_range_idx, afr_desc->tlv_header, 16118 afr_desc->start_freq, afr_desc->end_freq); 16119 afr_desc++; 16120 } 16121 16122 return QDF_STATUS_SUCCESS; 16123 } 16124 16125 #ifdef DFS_COMPONENT_ENABLE 16126 /** 16127 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 16128 * @wmi_handle: wma handle 16129 * @evt_buf: event buffer 16130 * @vdev_id: vdev id 16131 * @len: length of buffer 16132 * 16133 * Return: 0 for success or error code 16134 */ 16135 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 16136 uint8_t *evt_buf, 16137 uint32_t *vdev_id, 16138 uint32_t len) 16139 { 16140 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16141 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 16142 16143 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 16144 if (!param_tlvs) { 16145 wmi_err("invalid cac complete event buf"); 16146 return QDF_STATUS_E_FAILURE; 16147 } 16148 16149 cac_event = param_tlvs->fixed_param; 16150 *vdev_id = cac_event->vdev_id; 16151 wmi_debug("processed cac complete event vdev %d", *vdev_id); 16152 16153 return QDF_STATUS_SUCCESS; 16154 } 16155 16156 /** 16157 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 16158 * @wmi_handle: wma handle 16159 * @evt_buf: event buffer 16160 * @vdev_id: vdev id 16161 * @len: length of buffer 16162 * 16163 * Return: 0 for success or error code 16164 */ 16165 static QDF_STATUS 16166 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 16167 uint8_t *evt_buf, 16168 struct vdev_adfs_complete_status *param) 16169 { 16170 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16171 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 16172 16173 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16174 if (!param_tlvs) { 16175 wmi_err("invalid ocac complete event buf"); 16176 return QDF_STATUS_E_FAILURE; 16177 } 16178 16179 if (!param_tlvs->fixed_param) { 16180 wmi_err("invalid param_tlvs->fixed_param"); 16181 return QDF_STATUS_E_FAILURE; 16182 } 16183 16184 ocac_complete_status = param_tlvs->fixed_param; 16185 param->vdev_id = ocac_complete_status->vdev_id; 16186 param->chan_freq = ocac_complete_status->chan_freq; 16187 param->center_freq1 = ocac_complete_status->center_freq1; 16188 param->center_freq2 = ocac_complete_status->center_freq2; 16189 param->ocac_status = ocac_complete_status->status; 16190 param->chan_width = ocac_complete_status->chan_width; 16191 wmi_debug("processed ocac complete event vdev %d" 16192 " agile chan %d %d width %d status %d", 16193 param->vdev_id, 16194 param->center_freq1, 16195 param->center_freq2, 16196 param->chan_width, 16197 param->ocac_status); 16198 16199 return QDF_STATUS_SUCCESS; 16200 } 16201 16202 /** 16203 * extract_dfs_radar_detection_event_tlv() - extract radar found event 16204 * @wmi_handle: wma handle 16205 * @evt_buf: event buffer 16206 * @radar_found: radar found event info 16207 * @len: length of buffer 16208 * 16209 * Return: 0 for success or error code 16210 */ 16211 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 16212 wmi_unified_t wmi_handle, 16213 uint8_t *evt_buf, 16214 struct radar_found_info *radar_found, 16215 uint32_t len) 16216 { 16217 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 16218 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 16219 16220 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 16221 if (!param_tlv) { 16222 wmi_err("invalid radar detection event buf"); 16223 return QDF_STATUS_E_FAILURE; 16224 } 16225 16226 radar_event = param_tlv->fixed_param; 16227 16228 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16229 wmi_handle, 16230 radar_event->pdev_id); 16231 16232 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16233 return QDF_STATUS_E_FAILURE; 16234 16235 radar_found->detection_mode = radar_event->detection_mode; 16236 radar_found->chan_freq = radar_event->chan_freq; 16237 radar_found->chan_width = radar_event->chan_width; 16238 radar_found->detector_id = radar_event->detector_id; 16239 radar_found->segment_id = radar_event->segment_id; 16240 radar_found->timestamp = radar_event->timestamp; 16241 radar_found->is_chirp = radar_event->is_chirp; 16242 radar_found->freq_offset = radar_event->freq_offset; 16243 radar_found->sidx = radar_event->sidx; 16244 16245 wmi_debug("processed radar found event pdev %d," 16246 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 16247 "chan_width (RSSI) %d,detector_id (false_radar) %d," 16248 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 16249 "is_chirp %d,detection mode %d", 16250 radar_event->pdev_id, radar_found->pdev_id, 16251 radar_event->timestamp, radar_event->chan_freq, 16252 radar_event->chan_width, radar_event->detector_id, 16253 radar_event->freq_offset, radar_event->segment_id, 16254 radar_event->sidx, radar_event->is_chirp, 16255 radar_event->detection_mode); 16256 16257 return QDF_STATUS_SUCCESS; 16258 } 16259 16260 #ifdef MOBILE_DFS_SUPPORT 16261 /** 16262 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 16263 * @wmi_handle: wma handle 16264 * @evt_buf: event buffer 16265 * @wlan_radar_event: Pointer to struct radar_event_info 16266 * @len: length of buffer 16267 * 16268 * Return: QDF_STATUS 16269 */ 16270 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16271 wmi_unified_t wmi_handle, 16272 uint8_t *evt_buf, 16273 struct radar_event_info *wlan_radar_event, 16274 uint32_t len) 16275 { 16276 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 16277 wmi_dfs_radar_event_fixed_param *radar_event; 16278 16279 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 16280 if (!param_tlv) { 16281 wmi_err("invalid wlan radar event buf"); 16282 return QDF_STATUS_E_FAILURE; 16283 } 16284 16285 radar_event = param_tlv->fixed_param; 16286 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 16287 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 16288 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 16289 wlan_radar_event->rssi = radar_event->rssi; 16290 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 16291 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 16292 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 16293 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 16294 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 16295 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 16296 if (radar_event->pulse_flags & 16297 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 16298 wlan_radar_event->is_psidx_diff_valid = true; 16299 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 16300 } else { 16301 wlan_radar_event->is_psidx_diff_valid = false; 16302 } 16303 16304 wlan_radar_event->pdev_id = radar_event->pdev_id; 16305 16306 return QDF_STATUS_SUCCESS; 16307 } 16308 #else 16309 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16310 wmi_unified_t wmi_handle, 16311 uint8_t *evt_buf, 16312 struct radar_event_info *wlan_radar_event, 16313 uint32_t len) 16314 { 16315 return QDF_STATUS_SUCCESS; 16316 } 16317 #endif 16318 #endif 16319 16320 /** 16321 * send_get_rcpi_cmd_tlv() - send request for rcpi value 16322 * @wmi_handle: wmi handle 16323 * @get_rcpi_param: rcpi params 16324 * 16325 * Return: QDF status 16326 */ 16327 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 16328 struct rcpi_req *get_rcpi_param) 16329 { 16330 wmi_buf_t buf; 16331 wmi_request_rcpi_cmd_fixed_param *cmd; 16332 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 16333 16334 buf = wmi_buf_alloc(wmi_handle, len); 16335 if (!buf) 16336 return QDF_STATUS_E_NOMEM; 16337 16338 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 16339 WMITLV_SET_HDR(&cmd->tlv_header, 16340 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 16341 WMITLV_GET_STRUCT_TLVLEN 16342 (wmi_request_rcpi_cmd_fixed_param)); 16343 16344 cmd->vdev_id = get_rcpi_param->vdev_id; 16345 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 16346 &cmd->peer_macaddr); 16347 16348 switch (get_rcpi_param->measurement_type) { 16349 16350 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16351 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16352 break; 16353 16354 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 16355 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 16356 break; 16357 16358 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16359 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16360 break; 16361 16362 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 16363 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 16364 break; 16365 16366 default: 16367 /* 16368 * invalid rcpi measurement type, fall back to 16369 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 16370 */ 16371 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16372 break; 16373 } 16374 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 16375 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 16376 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16377 WMI_REQUEST_RCPI_CMDID)) { 16378 16379 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 16380 wmi_buf_free(buf); 16381 return QDF_STATUS_E_FAILURE; 16382 } 16383 16384 return QDF_STATUS_SUCCESS; 16385 } 16386 16387 /** 16388 * extract_rcpi_response_event_tlv() - Extract RCPI event params 16389 * @wmi_handle: wmi handle 16390 * @evt_buf: pointer to event buffer 16391 * @res: pointer to hold rcpi response from firmware 16392 * 16393 * Return: QDF_STATUS_SUCCESS for successful event parse 16394 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 16395 */ 16396 static QDF_STATUS 16397 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 16398 void *evt_buf, struct rcpi_res *res) 16399 { 16400 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 16401 wmi_update_rcpi_event_fixed_param *event; 16402 16403 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 16404 if (!param_buf) { 16405 wmi_err("Invalid rcpi event"); 16406 return QDF_STATUS_E_INVAL; 16407 } 16408 16409 event = param_buf->fixed_param; 16410 res->vdev_id = event->vdev_id; 16411 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 16412 16413 switch (event->measurement_type) { 16414 16415 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16416 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16417 break; 16418 16419 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 16420 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 16421 break; 16422 16423 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16424 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16425 break; 16426 16427 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 16428 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 16429 break; 16430 16431 default: 16432 wmi_err("Invalid rcpi measurement type from firmware"); 16433 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 16434 return QDF_STATUS_E_FAILURE; 16435 } 16436 16437 if (event->status) 16438 return QDF_STATUS_E_FAILURE; 16439 else 16440 return QDF_STATUS_SUCCESS; 16441 } 16442 16443 /** 16444 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 16445 * host to target defines. For legacy there is not conversion 16446 * required. Just return pdev_id as it is. 16447 * @param pdev_id: host pdev_id to be converted. 16448 * Return: target pdev_id after conversion. 16449 */ 16450 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 16451 wmi_unified_t wmi_handle, 16452 uint32_t pdev_id) 16453 { 16454 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 16455 return WMI_PDEV_ID_SOC; 16456 16457 /*No conversion required*/ 16458 return pdev_id; 16459 } 16460 16461 /** 16462 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 16463 * target to host defines. For legacy there is not conversion 16464 * required. Just return pdev_id as it is. 16465 * @param pdev_id: target pdev_id to be converted. 16466 * Return: host pdev_id after conversion. 16467 */ 16468 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 16469 wmi_unified_t wmi_handle, 16470 uint32_t pdev_id) 16471 { 16472 /*No conversion required*/ 16473 return pdev_id; 16474 } 16475 16476 /** 16477 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 16478 * host to target defines. For legacy there is not conversion 16479 * required. Just return phy_id as it is. 16480 * @param pdev_id: host phy_id to be converted. 16481 * Return: target phy_id after conversion. 16482 */ 16483 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 16484 wmi_unified_t wmi_handle, 16485 uint32_t phy_id) 16486 { 16487 /*No conversion required*/ 16488 return phy_id; 16489 } 16490 16491 /** 16492 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 16493 * target to host defines. For legacy there is not conversion 16494 * required. Just return phy_id as it is. 16495 * @param pdev_id: target phy_id to be converted. 16496 * Return: host phy_id after conversion. 16497 */ 16498 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 16499 wmi_unified_t wmi_handle, 16500 uint32_t phy_id) 16501 { 16502 /*No conversion required*/ 16503 return phy_id; 16504 } 16505 16506 /** 16507 * send_set_country_cmd_tlv() - WMI scan channel list function 16508 * @param wmi_handle : handle to WMI. 16509 * @param param : pointer to hold scan channel list parameter 16510 * 16511 * Return: 0 on success and -ve on failure. 16512 */ 16513 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 16514 struct set_country *params) 16515 { 16516 wmi_buf_t buf; 16517 QDF_STATUS qdf_status; 16518 wmi_set_current_country_cmd_fixed_param *cmd; 16519 uint16_t len = sizeof(*cmd); 16520 uint8_t pdev_id = params->pdev_id; 16521 16522 buf = wmi_buf_alloc(wmi_handle, len); 16523 if (!buf) { 16524 qdf_status = QDF_STATUS_E_NOMEM; 16525 goto end; 16526 } 16527 16528 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 16529 WMITLV_SET_HDR(&cmd->tlv_header, 16530 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 16531 WMITLV_GET_STRUCT_TLVLEN 16532 (wmi_set_current_country_cmd_fixed_param)); 16533 16534 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 16535 wmi_handle, 16536 pdev_id); 16537 wmi_debug("setting current country to %s and target pdev_id = %u", 16538 params->country, cmd->pdev_id); 16539 16540 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 16541 16542 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 16543 qdf_status = wmi_unified_cmd_send(wmi_handle, 16544 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 16545 16546 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16547 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 16548 wmi_buf_free(buf); 16549 } 16550 16551 end: 16552 return qdf_status; 16553 } 16554 16555 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 16556 WMI_SET_BITS(alpha, 0, 8, val0); \ 16557 WMI_SET_BITS(alpha, 8, 8, val1); \ 16558 WMI_SET_BITS(alpha, 16, 8, val2); \ 16559 } while (0) 16560 16561 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 16562 uint8_t pdev_id, struct cc_regdmn_s *rd) 16563 { 16564 wmi_set_init_country_cmd_fixed_param *cmd; 16565 uint16_t len; 16566 wmi_buf_t buf; 16567 int ret; 16568 16569 len = sizeof(wmi_set_init_country_cmd_fixed_param); 16570 buf = wmi_buf_alloc(wmi_handle, len); 16571 if (!buf) 16572 return QDF_STATUS_E_NOMEM; 16573 16574 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 16575 WMITLV_SET_HDR(&cmd->tlv_header, 16576 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 16577 WMITLV_GET_STRUCT_TLVLEN 16578 (wmi_set_init_country_cmd_fixed_param)); 16579 16580 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16581 wmi_handle, 16582 pdev_id); 16583 16584 if (rd->flags == CC_IS_SET) { 16585 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 16586 cmd->country_code.country_id = rd->cc.country_code; 16587 } else if (rd->flags == ALPHA_IS_SET) { 16588 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 16589 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 16590 rd->cc.alpha[0], 16591 rd->cc.alpha[1], 16592 rd->cc.alpha[2]); 16593 } else if (rd->flags == REGDMN_IS_SET) { 16594 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 16595 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 16596 rd->cc.regdmn.reg_2g_5g_pair_id); 16597 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 16598 rd->cc.regdmn.sixg_superdmn_id); 16599 } 16600 16601 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 16602 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16603 WMI_SET_INIT_COUNTRY_CMDID); 16604 if (ret) { 16605 wmi_err("Failed to config wow wakeup event"); 16606 wmi_buf_free(buf); 16607 return QDF_STATUS_E_FAILURE; 16608 } 16609 16610 return QDF_STATUS_SUCCESS; 16611 } 16612 16613 /** 16614 * send_obss_detection_cfg_cmd_tlv() - send obss detection 16615 * configurations to firmware. 16616 * @wmi_handle: wmi handle 16617 * @obss_cfg_param: obss detection configurations 16618 * 16619 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 16620 * 16621 * Return: QDF_STATUS 16622 */ 16623 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 16624 struct wmi_obss_detection_cfg_param *obss_cfg_param) 16625 { 16626 wmi_buf_t buf; 16627 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 16628 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 16629 16630 buf = wmi_buf_alloc(wmi_handle, len); 16631 if (!buf) 16632 return QDF_STATUS_E_NOMEM; 16633 16634 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 16635 WMITLV_SET_HDR(&cmd->tlv_header, 16636 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 16637 WMITLV_GET_STRUCT_TLVLEN 16638 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 16639 16640 cmd->vdev_id = obss_cfg_param->vdev_id; 16641 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 16642 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 16643 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 16644 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 16645 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 16646 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 16647 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 16648 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 16649 16650 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 16651 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16652 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 16653 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 16654 wmi_buf_free(buf); 16655 return QDF_STATUS_E_FAILURE; 16656 } 16657 16658 return QDF_STATUS_SUCCESS; 16659 } 16660 16661 /** 16662 * extract_obss_detection_info_tlv() - Extract obss detection info 16663 * received from firmware. 16664 * @evt_buf: pointer to event buffer 16665 * @obss_detection: Pointer to hold obss detection info 16666 * 16667 * Return: QDF_STATUS 16668 */ 16669 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 16670 struct wmi_obss_detect_info 16671 *obss_detection) 16672 { 16673 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 16674 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 16675 16676 if (!obss_detection) { 16677 wmi_err("Invalid obss_detection event buffer"); 16678 return QDF_STATUS_E_INVAL; 16679 } 16680 16681 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 16682 if (!param_buf) { 16683 wmi_err("Invalid evt_buf"); 16684 return QDF_STATUS_E_INVAL; 16685 } 16686 16687 fix_param = param_buf->fixed_param; 16688 obss_detection->vdev_id = fix_param->vdev_id; 16689 obss_detection->matched_detection_masks = 16690 fix_param->matched_detection_masks; 16691 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 16692 &obss_detection->matched_bssid_addr[0]); 16693 switch (fix_param->reason) { 16694 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 16695 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 16696 break; 16697 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 16698 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 16699 break; 16700 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 16701 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 16702 break; 16703 default: 16704 wmi_err("Invalid reason: %d", fix_param->reason); 16705 return QDF_STATUS_E_INVAL; 16706 } 16707 16708 return QDF_STATUS_SUCCESS; 16709 } 16710 16711 /** 16712 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 16713 * @wmi_handle: wmi handle 16714 * @params: pointer to request structure 16715 * 16716 * Return: QDF_STATUS 16717 */ 16718 static QDF_STATUS 16719 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 16720 struct wmi_roam_scan_stats_req *params) 16721 { 16722 wmi_buf_t buf; 16723 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 16724 WMITLV_TAG_ID tag; 16725 uint32_t size; 16726 uint32_t len = sizeof(*cmd); 16727 16728 buf = wmi_buf_alloc(wmi_handle, len); 16729 if (!buf) 16730 return QDF_STATUS_E_FAILURE; 16731 16732 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 16733 16734 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 16735 size = WMITLV_GET_STRUCT_TLVLEN( 16736 wmi_request_roam_scan_stats_cmd_fixed_param); 16737 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 16738 16739 cmd->vdev_id = params->vdev_id; 16740 16741 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 16742 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16743 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 16744 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 16745 wmi_buf_free(buf); 16746 return QDF_STATUS_E_FAILURE; 16747 } 16748 16749 return QDF_STATUS_SUCCESS; 16750 } 16751 16752 /** 16753 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 16754 * channel list from firmware 16755 * @wmi_handle: wmi handler 16756 * @vdev_id: vdev id 16757 * 16758 * Return: QDF_STATUS 16759 */ 16760 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 16761 uint32_t vdev_id) 16762 { 16763 wmi_buf_t buf; 16764 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 16765 uint16_t len = sizeof(*cmd); 16766 int ret; 16767 16768 buf = wmi_buf_alloc(wmi_handle, len); 16769 if (!buf) { 16770 wmi_err("Failed to allocate wmi buffer"); 16771 return QDF_STATUS_E_NOMEM; 16772 } 16773 16774 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 16775 wmi_buf_data(buf); 16776 WMITLV_SET_HDR(&cmd->tlv_header, 16777 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 16778 WMITLV_GET_STRUCT_TLVLEN( 16779 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 16780 cmd->vdev_id = vdev_id; 16781 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 16782 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16783 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 16784 if (QDF_IS_STATUS_ERROR(ret)) { 16785 wmi_err("Failed to send get roam scan channels request = %d", 16786 ret); 16787 wmi_buf_free(buf); 16788 } 16789 return ret; 16790 } 16791 16792 /** 16793 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 16794 * @wmi_handle: wmi handle 16795 * @evt_buf: pointer to event buffer 16796 * @vdev_id: output pointer to hold vdev id 16797 * @res_param: output pointer to hold the allocated response 16798 * 16799 * Return: QDF_STATUS 16800 */ 16801 static QDF_STATUS 16802 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16803 uint32_t *vdev_id, 16804 struct wmi_roam_scan_stats_res **res_param) 16805 { 16806 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 16807 wmi_roam_scan_stats_event_fixed_param *fixed_param; 16808 uint32_t *client_id = NULL; 16809 wmi_roaming_timestamp *timestamp = NULL; 16810 uint32_t *num_channels = NULL; 16811 uint32_t *chan_info = NULL; 16812 wmi_mac_addr *old_bssid = NULL; 16813 uint32_t *is_roaming_success = NULL; 16814 wmi_mac_addr *new_bssid = NULL; 16815 uint32_t *num_roam_candidates = NULL; 16816 wmi_roam_scan_trigger_reason *roam_reason = NULL; 16817 wmi_mac_addr *bssid = NULL; 16818 uint32_t *score = NULL; 16819 uint32_t *channel = NULL; 16820 uint32_t *rssi = NULL; 16821 int chan_idx = 0, cand_idx = 0; 16822 uint32_t total_len; 16823 struct wmi_roam_scan_stats_res *res; 16824 uint32_t i, j; 16825 uint32_t num_scans, scan_param_size; 16826 16827 *res_param = NULL; 16828 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 16829 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 16830 if (!param_buf) { 16831 wmi_err("Invalid roam scan stats event"); 16832 return QDF_STATUS_E_INVAL; 16833 } 16834 16835 fixed_param = param_buf->fixed_param; 16836 16837 num_scans = fixed_param->num_roam_scans; 16838 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 16839 *vdev_id = fixed_param->vdev_id; 16840 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 16841 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 16842 num_scans, WMI_ROAM_SCAN_STATS_MAX); 16843 return QDF_STATUS_E_INVAL; 16844 } 16845 16846 total_len = sizeof(*res) + num_scans * scan_param_size; 16847 16848 res = qdf_mem_malloc(total_len); 16849 if (!res) 16850 return QDF_STATUS_E_NOMEM; 16851 16852 if (!num_scans) { 16853 *res_param = res; 16854 return QDF_STATUS_SUCCESS; 16855 } 16856 16857 if (param_buf->client_id && 16858 param_buf->num_client_id == num_scans) 16859 client_id = param_buf->client_id; 16860 16861 if (param_buf->timestamp && 16862 param_buf->num_timestamp == num_scans) 16863 timestamp = param_buf->timestamp; 16864 16865 if (param_buf->old_bssid && 16866 param_buf->num_old_bssid == num_scans) 16867 old_bssid = param_buf->old_bssid; 16868 16869 if (param_buf->new_bssid && 16870 param_buf->num_new_bssid == num_scans) 16871 new_bssid = param_buf->new_bssid; 16872 16873 if (param_buf->is_roaming_success && 16874 param_buf->num_is_roaming_success == num_scans) 16875 is_roaming_success = param_buf->is_roaming_success; 16876 16877 if (param_buf->roam_reason && 16878 param_buf->num_roam_reason == num_scans) 16879 roam_reason = param_buf->roam_reason; 16880 16881 if (param_buf->num_channels && 16882 param_buf->num_num_channels == num_scans) { 16883 uint32_t count, chan_info_sum = 0; 16884 16885 num_channels = param_buf->num_channels; 16886 for (count = 0; count < param_buf->num_num_channels; count++) { 16887 if (param_buf->num_channels[count] > 16888 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 16889 wmi_err_rl("%u exceeded max scan channels %u", 16890 param_buf->num_channels[count], 16891 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 16892 goto error; 16893 } 16894 chan_info_sum += param_buf->num_channels[count]; 16895 } 16896 16897 if (param_buf->chan_info && 16898 param_buf->num_chan_info == chan_info_sum) 16899 chan_info = param_buf->chan_info; 16900 } 16901 16902 if (param_buf->num_roam_candidates && 16903 param_buf->num_num_roam_candidates == num_scans) { 16904 uint32_t cnt, roam_cand_sum = 0; 16905 16906 num_roam_candidates = param_buf->num_roam_candidates; 16907 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 16908 if (param_buf->num_roam_candidates[cnt] > 16909 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 16910 wmi_err_rl("%u exceeded max scan cand %u", 16911 param_buf->num_roam_candidates[cnt], 16912 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 16913 goto error; 16914 } 16915 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 16916 } 16917 16918 if (param_buf->bssid && 16919 param_buf->num_bssid == roam_cand_sum) 16920 bssid = param_buf->bssid; 16921 16922 if (param_buf->score && 16923 param_buf->num_score == roam_cand_sum) 16924 score = param_buf->score; 16925 16926 if (param_buf->channel && 16927 param_buf->num_channel == roam_cand_sum) 16928 channel = param_buf->channel; 16929 16930 if (param_buf->rssi && 16931 param_buf->num_rssi == roam_cand_sum) 16932 rssi = param_buf->rssi; 16933 } 16934 16935 res->num_roam_scans = num_scans; 16936 for (i = 0; i < num_scans; i++) { 16937 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 16938 16939 if (timestamp) 16940 roam->time_stamp = timestamp[i].lower32bit | 16941 (timestamp[i].upper32bit << 31); 16942 16943 if (client_id) 16944 roam->client_id = client_id[i]; 16945 16946 if (num_channels) { 16947 roam->num_scan_chans = num_channels[i]; 16948 if (chan_info) { 16949 for (j = 0; j < num_channels[i]; j++) 16950 roam->scan_freqs[j] = 16951 chan_info[chan_idx++]; 16952 } 16953 } 16954 16955 if (is_roaming_success) 16956 roam->is_roam_successful = is_roaming_success[i]; 16957 16958 if (roam_reason) { 16959 roam->trigger_id = roam_reason[i].trigger_id; 16960 roam->trigger_value = roam_reason[i].trigger_value; 16961 } 16962 16963 if (num_roam_candidates) { 16964 roam->num_roam_candidates = num_roam_candidates[i]; 16965 16966 for (j = 0; j < num_roam_candidates[i]; j++) { 16967 if (score) 16968 roam->cand[j].score = score[cand_idx]; 16969 if (rssi) 16970 roam->cand[j].rssi = rssi[cand_idx]; 16971 if (channel) 16972 roam->cand[j].freq = 16973 channel[cand_idx]; 16974 16975 if (bssid) 16976 WMI_MAC_ADDR_TO_CHAR_ARRAY( 16977 &bssid[cand_idx], 16978 roam->cand[j].bssid); 16979 16980 cand_idx++; 16981 } 16982 } 16983 16984 if (old_bssid) 16985 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 16986 roam->old_bssid); 16987 16988 if (new_bssid) 16989 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 16990 roam->new_bssid); 16991 } 16992 16993 *res_param = res; 16994 16995 return QDF_STATUS_SUCCESS; 16996 error: 16997 qdf_mem_free(res); 16998 return QDF_STATUS_E_FAILURE; 16999 } 17000 17001 /** 17002 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 17003 * @wmi_handle: wmi handle 17004 * @evt_buf: pointer to event buffer 17005 * @vdev_id: output pointer to hold vdev id 17006 * @tx_status: output pointer to hold the tx_status 17007 * 17008 * Return: QDF_STATUS 17009 */ 17010 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 17011 void *evt_buf, 17012 uint32_t *vdev_id, 17013 uint32_t *tx_status) { 17014 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 17015 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 17016 17017 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 17018 if (!param_buf) { 17019 wmi_err("Invalid offload bcn tx status event buffer"); 17020 return QDF_STATUS_E_INVAL; 17021 } 17022 17023 bcn_tx_status_event = param_buf->fixed_param; 17024 *vdev_id = bcn_tx_status_event->vdev_id; 17025 *tx_status = bcn_tx_status_event->tx_status; 17026 17027 return QDF_STATUS_SUCCESS; 17028 } 17029 17030 #ifdef WLAN_SUPPORT_GREEN_AP 17031 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 17032 uint8_t *evt_buf, 17033 struct wlan_green_ap_egap_status_info *egap_status_info_params) 17034 { 17035 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 17036 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 17037 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 17038 17039 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 17040 if (!param_buf) { 17041 wmi_err("Invalid EGAP Info status event buffer"); 17042 return QDF_STATUS_E_INVAL; 17043 } 17044 17045 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 17046 param_buf->fixed_param; 17047 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 17048 param_buf->chainmask_list; 17049 17050 if (!egap_info_event || !chainmask_event) { 17051 wmi_err("Invalid EGAP Info event or chainmask event"); 17052 return QDF_STATUS_E_INVAL; 17053 } 17054 17055 egap_status_info_params->status = egap_info_event->status; 17056 egap_status_info_params->mac_id = chainmask_event->mac_id; 17057 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 17058 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 17059 17060 return QDF_STATUS_SUCCESS; 17061 } 17062 #endif 17063 17064 /* 17065 * extract_comb_phyerr_tlv() - extract comb phy error from event 17066 * @wmi_handle: wmi handle 17067 * @evt_buf: pointer to event buffer 17068 * @datalen: data length of event buffer 17069 * @buf_offset: Pointer to hold value of current event buffer offset 17070 * post extraction 17071 * @phyerr: Pointer to hold phyerr 17072 * 17073 * Return: QDF_STATUS 17074 */ 17075 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 17076 void *evt_buf, 17077 uint16_t datalen, 17078 uint16_t *buf_offset, 17079 wmi_host_phyerr_t *phyerr) 17080 { 17081 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 17082 wmi_comb_phyerr_rx_hdr *pe_hdr; 17083 17084 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 17085 if (!param_tlvs) { 17086 wmi_debug("Received null data from FW"); 17087 return QDF_STATUS_E_FAILURE; 17088 } 17089 17090 pe_hdr = param_tlvs->hdr; 17091 if (!pe_hdr) { 17092 wmi_debug("Received Data PE Header is NULL"); 17093 return QDF_STATUS_E_FAILURE; 17094 } 17095 17096 /* Ensure it's at least the size of the header */ 17097 if (datalen < sizeof(*pe_hdr)) { 17098 wmi_debug("Expected minimum size %zu, received %d", 17099 sizeof(*pe_hdr), datalen); 17100 return QDF_STATUS_E_FAILURE; 17101 } 17102 17103 phyerr->pdev_id = wmi_handle->ops-> 17104 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 17105 phyerr->tsf64 = pe_hdr->tsf_l32; 17106 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 17107 phyerr->bufp = param_tlvs->bufp; 17108 17109 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 17110 wmi_debug("Invalid buf_len %d, num_bufp %d", 17111 pe_hdr->buf_len, param_tlvs->num_bufp); 17112 return QDF_STATUS_E_FAILURE; 17113 } 17114 17115 phyerr->buf_len = pe_hdr->buf_len; 17116 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 17117 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 17118 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 17119 17120 return QDF_STATUS_SUCCESS; 17121 } 17122 17123 /** 17124 * extract_single_phyerr_tlv() - extract single phy error from event 17125 * @wmi_handle: wmi handle 17126 * @evt_buf: pointer to event buffer 17127 * @datalen: data length of event buffer 17128 * @buf_offset: Pointer to hold value of current event buffer offset 17129 * post extraction 17130 * @phyerr: Pointer to hold phyerr 17131 * 17132 * Return: QDF_STATUS 17133 */ 17134 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 17135 void *evt_buf, 17136 uint16_t datalen, 17137 uint16_t *buf_offset, 17138 wmi_host_phyerr_t *phyerr) 17139 { 17140 wmi_single_phyerr_rx_event *ev; 17141 uint16_t n = *buf_offset; 17142 uint8_t *data = (uint8_t *)evt_buf; 17143 17144 if (n < datalen) { 17145 if ((datalen - n) < sizeof(ev->hdr)) { 17146 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 17147 datalen, n, sizeof(ev->hdr)); 17148 return QDF_STATUS_E_FAILURE; 17149 } 17150 17151 /* 17152 * Obtain a pointer to the beginning of the current event. 17153 * data[0] is the beginning of the WMI payload. 17154 */ 17155 ev = (wmi_single_phyerr_rx_event *)&data[n]; 17156 17157 /* 17158 * Sanity check the buffer length of the event against 17159 * what we currently have. 17160 * 17161 * Since buf_len is 32 bits, we check if it overflows 17162 * a large 32 bit value. It's not 0x7fffffff because 17163 * we increase n by (buf_len + sizeof(hdr)), which would 17164 * in itself cause n to overflow. 17165 * 17166 * If "int" is 64 bits then this becomes a moot point. 17167 */ 17168 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 17169 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 17170 return QDF_STATUS_E_FAILURE; 17171 } 17172 17173 if ((n + ev->hdr.buf_len) > datalen) { 17174 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 17175 n, ev->hdr.buf_len, datalen); 17176 return QDF_STATUS_E_FAILURE; 17177 } 17178 17179 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 17180 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 17181 phyerr->bufp = &ev->bufp[0]; 17182 phyerr->buf_len = ev->hdr.buf_len; 17183 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 17184 17185 /* 17186 * Advance the buffer pointer to the next PHY error. 17187 * buflen is the length of this payload, so we need to 17188 * advance past the current header _AND_ the payload. 17189 */ 17190 n += sizeof(*ev) + ev->hdr.buf_len; 17191 } 17192 *buf_offset = n; 17193 17194 return QDF_STATUS_SUCCESS; 17195 } 17196 17197 /** 17198 * extract_esp_estimation_ev_param_tlv() - extract air time from event 17199 * @wmi_handle: wmi handle 17200 * @evt_buf: pointer to event buffer 17201 * @param: Pointer to hold esp event 17202 * 17203 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 17204 */ 17205 static QDF_STATUS 17206 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 17207 void *evt_buf, 17208 struct esp_estimation_event *param) 17209 { 17210 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 17211 wmi_esp_estimate_event_fixed_param *esp_event; 17212 17213 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 17214 if (!param_buf) { 17215 wmi_err("Invalid ESP Estimate Event buffer"); 17216 return QDF_STATUS_E_INVAL; 17217 } 17218 esp_event = param_buf->fixed_param; 17219 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 17220 17221 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17222 wmi_handle, 17223 esp_event->pdev_id); 17224 17225 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17226 return QDF_STATUS_E_FAILURE; 17227 17228 return QDF_STATUS_SUCCESS; 17229 } 17230 17231 /* 17232 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 17233 * updating bss color change within firmware when AP announces bss color change. 17234 * @wmi_handle: wmi handle 17235 * @vdev_id: vdev ID 17236 * @enable: enable bss color change within firmware 17237 * 17238 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 17239 * 17240 * Return: QDF_STATUS 17241 */ 17242 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 17243 uint32_t vdev_id, 17244 bool enable) 17245 { 17246 wmi_buf_t buf; 17247 wmi_bss_color_change_enable_fixed_param *cmd; 17248 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 17249 17250 buf = wmi_buf_alloc(wmi_handle, len); 17251 if (!buf) 17252 return QDF_STATUS_E_NOMEM; 17253 17254 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 17255 WMITLV_SET_HDR(&cmd->tlv_header, 17256 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 17257 WMITLV_GET_STRUCT_TLVLEN 17258 (wmi_bss_color_change_enable_fixed_param)); 17259 cmd->vdev_id = vdev_id; 17260 cmd->enable = enable; 17261 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 17262 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17263 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 17264 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 17265 wmi_buf_free(buf); 17266 return QDF_STATUS_E_FAILURE; 17267 } 17268 17269 return QDF_STATUS_SUCCESS; 17270 } 17271 17272 /** 17273 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 17274 * configurations to firmware. 17275 * @wmi_handle: wmi handle 17276 * @cfg_param: obss detection configurations 17277 * 17278 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 17279 * 17280 * Return: QDF_STATUS 17281 */ 17282 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 17283 wmi_unified_t wmi_handle, 17284 struct wmi_obss_color_collision_cfg_param *cfg_param) 17285 { 17286 wmi_buf_t buf; 17287 wmi_obss_color_collision_det_config_fixed_param *cmd; 17288 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 17289 17290 buf = wmi_buf_alloc(wmi_handle, len); 17291 if (!buf) 17292 return QDF_STATUS_E_NOMEM; 17293 17294 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 17295 buf); 17296 WMITLV_SET_HDR(&cmd->tlv_header, 17297 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 17298 WMITLV_GET_STRUCT_TLVLEN 17299 (wmi_obss_color_collision_det_config_fixed_param)); 17300 cmd->vdev_id = cfg_param->vdev_id; 17301 cmd->flags = cfg_param->flags; 17302 cmd->current_bss_color = cfg_param->current_bss_color; 17303 cmd->detection_period_ms = cfg_param->detection_period_ms; 17304 cmd->scan_period_ms = cfg_param->scan_period_ms; 17305 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 17306 17307 switch (cfg_param->evt_type) { 17308 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 17309 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 17310 break; 17311 case OBSS_COLOR_COLLISION_DETECTION: 17312 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 17313 break; 17314 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17315 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17316 break; 17317 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 17318 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 17319 break; 17320 default: 17321 wmi_err("Invalid event type: %d", cfg_param->evt_type); 17322 wmi_buf_free(buf); 17323 return QDF_STATUS_E_FAILURE; 17324 } 17325 17326 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 17327 "detection_period_ms: %d scan_period_ms: %d " 17328 "free_slot_expiry_timer_ms: %d", 17329 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 17330 cmd->detection_period_ms, cmd->scan_period_ms, 17331 cmd->free_slot_expiry_time_ms); 17332 17333 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 17334 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17335 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 17336 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 17337 cfg_param->vdev_id); 17338 wmi_buf_free(buf); 17339 return QDF_STATUS_E_FAILURE; 17340 } 17341 17342 return QDF_STATUS_SUCCESS; 17343 } 17344 17345 /** 17346 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 17347 * received from firmware. 17348 * @evt_buf: pointer to event buffer 17349 * @info: Pointer to hold bss collision info 17350 * 17351 * Return: QDF_STATUS 17352 */ 17353 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 17354 struct wmi_obss_color_collision_info *info) 17355 { 17356 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 17357 wmi_obss_color_collision_evt_fixed_param *fix_param; 17358 17359 if (!info) { 17360 wmi_err("Invalid obss color buffer"); 17361 return QDF_STATUS_E_INVAL; 17362 } 17363 17364 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 17365 evt_buf; 17366 if (!param_buf) { 17367 wmi_err("Invalid evt_buf"); 17368 return QDF_STATUS_E_INVAL; 17369 } 17370 17371 fix_param = param_buf->fixed_param; 17372 info->vdev_id = fix_param->vdev_id; 17373 info->obss_color_bitmap_bit0to31 = 17374 fix_param->bss_color_bitmap_bit0to31; 17375 info->obss_color_bitmap_bit32to63 = 17376 fix_param->bss_color_bitmap_bit32to63; 17377 17378 switch (fix_param->evt_type) { 17379 case WMI_BSS_COLOR_COLLISION_DISABLE: 17380 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 17381 break; 17382 case WMI_BSS_COLOR_COLLISION_DETECTION: 17383 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 17384 break; 17385 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17386 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17387 break; 17388 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 17389 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 17390 break; 17391 default: 17392 wmi_err("Invalid event type: %d, vdev_id: %d", 17393 fix_param->evt_type, fix_param->vdev_id); 17394 return QDF_STATUS_E_FAILURE; 17395 } 17396 17397 return QDF_STATUS_SUCCESS; 17398 } 17399 17400 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 17401 { 17402 struct wmi_ops *ops = wmi_handle->ops; 17403 17404 ops->send_obss_color_collision_cfg_cmd = 17405 send_obss_color_collision_cfg_cmd_tlv; 17406 ops->extract_obss_color_collision_info = 17407 extract_obss_color_collision_info_tlv; 17408 } 17409 17410 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17411 static QDF_STATUS 17412 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 17413 struct config_fils_params *param) 17414 { 17415 wmi_buf_t buf; 17416 wmi_enable_fils_cmd_fixed_param *cmd; 17417 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 17418 17419 buf = wmi_buf_alloc(wmi_handle, len); 17420 if (!buf) 17421 return QDF_STATUS_E_NOMEM; 17422 17423 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 17424 buf); 17425 WMITLV_SET_HDR(&cmd->tlv_header, 17426 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 17427 WMITLV_GET_STRUCT_TLVLEN 17428 (wmi_enable_fils_cmd_fixed_param)); 17429 cmd->vdev_id = param->vdev_id; 17430 cmd->fd_period = param->fd_period; 17431 if (param->send_prb_rsp_frame) 17432 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 17433 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 17434 cmd->vdev_id, cmd->fd_period, cmd->flags); 17435 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 17436 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17437 WMI_ENABLE_FILS_CMDID)) { 17438 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 17439 wmi_buf_free(buf); 17440 return QDF_STATUS_E_FAILURE; 17441 } 17442 17443 return QDF_STATUS_SUCCESS; 17444 } 17445 #endif 17446 17447 #ifdef WLAN_MWS_INFO_DEBUGFS 17448 /** 17449 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 17450 * 17451 * @wmi_handle: wmi handle 17452 * @vdev_id: vdev id 17453 * @cmd_id: Coex command id 17454 * 17455 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 17456 * 17457 * Return: QDF_STATUS 17458 */ 17459 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 17460 uint32_t vdev_id, 17461 uint32_t cmd_id) 17462 { 17463 wmi_buf_t buf; 17464 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 17465 uint16_t len = sizeof(*cmd); 17466 int ret; 17467 17468 buf = wmi_buf_alloc(wmi_handle, len); 17469 if (!buf) { 17470 wmi_err("Failed to allocate wmi buffer"); 17471 return QDF_STATUS_E_NOMEM; 17472 } 17473 17474 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 17475 WMITLV_SET_HDR(&cmd->tlv_header, 17476 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 17477 WMITLV_GET_STRUCT_TLVLEN 17478 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 17479 cmd->vdev_id = vdev_id; 17480 cmd->cmd_id = cmd_id; 17481 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 17482 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17483 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 17484 if (QDF_IS_STATUS_ERROR(ret)) { 17485 wmi_err("Failed to send set param command ret = %d", ret); 17486 wmi_buf_free(buf); 17487 } 17488 return ret; 17489 } 17490 #endif 17491 17492 #ifdef FEATURE_MEC_OFFLOAD 17493 static QDF_STATUS 17494 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 17495 struct set_mec_timer_params *param) 17496 { 17497 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 17498 wmi_buf_t buf; 17499 int32_t len = sizeof(*cmd); 17500 17501 buf = wmi_buf_alloc(wmi_handle, len); 17502 if (!buf) { 17503 wmi_err("wmi_buf_alloc failed"); 17504 return QDF_STATUS_E_FAILURE; 17505 } 17506 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 17507 wmi_buf_data(buf); 17508 WMITLV_SET_HDR(&cmd->tlv_header, 17509 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 17510 WMITLV_GET_STRUCT_TLVLEN( 17511 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 17512 cmd->pdev_id = param->pdev_id; 17513 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 17514 17515 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 17516 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17517 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 17518 wmi_err("Failed to set mec aging timer param"); 17519 wmi_buf_free(buf); 17520 return QDF_STATUS_E_FAILURE; 17521 } 17522 17523 return QDF_STATUS_SUCCESS; 17524 } 17525 #endif 17526 17527 #ifdef WIFI_POS_CONVERGED 17528 /** 17529 * extract_oem_response_param_tlv() - Extract oem response params 17530 * @wmi_handle: wmi handle 17531 * @resp_buf: response buffer 17532 * @oem_resp_param: pointer to hold oem response params 17533 * 17534 * Return: QDF_STATUS_SUCCESS on success or proper error code. 17535 */ 17536 static QDF_STATUS 17537 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 17538 struct wmi_oem_response_param *oem_resp_param) 17539 { 17540 uint64_t temp_addr; 17541 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 17542 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 17543 17544 if (!param_buf) { 17545 wmi_err("Invalid OEM response"); 17546 return QDF_STATUS_E_INVAL; 17547 } 17548 17549 if (param_buf->num_data) { 17550 oem_resp_param->num_data1 = param_buf->num_data; 17551 oem_resp_param->data_1 = param_buf->data; 17552 } 17553 17554 if (param_buf->num_data2) { 17555 oem_resp_param->num_data2 = param_buf->num_data2; 17556 oem_resp_param->data_2 = param_buf->data2; 17557 } 17558 17559 if (param_buf->indirect_data) { 17560 oem_resp_param->indirect_data.pdev_id = 17561 param_buf->indirect_data->pdev_id; 17562 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 17563 oem_resp_param->indirect_data.addr = 17564 param_buf->indirect_data->addr_lo + 17565 ((uint64_t)temp_addr << 32); 17566 oem_resp_param->indirect_data.len = 17567 param_buf->indirect_data->len; 17568 } 17569 17570 return QDF_STATUS_SUCCESS; 17571 } 17572 #endif /* WIFI_POS_CONVERGED */ 17573 17574 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 17575 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 17576 17577 static QDF_STATUS 17578 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17579 struct wifi_pos_pasn_peer_data *dst) 17580 { 17581 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 17582 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 17583 wmi_rtt_pasn_peer_create_req_param *buf; 17584 uint8_t security_mode, i; 17585 17586 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 17587 if (!param_buf) { 17588 wmi_err("Invalid peer_create req buffer"); 17589 return QDF_STATUS_E_INVAL; 17590 } 17591 17592 fixed_param = param_buf->fixed_param; 17593 17594 if (param_buf->num_rtt_pasn_peer_param > 17595 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 17596 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 17597 wmi_err("Invalid TLV size"); 17598 return QDF_STATUS_E_INVAL; 17599 } 17600 17601 if (!param_buf->num_rtt_pasn_peer_param || 17602 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 17603 wmi_err("Invalid num TLV:%d", 17604 param_buf->num_rtt_pasn_peer_param); 17605 return QDF_STATUS_E_INVAL; 17606 } 17607 17608 dst->vdev_id = fixed_param->vdev_id; 17609 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 17610 wmi_err("Invalid vdev id:%d", dst->vdev_id); 17611 return QDF_STATUS_E_INVAL; 17612 } 17613 17614 buf = param_buf->rtt_pasn_peer_param; 17615 if (!buf) { 17616 wmi_err("NULL peer param TLV"); 17617 return QDF_STATUS_E_INVAL; 17618 } 17619 17620 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 17621 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 17622 dst->peer_info[i].self_mac.bytes); 17623 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 17624 dst->peer_info[i].peer_mac.bytes); 17625 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 17626 buf->control_flag); 17627 if (security_mode) 17628 dst->peer_info[i].peer_type = 17629 WLAN_WIFI_POS_PASN_SECURE_PEER; 17630 else 17631 dst->peer_info[i].peer_type = 17632 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 17633 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 17634 dst->peer_info[i].is_ltf_keyseed_required = true; 17635 17636 dst->peer_info[i].force_self_mac_usage = 17637 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 17638 buf->control_flag); 17639 dst->num_peers++; 17640 buf++; 17641 } 17642 17643 return QDF_STATUS_SUCCESS; 17644 } 17645 17646 static QDF_STATUS 17647 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17648 struct wifi_pos_pasn_peer_data *dst) 17649 { 17650 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 17651 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 17652 wmi_rtt_pasn_peer_delete_param *buf; 17653 uint8_t i; 17654 17655 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 17656 if (!param_buf) { 17657 wmi_err("Invalid peer_delete evt buffer"); 17658 return QDF_STATUS_E_INVAL; 17659 } 17660 17661 fixed_param = param_buf->fixed_param; 17662 17663 if (param_buf->num_rtt_pasn_peer_param > 17664 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 17665 sizeof(wmi_rtt_pasn_peer_delete_param))) { 17666 wmi_err("Invalid TLV size"); 17667 return QDF_STATUS_E_INVAL; 17668 } 17669 17670 if (!param_buf->num_rtt_pasn_peer_param || 17671 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 17672 wmi_err("Invalid num TLV:%d", 17673 param_buf->num_rtt_pasn_peer_param); 17674 return QDF_STATUS_E_INVAL; 17675 } 17676 17677 dst->vdev_id = fixed_param->vdev_id; 17678 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 17679 wmi_err("Invalid vdev id:%d", dst->vdev_id); 17680 return QDF_STATUS_E_INVAL; 17681 } 17682 17683 buf = param_buf->rtt_pasn_peer_param; 17684 if (!buf) { 17685 wmi_err("NULL peer param TLV"); 17686 return QDF_STATUS_E_INVAL; 17687 } 17688 17689 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 17690 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 17691 dst->peer_info[i].peer_mac.bytes); 17692 dst->peer_info[i].control_flags = buf->control_flag; 17693 17694 dst->num_peers++; 17695 buf++; 17696 } 17697 17698 return QDF_STATUS_SUCCESS; 17699 } 17700 17701 static QDF_STATUS 17702 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 17703 struct wlan_pasn_auth_status *data) 17704 { 17705 QDF_STATUS status; 17706 wmi_buf_t buf; 17707 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 17708 uint8_t *buf_ptr; 17709 uint8_t i; 17710 size_t len = sizeof(*fixed_param) + 17711 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 17712 WMI_TLV_HDR_SIZE; 17713 17714 buf = wmi_buf_alloc(wmi_handle, len); 17715 if (!buf) { 17716 wmi_err("wmi_buf_alloc failed"); 17717 return QDF_STATUS_E_FAILURE; 17718 } 17719 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17720 fixed_param = 17721 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 17722 WMITLV_SET_HDR(&fixed_param->tlv_header, 17723 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 17724 WMITLV_GET_STRUCT_TLVLEN( 17725 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 17726 buf_ptr += sizeof(*fixed_param); 17727 17728 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 17729 (data->num_peers * 17730 sizeof(wmi_rtt_pasn_auth_status_param))); 17731 buf_ptr += WMI_TLV_HDR_SIZE; 17732 17733 for (i = 0; i < data->num_peers; i++) { 17734 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 17735 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 17736 17737 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 17738 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 17739 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 17740 17741 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 17742 &auth_status_tlv->peer_mac_addr); 17743 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 17744 &auth_status_tlv->source_mac_addr); 17745 auth_status_tlv->status = data->auth_status[i].status; 17746 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 17747 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 17748 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 17749 auth_status_tlv->status); 17750 17751 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 17752 } 17753 17754 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 17755 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17756 WMI_RTT_PASN_AUTH_STATUS_CMD); 17757 if (QDF_IS_STATUS_ERROR(status)) { 17758 wmi_err("Failed to send Auth status command ret = %d", status); 17759 wmi_buf_free(buf); 17760 } 17761 17762 return status; 17763 } 17764 17765 static QDF_STATUS 17766 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 17767 struct qdf_mac_addr *peer_mac) 17768 { 17769 QDF_STATUS status; 17770 wmi_buf_t buf; 17771 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 17772 size_t len = sizeof(*fixed_param); 17773 17774 buf = wmi_buf_alloc(wmi_handle, len); 17775 if (!buf) { 17776 wmi_err("wmi_buf_alloc failed"); 17777 return QDF_STATUS_E_FAILURE; 17778 } 17779 fixed_param = 17780 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 17781 WMITLV_SET_HDR(&fixed_param->tlv_header, 17782 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 17783 WMITLV_GET_STRUCT_TLVLEN( 17784 wmi_rtt_pasn_deauth_cmd_fixed_param)); 17785 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 17786 &fixed_param->peer_mac_addr); 17787 17788 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 17789 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17790 WMI_RTT_PASN_DEAUTH_CMD); 17791 if (QDF_IS_STATUS_ERROR(status)) { 17792 wmi_err("Failed to send pasn deauth command ret = %d", status); 17793 wmi_buf_free(buf); 17794 } 17795 17796 return status; 17797 } 17798 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 17799 17800 static QDF_STATUS 17801 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 17802 struct wlan_crypto_ltf_keyseed_data *data) 17803 { 17804 QDF_STATUS status; 17805 wmi_buf_t buf; 17806 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 17807 uint8_t *buf_ptr; 17808 size_t len = sizeof(*fixed_param) + data->key_seed_len + 17809 WMI_TLV_HDR_SIZE; 17810 17811 buf = wmi_buf_alloc(wmi_handle, len); 17812 if (!buf) { 17813 wmi_err("wmi_buf_alloc failed"); 17814 return QDF_STATUS_E_FAILURE; 17815 } 17816 17817 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17818 fixed_param = 17819 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 17820 WMITLV_SET_HDR(&fixed_param->tlv_header, 17821 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 17822 WMITLV_GET_STRUCT_TLVLEN( 17823 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 17824 17825 fixed_param->vdev_id = data->vdev_id; 17826 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 17827 &fixed_param->peer_macaddr); 17828 fixed_param->key_seed_len = data->key_seed_len; 17829 fixed_param->rsn_authmode = data->rsn_authmode; 17830 17831 buf_ptr += sizeof(*fixed_param); 17832 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 17833 (fixed_param->key_seed_len * sizeof(A_UINT8))); 17834 buf_ptr += WMI_TLV_HDR_SIZE; 17835 17836 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 17837 17838 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 17839 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17840 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 17841 if (QDF_IS_STATUS_ERROR(status)) { 17842 wmi_err("Failed to send ltf keyseed command ret = %d", status); 17843 wmi_buf_free(buf); 17844 } 17845 17846 return status; 17847 } 17848 17849 /** 17850 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 17851 * @wmi_handle: wmi handle 17852 * @event_buf: pointer to event buffer 17853 * @cmd_status: status of HW mode change command 17854 * 17855 * Return QDF_STATUS_SUCCESS on success or proper error code. 17856 */ 17857 static QDF_STATUS 17858 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17859 uint32_t *cmd_status) 17860 { 17861 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 17862 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 17863 17864 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 17865 if (!param_buf) { 17866 wmi_err("Invalid mode change event buffer"); 17867 return QDF_STATUS_E_INVAL; 17868 } 17869 17870 fixed_param = param_buf->fixed_param; 17871 if (!fixed_param) { 17872 wmi_err("Invalid fixed param"); 17873 return QDF_STATUS_E_INVAL; 17874 } 17875 17876 *cmd_status = fixed_param->status; 17877 return QDF_STATUS_SUCCESS; 17878 } 17879 17880 #ifdef FEATURE_ANI_LEVEL_REQUEST 17881 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 17882 uint32_t *freqs, 17883 uint8_t num_freqs) 17884 { 17885 wmi_buf_t buf; 17886 wmi_get_channel_ani_cmd_fixed_param *cmd; 17887 QDF_STATUS ret; 17888 uint32_t len; 17889 A_UINT32 *chan_list; 17890 uint8_t i, *buf_ptr; 17891 17892 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 17893 WMI_TLV_HDR_SIZE + 17894 num_freqs * sizeof(A_UINT32); 17895 17896 buf = wmi_buf_alloc(wmi_handle, len); 17897 if (!buf) 17898 return QDF_STATUS_E_FAILURE; 17899 17900 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17901 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 17902 WMITLV_SET_HDR(&cmd->tlv_header, 17903 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 17904 WMITLV_GET_STRUCT_TLVLEN( 17905 wmi_get_channel_ani_cmd_fixed_param)); 17906 17907 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 17908 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 17909 (num_freqs * sizeof(A_UINT32))); 17910 17911 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 17912 for (i = 0; i < num_freqs; i++) { 17913 chan_list[i] = freqs[i]; 17914 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 17915 } 17916 17917 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17918 WMI_GET_CHANNEL_ANI_CMDID); 17919 17920 if (QDF_IS_STATUS_ERROR(ret)) { 17921 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 17922 wmi_buf_free(buf); 17923 } 17924 17925 return ret; 17926 } 17927 17928 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 17929 struct wmi_host_ani_level_event **info, 17930 uint32_t *num_freqs) 17931 { 17932 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 17933 wmi_get_channel_ani_event_fixed_param *fixed_param; 17934 wmi_channel_ani_info_tlv_param *tlv_params; 17935 uint8_t *buf_ptr, i; 17936 17937 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 17938 if (!param_buf) { 17939 wmi_err("Invalid ani level event buffer"); 17940 return QDF_STATUS_E_INVAL; 17941 } 17942 17943 fixed_param = 17944 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 17945 if (!fixed_param) { 17946 wmi_err("Invalid fixed param"); 17947 return QDF_STATUS_E_INVAL; 17948 } 17949 17950 buf_ptr = (uint8_t *)fixed_param; 17951 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 17952 buf_ptr += WMI_TLV_HDR_SIZE; 17953 17954 *num_freqs = param_buf->num_ani_info; 17955 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 17956 wmi_err("Invalid number of freqs received"); 17957 return QDF_STATUS_E_INVAL; 17958 } 17959 17960 *info = qdf_mem_malloc(*num_freqs * 17961 sizeof(struct wmi_host_ani_level_event)); 17962 if (!(*info)) 17963 return QDF_STATUS_E_NOMEM; 17964 17965 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 17966 for (i = 0; i < param_buf->num_ani_info; i++) { 17967 (*info)[i].ani_level = tlv_params->ani_level; 17968 (*info)[i].chan_freq = tlv_params->chan_freq; 17969 tlv_params++; 17970 } 17971 17972 return QDF_STATUS_SUCCESS; 17973 } 17974 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 17975 17976 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 17977 /** 17978 * convert_wtc_scan_mode() - Function to convert TLV specific 17979 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 17980 * @scan_mode: scan freq scheme coming from firmware 17981 * 17982 * Return: ROAM_TRIGGER_SCAN_MODE 17983 */ 17984 static enum roam_scan_freq_scheme 17985 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 17986 { 17987 switch (scan_mode) { 17988 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 17989 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 17990 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 17991 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 17992 case ROAM_TRIGGER_SCAN_MODE_FULL: 17993 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 17994 default: 17995 return ROAM_SCAN_FREQ_SCHEME_NONE; 17996 } 17997 } 17998 17999 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 18000 { 18001 switch (fw_trig_reason) { 18002 case WMI_ROAM_TRIGGER_REASON_NONE: 18003 return ROAM_TRIGGER_REASON_NONE; 18004 case WMI_ROAM_TRIGGER_REASON_PER: 18005 return ROAM_TRIGGER_REASON_PER; 18006 case WMI_ROAM_TRIGGER_REASON_BMISS: 18007 return ROAM_TRIGGER_REASON_BMISS; 18008 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18009 return ROAM_TRIGGER_REASON_LOW_RSSI; 18010 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18011 return ROAM_TRIGGER_REASON_HIGH_RSSI; 18012 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18013 return ROAM_TRIGGER_REASON_PERIODIC; 18014 case WMI_ROAM_TRIGGER_REASON_MAWC: 18015 return ROAM_TRIGGER_REASON_MAWC; 18016 case WMI_ROAM_TRIGGER_REASON_DENSE: 18017 return ROAM_TRIGGER_REASON_DENSE; 18018 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18019 return ROAM_TRIGGER_REASON_BACKGROUND; 18020 case WMI_ROAM_TRIGGER_REASON_FORCED: 18021 return ROAM_TRIGGER_REASON_FORCED; 18022 case WMI_ROAM_TRIGGER_REASON_BTM: 18023 return ROAM_TRIGGER_REASON_BTM; 18024 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18025 return ROAM_TRIGGER_REASON_UNIT_TEST; 18026 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18027 return ROAM_TRIGGER_REASON_BSS_LOAD; 18028 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18029 return ROAM_TRIGGER_REASON_DEAUTH; 18030 case WMI_ROAM_TRIGGER_REASON_IDLE: 18031 return ROAM_TRIGGER_REASON_IDLE; 18032 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 18033 return ROAM_TRIGGER_REASON_STA_KICKOUT; 18034 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 18035 return ROAM_TRIGGER_REASON_ESS_RSSI; 18036 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18037 return ROAM_TRIGGER_REASON_WTC_BTM; 18038 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 18039 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 18040 case WMI_ROAM_TRIGGER_REASON_BTC: 18041 return ROAM_TRIGGER_REASON_BTC; 18042 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 18043 return ROAM_TRIGGER_REASON_MAX; 18044 default: 18045 return ROAM_TRIGGER_REASON_NONE; 18046 } 18047 } 18048 18049 /** 18050 * extract_roam_11kv_candidate_info - Extract btm candidate info 18051 * @wmi_handle: wmi_handle 18052 * @evt_buf: Event buffer 18053 * @dst_info: Destination buffer 18054 * 18055 * Return: QDF_STATUS 18056 */ 18057 static QDF_STATUS 18058 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 18059 struct wmi_btm_req_candidate_info *dst_info, 18060 uint8_t btm_idx, uint16_t num_cand) 18061 { 18062 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18063 wmi_roam_btm_request_candidate_info *src_data; 18064 uint8_t i; 18065 18066 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18067 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 18068 !param_buf->num_roam_btm_request_candidate_info || 18069 (btm_idx + 18070 num_cand) > param_buf->num_roam_btm_request_candidate_info) 18071 return QDF_STATUS_SUCCESS; 18072 18073 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 18074 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 18075 num_cand = WLAN_MAX_BTM_CANDIDATE; 18076 for (i = 0; i < num_cand; i++) { 18077 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 18078 dst_info->candidate_bssid.bytes); 18079 dst_info->preference = src_data->preference; 18080 src_data++; 18081 dst_info++; 18082 } 18083 18084 return QDF_STATUS_SUCCESS; 18085 } 18086 18087 static enum roam_trigger_sub_reason 18088 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 18089 { 18090 switch (subreason) { 18091 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 18092 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 18093 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 18094 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 18095 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 18096 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 18097 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 18098 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 18099 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 18100 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 18101 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 18102 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 18103 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 18104 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 18105 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 18106 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 18107 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 18108 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 18109 default: 18110 break; 18111 } 18112 18113 return 0; 18114 } 18115 18116 /** 18117 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 18118 * from the WMI_ROAM_STATS_EVENTID 18119 * @wmi_handle: wmi handle 18120 * @evt_buf: Pointer to the event buffer 18121 * @trig: Pointer to destination structure to fill data 18122 * @idx: TLV id 18123 */ 18124 static QDF_STATUS 18125 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18126 struct wmi_roam_trigger_info *trig, uint8_t idx, 18127 uint8_t btm_idx) 18128 { 18129 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18130 wmi_roam_trigger_reason *src_data = NULL; 18131 uint32_t trig_reason; 18132 18133 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18134 if (!param_buf || !param_buf->roam_trigger_reason) 18135 return QDF_STATUS_E_FAILURE; 18136 18137 src_data = ¶m_buf->roam_trigger_reason[idx]; 18138 18139 trig->present = true; 18140 trig_reason = src_data->trigger_reason; 18141 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 18142 trig->trigger_sub_reason = 18143 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 18144 trig->current_rssi = src_data->current_rssi; 18145 trig->timestamp = src_data->timestamp; 18146 18147 switch (trig_reason) { 18148 case WMI_ROAM_TRIGGER_REASON_PER: 18149 case WMI_ROAM_TRIGGER_REASON_BMISS: 18150 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18151 case WMI_ROAM_TRIGGER_REASON_MAWC: 18152 case WMI_ROAM_TRIGGER_REASON_DENSE: 18153 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18154 case WMI_ROAM_TRIGGER_REASON_IDLE: 18155 case WMI_ROAM_TRIGGER_REASON_FORCED: 18156 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18157 case WMI_ROAM_TRIGGER_REASON_BTC: 18158 return QDF_STATUS_SUCCESS; 18159 18160 case WMI_ROAM_TRIGGER_REASON_BTM: 18161 trig->btm_trig_data.btm_request_mode = 18162 src_data->btm_request_mode; 18163 trig->btm_trig_data.disassoc_timer = 18164 src_data->disassoc_imminent_timer; 18165 trig->btm_trig_data.validity_interval = 18166 src_data->validity_internal; 18167 trig->btm_trig_data.candidate_list_count = 18168 src_data->candidate_list_count; 18169 trig->btm_trig_data.btm_resp_status = 18170 src_data->btm_response_status_code; 18171 trig->btm_trig_data.btm_bss_termination_timeout = 18172 src_data->btm_bss_termination_timeout; 18173 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18174 src_data->btm_mbo_assoc_retry_timeout; 18175 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 18176 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 18177 param_buf->num_roam_btm_request_candidate_info) 18178 extract_roam_11kv_candidate_info( 18179 wmi_handle, evt_buf, 18180 trig->btm_trig_data.btm_cand, 18181 btm_idx, 18182 src_data->candidate_list_count); 18183 18184 return QDF_STATUS_SUCCESS; 18185 18186 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18187 trig->cu_trig_data.cu_load = src_data->cu_load; 18188 return QDF_STATUS_SUCCESS; 18189 18190 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18191 trig->deauth_trig_data.type = src_data->deauth_type; 18192 trig->deauth_trig_data.reason = src_data->deauth_reason; 18193 return QDF_STATUS_SUCCESS; 18194 18195 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18196 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18197 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 18198 return QDF_STATUS_SUCCESS; 18199 18200 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18201 trig->wtc_btm_trig_data.roaming_mode = 18202 src_data->vendor_specific1[0]; 18203 trig->wtc_btm_trig_data.vsie_trigger_reason = 18204 src_data->vendor_specific1[1]; 18205 trig->wtc_btm_trig_data.sub_code = 18206 src_data->vendor_specific1[2]; 18207 trig->wtc_btm_trig_data.wtc_mode = 18208 src_data->vendor_specific1[3]; 18209 trig->wtc_btm_trig_data.wtc_scan_mode = 18210 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 18211 trig->wtc_btm_trig_data.wtc_rssi_th = 18212 src_data->vendor_specific1[5]; 18213 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 18214 src_data->vendor_specific1[6]; 18215 18216 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 18217 src_data->vendor_specific2[0]; 18218 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 18219 src_data->vendor_specific2[1]; 18220 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 18221 src_data->vendor_specific2[2]; 18222 trig->wtc_btm_trig_data.duration = 18223 src_data->vendor_specific2[3]; 18224 18225 return QDF_STATUS_SUCCESS; 18226 default: 18227 return QDF_STATUS_SUCCESS; 18228 } 18229 18230 return QDF_STATUS_SUCCESS; 18231 } 18232 18233 /** 18234 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 18235 * from the WMI_ROAM_STATS_EVENTID 18236 * @wmi_handle: wmi handle 18237 * @evt_buf: Pointer to the event buffer 18238 * @dst: Pointer to destination structure to fill data 18239 * @ap_idx: TLV index for this roam scan 18240 * @num_cand: number of candidates list in the roam scan 18241 */ 18242 static QDF_STATUS 18243 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18244 struct wmi_roam_candidate_info *dst, 18245 uint8_t ap_idx, uint16_t num_cand) 18246 { 18247 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18248 wmi_roam_ap_info *src = NULL; 18249 uint8_t i; 18250 18251 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18252 if (!param_buf) { 18253 wmi_err("Param buf is NULL"); 18254 return QDF_STATUS_E_FAILURE; 18255 } 18256 18257 if (ap_idx >= param_buf->num_roam_ap_info) { 18258 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 18259 ap_idx, param_buf->num_roam_ap_info); 18260 return QDF_STATUS_E_FAILURE; 18261 } 18262 18263 src = ¶m_buf->roam_ap_info[ap_idx]; 18264 18265 for (i = 0; i < num_cand; i++) { 18266 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 18267 dst->type = src->candidate_type; 18268 dst->freq = src->channel; 18269 dst->etp = src->etp; 18270 dst->rssi = src->rssi; 18271 dst->rssi_score = src->rssi_score; 18272 dst->cu_load = src->cu_load; 18273 dst->cu_score = src->cu_score; 18274 dst->total_score = src->total_score; 18275 dst->timestamp = src->timestamp; 18276 dst->dl_reason = src->bl_reason; 18277 dst->dl_source = src->bl_source; 18278 dst->dl_timestamp = src->bl_timestamp; 18279 dst->dl_original_timeout = src->bl_original_timeout; 18280 18281 src++; 18282 dst++; 18283 } 18284 18285 return QDF_STATUS_SUCCESS; 18286 } 18287 18288 /** 18289 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18290 * from the WMI_ROAM_STATS_EVENTID 18291 * @wmi_handle: wmi handle 18292 * @evt_buf: Pointer to the event buffer 18293 * @dst: Pointer to destination structure to fill data 18294 * @idx: TLV id 18295 * @chan_idx: Index of the channel tlv for the current roam trigger 18296 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 18297 */ 18298 static QDF_STATUS 18299 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18300 struct wmi_roam_scan_data *dst, uint8_t idx, 18301 uint8_t chan_idx, uint8_t ap_idx) 18302 { 18303 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18304 wmi_roam_scan_info *src_data = NULL; 18305 wmi_roam_scan_channel_info *src_chan = NULL; 18306 QDF_STATUS status; 18307 uint8_t i; 18308 18309 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18310 if (!param_buf || !param_buf->roam_scan_info || 18311 idx >= param_buf->num_roam_scan_info) 18312 return QDF_STATUS_E_FAILURE; 18313 18314 src_data = ¶m_buf->roam_scan_info[idx]; 18315 18316 dst->present = true; 18317 dst->type = src_data->roam_scan_type; 18318 dst->num_chan = src_data->roam_scan_channel_count; 18319 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 18320 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 18321 dst->frame_info_count = src_data->frame_info_count; 18322 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 18323 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 18324 18325 /* Read the channel data only for dst->type is 0 (partial scan) */ 18326 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 18327 chan_idx < param_buf->num_roam_scan_chan_info) { 18328 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 18329 dst->num_chan = MAX_ROAM_SCAN_CHAN; 18330 18331 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 18332 for (i = 0; i < dst->num_chan; i++) { 18333 dst->chan_freq[i] = src_chan->channel; 18334 src_chan++; 18335 } 18336 } 18337 18338 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 18339 return QDF_STATUS_SUCCESS; 18340 18341 dst->num_ap = src_data->roam_ap_count; 18342 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 18343 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 18344 18345 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 18346 ap_idx, dst->num_ap); 18347 if (QDF_IS_STATUS_ERROR(status)) { 18348 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 18349 return status; 18350 } 18351 18352 return QDF_STATUS_SUCCESS; 18353 } 18354 18355 /** 18356 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 18357 * @wmi_roam_fail_reason: roam fail enum 18358 * 18359 * Return: Roaming failure reason codes 18360 */ 18361 static enum wlan_roam_failure_reason_code 18362 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 18363 { 18364 switch (wmi_roam_fail_reason) { 18365 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 18366 return ROAM_FAIL_REASON_NO_SCAN_START; 18367 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 18368 return ROAM_FAIL_REASON_NO_AP_FOUND; 18369 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 18370 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 18371 case WMI_ROAM_FAIL_REASON_HOST: 18372 return ROAM_FAIL_REASON_HOST; 18373 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 18374 return ROAM_FAIL_REASON_AUTH_SEND; 18375 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 18376 return ROAM_FAIL_REASON_AUTH_RECV; 18377 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 18378 return ROAM_FAIL_REASON_NO_AUTH_RESP; 18379 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 18380 return ROAM_FAIL_REASON_REASSOC_SEND; 18381 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 18382 return ROAM_FAIL_REASON_REASSOC_RECV; 18383 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 18384 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 18385 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 18386 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 18387 case WMI_ROAM_FAIL_REASON_MLME: 18388 return ROAM_FAIL_REASON_MLME; 18389 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 18390 return ROAM_FAIL_REASON_INTERNAL_ABORT; 18391 case WMI_ROAM_FAIL_REASON_SCAN_START: 18392 return ROAM_FAIL_REASON_SCAN_START; 18393 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 18394 return ROAM_FAIL_REASON_AUTH_NO_ACK; 18395 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 18396 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 18397 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 18398 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 18399 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 18400 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 18401 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 18402 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 18403 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 18404 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 18405 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 18406 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 18407 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 18408 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 18409 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 18410 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 18411 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 18412 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 18413 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 18414 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 18415 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 18416 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 18417 case WMI_ROAM_FAIL_REASON_DISCONNECT: 18418 return ROAM_FAIL_REASON_DISCONNECT; 18419 case WMI_ROAM_FAIL_REASON_SYNC: 18420 return ROAM_FAIL_REASON_SYNC; 18421 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 18422 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 18423 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 18424 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 18425 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 18426 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 18427 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 18428 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 18429 default: 18430 return ROAM_FAIL_REASON_UNKNOWN; 18431 } 18432 } 18433 18434 /** 18435 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18436 * from the WMI_ROAM_STATS_EVENTID 18437 * @wmi_handle: wmi handle 18438 * @evt_buf: Pointer to the event buffer 18439 * @dst: Pointer to destination structure to fill data 18440 * @idx: TLV id 18441 */ 18442 static QDF_STATUS 18443 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18444 struct wmi_roam_result *dst, uint8_t idx) 18445 { 18446 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18447 wmi_roam_result *src_data = NULL; 18448 18449 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18450 if (!param_buf || !param_buf->roam_result || 18451 idx >= param_buf->num_roam_result) 18452 return QDF_STATUS_E_FAILURE; 18453 18454 src_data = ¶m_buf->roam_result[idx]; 18455 18456 dst->present = true; 18457 dst->status = src_data->roam_status; 18458 dst->timestamp = src_data->timestamp; 18459 dst->fail_reason = 18460 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 18461 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 18462 18463 return QDF_STATUS_SUCCESS; 18464 } 18465 18466 /** 18467 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 18468 * from the WMI_ROAM_STATS_EVENTID 18469 * @wmi_handle: wmi handle 18470 * @evt_buf: Pointer to the event buffer 18471 * @dst: Pointer to destination structure to fill data 18472 * @idx: TLV id 18473 * @rpt_idx: Neighbor report Channel index 18474 */ 18475 static QDF_STATUS 18476 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18477 struct wmi_neighbor_report_data *dst, 18478 uint8_t idx, uint8_t rpt_idx) 18479 { 18480 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18481 wmi_roam_neighbor_report_info *src_data = NULL; 18482 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 18483 uint8_t i; 18484 18485 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18486 if (!param_buf || !param_buf->roam_neighbor_report_info || 18487 !param_buf->num_roam_neighbor_report_info || 18488 idx >= param_buf->num_roam_neighbor_report_info) { 18489 wmi_debug("Invalid 1kv param buf"); 18490 return QDF_STATUS_E_FAILURE; 18491 } 18492 18493 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 18494 18495 dst->present = true; 18496 dst->req_type = src_data->request_type; 18497 dst->num_freq = src_data->neighbor_report_channel_count; 18498 dst->req_time = src_data->neighbor_report_request_timestamp; 18499 dst->resp_time = src_data->neighbor_report_response_timestamp; 18500 dst->btm_query_token = src_data->btm_query_token; 18501 dst->btm_query_reason = src_data->btm_query_reason_code; 18502 18503 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 18504 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 18505 return QDF_STATUS_SUCCESS; 18506 18507 if (!param_buf->roam_neighbor_report_chan_info) { 18508 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 18509 dst->num_freq); 18510 dst->num_freq = 0; 18511 /* return success as its optional tlv and we can print neighbor 18512 * report received info 18513 */ 18514 return QDF_STATUS_SUCCESS; 18515 } 18516 18517 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 18518 18519 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 18520 dst->num_freq = MAX_ROAM_SCAN_CHAN; 18521 18522 for (i = 0; i < dst->num_freq; i++) { 18523 dst->freq[i] = src_freq->channel; 18524 src_freq++; 18525 } 18526 18527 return QDF_STATUS_SUCCESS; 18528 } 18529 18530 /** 18531 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 18532 * @wmi_handle : handle to WMI. 18533 * @roam_param : pointer to hold roam set parameter 18534 * 18535 * Return: 0 on success and -ve on failure. 18536 */ 18537 static QDF_STATUS 18538 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 18539 struct vdev_set_params *roam_param) 18540 { 18541 QDF_STATUS ret; 18542 wmi_roam_set_param_cmd_fixed_param *cmd; 18543 wmi_buf_t buf; 18544 uint16_t len = sizeof(*cmd); 18545 18546 buf = wmi_buf_alloc(wmi_handle, len); 18547 if (!buf) 18548 return QDF_STATUS_E_NOMEM; 18549 18550 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 18551 WMITLV_SET_HDR(&cmd->tlv_header, 18552 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 18553 WMITLV_GET_STRUCT_TLVLEN 18554 (wmi_roam_set_param_cmd_fixed_param)); 18555 cmd->vdev_id = roam_param->vdev_id; 18556 cmd->param_id = roam_param->param_id; 18557 cmd->param_value = roam_param->param_value; 18558 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 18559 cmd->vdev_id, cmd->param_id, cmd->param_value); 18560 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 18561 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18562 WMI_ROAM_SET_PARAM_CMDID); 18563 if (QDF_IS_STATUS_ERROR(ret)) { 18564 wmi_err("Failed to send roam set param command, ret = %d", ret); 18565 wmi_buf_free(buf); 18566 } 18567 18568 return ret; 18569 } 18570 #else 18571 static inline QDF_STATUS 18572 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18573 struct wmi_roam_trigger_info *trig, uint8_t idx, 18574 uint8_t btm_idx) 18575 { 18576 return QDF_STATUS_E_NOSUPPORT; 18577 } 18578 18579 static inline QDF_STATUS 18580 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18581 struct wmi_roam_result *dst, uint8_t idx) 18582 { 18583 return QDF_STATUS_E_NOSUPPORT; 18584 } 18585 18586 static QDF_STATUS 18587 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18588 struct wmi_neighbor_report_data *dst, 18589 uint8_t idx, uint8_t rpt_idx) 18590 { 18591 return QDF_STATUS_E_NOSUPPORT; 18592 } 18593 18594 static QDF_STATUS 18595 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18596 struct wmi_roam_scan_data *dst, uint8_t idx, 18597 uint8_t chan_idx, uint8_t ap_idx) 18598 { 18599 return QDF_STATUS_E_NOSUPPORT; 18600 } 18601 #endif 18602 18603 #ifdef WLAN_FEATURE_PKT_CAPTURE 18604 static QDF_STATUS 18605 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 18606 struct mgmt_offload_event_params *params) 18607 { 18608 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 18609 wmi_mgmt_hdr *hdr; 18610 18611 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 18612 if (!param_tlvs) 18613 return QDF_STATUS_E_INVAL; 18614 18615 hdr = param_tlvs->fixed_param; 18616 if (!hdr) 18617 return QDF_STATUS_E_INVAL; 18618 18619 if (hdr->buf_len > param_tlvs->num_bufp) 18620 return QDF_STATUS_E_INVAL; 18621 18622 params->tsf_l32 = hdr->tsf_l32; 18623 params->chan_freq = hdr->chan_freq; 18624 params->rate_kbps = hdr->rate_kbps; 18625 params->rssi = hdr->rssi; 18626 params->buf_len = hdr->buf_len; 18627 params->tx_status = hdr->tx_status; 18628 params->buf = param_tlvs->bufp; 18629 params->tx_retry_cnt = hdr->tx_retry_cnt; 18630 return QDF_STATUS_SUCCESS; 18631 } 18632 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 18633 18634 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 18635 static QDF_STATUS 18636 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 18637 struct smu_event_params *params) 18638 { 18639 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 18640 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 18641 18642 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 18643 if (!param_buf) { 18644 wmi_err("Invalid smart monitor event"); 18645 return QDF_STATUS_E_INVAL; 18646 } 18647 18648 smu_event = param_buf->fixed_param; 18649 if (!smu_event) { 18650 wmi_err("smart monitor event fixed param is NULL"); 18651 return QDF_STATUS_E_INVAL; 18652 } 18653 18654 params->vdev_id = smu_event->vdev_id; 18655 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 18656 return QDF_STATUS_E_INVAL; 18657 18658 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 18659 18660 return QDF_STATUS_SUCCESS; 18661 } 18662 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 18663 18664 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 18665 /** 18666 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 18667 * 18668 * @wmi: wmi handle 18669 * @vdev_id: vdev id 18670 * @burst_mode: Indicates whether relation derived using FTM is needed for 18671 * each FTM frame or only aggregated result is required. 18672 * 18673 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 18674 * 18675 * Return: QDF_STATUS 18676 */ 18677 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 18678 uint32_t vdev_id, 18679 bool burst_mode) 18680 { 18681 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 18682 wmi_buf_t buf; 18683 int32_t len = sizeof(*cmd); 18684 18685 buf = wmi_buf_alloc(wmi, len); 18686 if (!buf) { 18687 wmi_err("wmi_buf_alloc failed"); 18688 return QDF_STATUS_E_NOMEM; 18689 } 18690 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 18691 WMITLV_SET_HDR(&cmd->tlv_header, 18692 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 18693 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 18694 cmd->vdev_id = vdev_id; 18695 cmd->agg_relation = burst_mode ? false : true; 18696 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 18697 wmi_err("Failed to send audio sync trigger cmd"); 18698 wmi_buf_free(buf); 18699 return QDF_STATUS_E_FAILURE; 18700 } 18701 18702 return QDF_STATUS_SUCCESS; 18703 } 18704 18705 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 18706 uint32_t vdev_id, 18707 uint64_t lpass_ts) 18708 { 18709 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 18710 wmi_buf_t buf; 18711 int32_t len = sizeof(*cmd); 18712 18713 buf = wmi_buf_alloc(wmi, len); 18714 if (!buf) { 18715 wmi_err("wmi_buf_alloc failed"); 18716 return QDF_STATUS_E_NOMEM; 18717 } 18718 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 18719 WMITLV_SET_HDR(&cmd->tlv_header, 18720 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 18721 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 18722 cmd->vdev_id = vdev_id; 18723 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 18724 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 18725 18726 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 18727 wmi_err("Failed to send audio qtime command"); 18728 wmi_buf_free(buf); 18729 return QDF_STATUS_E_FAILURE; 18730 } 18731 18732 return QDF_STATUS_SUCCESS; 18733 } 18734 18735 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 18736 wmi_unified_t wmi, void *buf, 18737 struct ftm_time_sync_start_stop_params *param) 18738 { 18739 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 18740 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 18741 18742 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 18743 if (!param_buf) { 18744 wmi_err("Invalid audio sync start stop event buffer"); 18745 return QDF_STATUS_E_FAILURE; 18746 } 18747 18748 resp_event = param_buf->fixed_param; 18749 if (!resp_event) { 18750 wmi_err("Invalid audio sync start stop fixed param buffer"); 18751 return QDF_STATUS_E_FAILURE; 18752 } 18753 18754 param->vdev_id = resp_event->vdev_id; 18755 param->timer_interval = resp_event->periodicity; 18756 param->num_reads = resp_event->reads_needed; 18757 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 18758 resp_event->qtimer_l32; 18759 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 18760 resp_event->mac_timer_l32; 18761 18762 wmi_debug("FTM time sync time_interval %d, num_reads %d", 18763 param->timer_interval, param->num_reads); 18764 18765 return QDF_STATUS_SUCCESS; 18766 } 18767 18768 static QDF_STATUS 18769 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 18770 struct ftm_time_sync_offset *param) 18771 { 18772 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 18773 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 18774 wmi_audio_sync_q_master_slave_times *q_pair; 18775 int iter; 18776 18777 param_buf = 18778 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 18779 if (!param_buf) { 18780 wmi_err("Invalid timesync ftm offset event buffer"); 18781 return QDF_STATUS_E_FAILURE; 18782 } 18783 18784 resp_event = param_buf->fixed_param; 18785 if (!resp_event) { 18786 wmi_err("Invalid timesync ftm offset fixed param buffer"); 18787 return QDF_STATUS_E_FAILURE; 18788 } 18789 18790 param->vdev_id = resp_event->vdev_id; 18791 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 18792 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 18793 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 18794 18795 q_pair = param_buf->audio_sync_q_master_slave_times; 18796 if (!q_pair) { 18797 wmi_err("Invalid q_master_slave_times buffer"); 18798 return QDF_STATUS_E_FAILURE; 18799 } 18800 18801 for (iter = 0; iter < param->num_qtime; iter++) { 18802 param->pairs[iter].qtime_initiator = ( 18803 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 18804 q_pair[iter].qmaster_l32; 18805 param->pairs[iter].qtime_target = ( 18806 (uint64_t)q_pair[iter].qslave_u32 << 32) | 18807 q_pair[iter].qslave_l32; 18808 } 18809 return QDF_STATUS_SUCCESS; 18810 } 18811 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 18812 18813 /** 18814 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 18815 * @wmi: wmi handle 18816 * @vdev_id: vdev id 18817 * 18818 * TSF_TSTAMP_READ_VALUE is the only operation supported 18819 * Return: QDF_STATUS_SUCCESS for success or erro code 18820 */ 18821 static QDF_STATUS 18822 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 18823 { 18824 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 18825 wmi_buf_t buf; 18826 int32_t len = sizeof(*cmd); 18827 18828 buf = wmi_buf_alloc(wmi, len); 18829 if (!buf) 18830 return QDF_STATUS_E_NOMEM; 18831 18832 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 18833 WMITLV_SET_HDR(&cmd->tlv_header, 18834 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 18835 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 18836 cmd->vdev_id = vdev_id; 18837 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 18838 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 18839 if (wmi_unified_cmd_send(wmi, buf, len, 18840 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 18841 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 18842 __func__); 18843 wmi_buf_free(buf); 18844 return QDF_STATUS_E_FAILURE; 18845 } 18846 18847 return QDF_STATUS_SUCCESS; 18848 } 18849 18850 /** 18851 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 18852 * @wmi_handle: wmi handle 18853 * @param evt_buf: pointer to event buffer 18854 * @wmi_host_tsf_event param: Pointer to struct to hold event info 18855 * 18856 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 18857 */ 18858 static QDF_STATUS 18859 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18860 struct wmi_host_tsf_event *param) 18861 { 18862 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 18863 wmi_vdev_tsf_report_event_fixed_param *evt; 18864 18865 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 18866 if (!param_buf) { 18867 wmi_err("Invalid tsf report event buffer"); 18868 return QDF_STATUS_E_INVAL; 18869 } 18870 18871 evt = param_buf->fixed_param; 18872 param->vdev_id = evt->vdev_id; 18873 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 18874 param->tsf_low = evt->tsf_low; 18875 param->tsf_high = evt->tsf_high; 18876 param->qtimer_low = evt->qtimer_low; 18877 param->qtimer_high = evt->qtimer_high; 18878 param->tsf_id = evt->tsf_id; 18879 param->tsf_id_valid = evt->tsf_id_valid; 18880 param->mac_id = evt->mac_id; 18881 param->mac_id_valid = evt->mac_id_valid; 18882 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 18883 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 18884 param->tqm_timer_low = evt->tqm_timer_low; 18885 param->tqm_timer_high = evt->tqm_timer_high; 18886 param->use_tqm_timer = evt->use_tqm_timer; 18887 18888 return QDF_STATUS_SUCCESS; 18889 } 18890 18891 /** 18892 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18893 * status tlv 18894 * @wmi_handle: wmi handle 18895 * @param evt_buf: pointer to event buffer 18896 * @param param: Pointer to hold csa switch count status event param 18897 * 18898 * Return: QDF_STATUS_SUCCESS for success or error code 18899 */ 18900 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18901 wmi_unified_t wmi_handle, 18902 void *evt_buf, 18903 struct pdev_csa_switch_count_status *param) 18904 { 18905 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18906 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18907 18908 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18909 evt_buf; 18910 if (!param_buf) { 18911 wmi_err("Invalid CSA status event"); 18912 return QDF_STATUS_E_INVAL; 18913 } 18914 18915 csa_status = param_buf->fixed_param; 18916 18917 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18918 wmi_handle, 18919 csa_status->pdev_id); 18920 param->current_switch_count = csa_status->current_switch_count; 18921 param->num_vdevs = csa_status->num_vdevs; 18922 param->vdev_ids = param_buf->vdev_ids; 18923 18924 return QDF_STATUS_SUCCESS; 18925 } 18926 18927 #ifdef CONFIG_AFC_SUPPORT 18928 /** 18929 * send_afc_cmd_tlv() - Sends the AFC indication to FW 18930 * @wmi_handle: wmi handle 18931 * @pdev_id: Pdev id 18932 * @param: Pointer to hold AFC indication. 18933 * 18934 * Return: QDF_STATUS_SUCCESS for success or error code 18935 */ 18936 static 18937 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 18938 uint8_t pdev_id, 18939 struct reg_afc_resp_rx_ind_info *param) 18940 { 18941 wmi_buf_t buf; 18942 wmi_afc_cmd_fixed_param *cmd; 18943 uint32_t len; 18944 uint8_t *buf_ptr; 18945 QDF_STATUS ret; 18946 18947 len = sizeof(wmi_afc_cmd_fixed_param); 18948 buf = wmi_buf_alloc(wmi_handle, len); 18949 if (!buf) 18950 return QDF_STATUS_E_NOMEM; 18951 18952 buf_ptr = (uint8_t *)wmi_buf_data(buf); 18953 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 18954 18955 WMITLV_SET_HDR(&cmd->tlv_header, 18956 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 18957 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 18958 18959 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 18960 wmi_handle, 18961 pdev_id); 18962 cmd->cmd_type = param->cmd_type; 18963 cmd->serv_resp_format = param->serv_resp_format; 18964 18965 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 18966 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 18967 if (QDF_IS_STATUS_ERROR(ret)) { 18968 wmi_err("Failed to send WMI_AFC_CMDID"); 18969 wmi_buf_free(buf); 18970 return QDF_STATUS_E_FAILURE; 18971 } 18972 18973 return QDF_STATUS_SUCCESS; 18974 } 18975 #endif 18976 18977 /** 18978 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 18979 * @wmi_handle: wmi handle 18980 * @param: Pointer to hold TX power info 18981 * 18982 * Return: QDF_STATUS_SUCCESS for success or error code 18983 */ 18984 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 18985 uint8_t vdev_id, 18986 struct reg_tpc_power_info *param) 18987 { 18988 wmi_buf_t buf; 18989 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 18990 wmi_vdev_ch_power_info *ch_power_info; 18991 uint8_t *buf_ptr; 18992 uint16_t idx; 18993 uint32_t len; 18994 QDF_STATUS ret; 18995 18996 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 18997 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 18998 18999 buf = wmi_buf_alloc(wmi_handle, len); 19000 if (!buf) 19001 return QDF_STATUS_E_NOMEM; 19002 19003 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19004 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 19005 19006 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 19007 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 19008 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 19009 19010 tpc_power_info_param->vdev_id = vdev_id; 19011 tpc_power_info_param->psd_power = param->is_psd_power; 19012 tpc_power_info_param->eirp_power = param->eirp_power; 19013 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 19014 wmi_debug("eirp_power = %d is_psd_power = %d power_type_6ghz = %d", 19015 tpc_power_info_param->eirp_power, 19016 tpc_power_info_param->psd_power, 19017 tpc_power_info_param->power_type_6ghz); 19018 19019 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 19020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19021 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 19022 19023 buf_ptr += WMI_TLV_HDR_SIZE; 19024 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 19025 19026 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 19027 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 19028 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 19029 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 19030 ch_power_info[idx].chan_cfreq = 19031 param->chan_power_info[idx].chan_cfreq; 19032 ch_power_info[idx].tx_power = 19033 param->chan_power_info[idx].tx_power; 19034 wmi_debug("chan_cfreq = %d tx_power = %d", 19035 ch_power_info[idx].chan_cfreq, 19036 ch_power_info[idx].tx_power); 19037 buf_ptr += sizeof(wmi_vdev_ch_power_info); 19038 } 19039 19040 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 19041 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19042 WMI_VDEV_SET_TPC_POWER_CMDID); 19043 if (QDF_IS_STATUS_ERROR(ret)) 19044 wmi_buf_free(buf); 19045 19046 19047 return ret; 19048 } 19049 19050 /** 19051 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 19052 * @wmi_handle: wmi handle 19053 * @evt_buf: event buffer 19054 * @param: dpd status info 19055 * 19056 * Return: QDF_STATUS_SUCCESS for success or error code 19057 */ 19058 static QDF_STATUS 19059 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 19060 void *evt_buf, 19061 struct wmi_host_pdev_get_dpd_status_event *param) 19062 { 19063 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 19064 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 19065 19066 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 19067 if (!param_buf) { 19068 wmi_err("Invalid get dpd_status event"); 19069 return QDF_STATUS_E_INVAL; 19070 } 19071 19072 dpd_status = param_buf->fixed_param; 19073 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19074 (wmi_handle, dpd_status->pdev_id); 19075 param->dpd_status = dpd_status->dpd_status; 19076 19077 return QDF_STATUS_SUCCESS; 19078 } 19079 19080 static int 19081 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 19082 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 19083 { 19084 if (status->halphy_cal_valid_bmap && valid_bit) 19085 return (status->halphy_cal_status && valid_bit); 19086 19087 return 0; 19088 } 19089 19090 static QDF_STATUS 19091 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 19092 void *evt_buf, 19093 struct wmi_host_pdev_get_halphy_cal_status_event *param) 19094 { 19095 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 19096 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 19097 19098 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 19099 if (!param_buf) { 19100 wmi_err("Invalid get halphy cal status event"); 19101 return QDF_STATUS_E_INVAL; 19102 } 19103 19104 halphy_cal_status = param_buf->fixed_param; 19105 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19106 (wmi_handle, halphy_cal_status->pdev_id); 19107 param->halphy_cal_adc_status = 19108 convert_halphy_status(halphy_cal_status, 19109 WMI_HALPHY_CAL_ADC_BMAP); 19110 param->halphy_cal_bwfilter_status = 19111 convert_halphy_status(halphy_cal_status, 19112 WMI_HALPHY_CAL_BWFILTER_BMAP); 19113 param->halphy_cal_pdet_and_pal_status = 19114 convert_halphy_status(halphy_cal_status, 19115 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 19116 param->halphy_cal_rxdco_status = 19117 convert_halphy_status(halphy_cal_status, 19118 WMI_HALPHY_CAL_RXDCO_BMAP); 19119 param->halphy_cal_comb_txiq_rxiq_status = 19120 convert_halphy_status(halphy_cal_status, 19121 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 19122 param->halphy_cal_ibf_status = 19123 convert_halphy_status(halphy_cal_status, 19124 WMI_HALPHY_CAL_IBF_BMAP); 19125 param->halphy_cal_pa_droop_status = 19126 convert_halphy_status(halphy_cal_status, 19127 WMI_HALPHY_CAL_PA_DROOP_BMAP); 19128 param->halphy_cal_dac_status = 19129 convert_halphy_status(halphy_cal_status, 19130 WMI_HALPHY_CAL_DAC_BMAP); 19131 param->halphy_cal_ani_status = 19132 convert_halphy_status(halphy_cal_status, 19133 WMI_HALPHY_CAL_ANI_BMAP); 19134 param->halphy_cal_noise_floor_status = 19135 convert_halphy_status(halphy_cal_status, 19136 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 19137 19138 return QDF_STATUS_SUCCESS; 19139 } 19140 19141 /** 19142 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 19143 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 19144 * 19145 * Return: host_set_halphy_cal_status 19146 */ 19147 static enum wmi_host_set_halphy_cal_status 19148 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 19149 { 19150 if (fw_status == 0) 19151 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 19152 else if (fw_status == 1) 19153 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19154 19155 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 19156 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19157 } 19158 19159 /** 19160 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 19161 * @wmi_handle: wmi handle 19162 * @evt_buf: event buffer 19163 * @param: set halphy cal status info 19164 * 19165 * Return: QDF_STATUS_SUCCESS for success or error code 19166 */ 19167 static QDF_STATUS 19168 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 19169 void *evt_buf, 19170 struct wmi_host_pdev_set_halphy_cal_event *param) 19171 { 19172 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 19173 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 19174 19175 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 19176 if (!param_buf) { 19177 wmi_err("Invalid set halphy_status event"); 19178 return QDF_STATUS_E_INVAL; 19179 } 19180 19181 set_halphy_status = param_buf->fixed_param; 19182 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19183 (wmi_handle, set_halphy_status->pdev_id); 19184 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 19185 19186 return QDF_STATUS_SUCCESS; 19187 } 19188 19189 /** 19190 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 19191 * @wmi_handle: wmi handle 19192 * @evt_buf: pointer to event buffer 19193 * @len: length of the event buffer 19194 * @param: Pointer to hold install key complete event param 19195 * 19196 * Return: QDF_STATUS_SUCCESS for success or error code 19197 */ 19198 static QDF_STATUS 19199 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 19200 void *evt_buf, uint32_t len, 19201 struct wmi_install_key_comp_event *param) 19202 { 19203 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 19204 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 19205 19206 if (len < sizeof(*param_buf)) { 19207 wmi_err("invalid event buf len %d", len); 19208 return QDF_STATUS_E_INVAL; 19209 } 19210 19211 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 19212 if (!param_buf) { 19213 wmi_err("received null buf from target"); 19214 return QDF_STATUS_E_INVAL; 19215 } 19216 19217 key_fp = param_buf->fixed_param; 19218 if (!key_fp) { 19219 wmi_err("received null event data from target"); 19220 return QDF_STATUS_E_INVAL; 19221 } 19222 19223 param->vdev_id = key_fp->vdev_id; 19224 param->key_ix = key_fp->key_ix; 19225 param->key_flags = key_fp->key_flags; 19226 param->status = key_fp->status; 19227 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 19228 param->peer_macaddr); 19229 19230 return QDF_STATUS_SUCCESS; 19231 } 19232 19233 static QDF_STATUS 19234 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 19235 struct wmi_host_send_set_halphy_cal_info *param) 19236 { 19237 wmi_buf_t buf; 19238 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 19239 QDF_STATUS ret; 19240 uint32_t len; 19241 19242 len = sizeof(*cmd); 19243 19244 buf = wmi_buf_alloc(wmi_handle, len); 19245 if (!buf) 19246 return QDF_STATUS_E_FAILURE; 19247 19248 cmd = (void *)wmi_buf_data(buf); 19249 19250 WMITLV_SET_HDR(&cmd->tlv_header, 19251 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 19252 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 19253 19254 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 19255 param->pdev_id); 19256 cmd->online_halphy_cals_bmap = param->value; 19257 cmd->home_scan_channel = param->chan_sel; 19258 19259 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19260 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 19261 if (QDF_IS_STATUS_ERROR(ret)) { 19262 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 19263 wmi_buf_free(buf); 19264 } 19265 19266 return ret; 19267 } 19268 19269 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19270 /** 19271 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 19272 * @wmi: wmi handle 19273 * @params: set MAC address command params 19274 * 19275 * Return: QDF_STATUS_SUCCESS for success or error code 19276 */ 19277 static QDF_STATUS 19278 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 19279 struct set_mac_addr_params *params) 19280 { 19281 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 19282 wmi_buf_t buf; 19283 int32_t len = sizeof(*cmd); 19284 19285 buf = wmi_buf_alloc(wmi, len); 19286 if (!buf) 19287 return QDF_STATUS_E_NOMEM; 19288 19289 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 19290 WMITLV_SET_HDR( 19291 &cmd->tlv_header, 19292 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 19293 WMITLV_GET_STRUCT_TLVLEN 19294 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 19295 cmd->vdev_id = params->vdev_id; 19296 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 19297 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 19298 19299 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 19300 QDF_MAC_ADDR_FMT, cmd->vdev_id, 19301 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 19302 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 19303 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 19304 if (wmi_unified_cmd_send(wmi, buf, len, 19305 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 19306 wmi_buf_free(buf); 19307 return QDF_STATUS_E_FAILURE; 19308 } 19309 19310 return QDF_STATUS_SUCCESS; 19311 } 19312 19313 /** 19314 * extract_update_mac_address_event_tlv() - extract update MAC address event 19315 * @wmi_handle: WMI handle 19316 * @evt_buf: event buffer 19317 * @vdev_id: VDEV ID 19318 * @status: FW status of the set MAC address operation 19319 * 19320 * Return: QDF_STATUS 19321 */ 19322 static QDF_STATUS extract_update_mac_address_event_tlv( 19323 wmi_unified_t wmi_handle, void *evt_buf, 19324 uint8_t *vdev_id, uint8_t *status) 19325 { 19326 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 19327 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 19328 19329 param_buf = 19330 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 19331 19332 event = param_buf->fixed_param; 19333 19334 *vdev_id = event->vdev_id; 19335 *status = event->status; 19336 19337 return QDF_STATUS_SUCCESS; 19338 } 19339 #endif 19340 19341 #ifdef WLAN_FEATURE_11BE_MLO 19342 /** 19343 * extract_quiet_offload_event_tlv() - extract quiet offload event 19344 * @wmi_handle: WMI handle 19345 * @evt_buf: event buffer 19346 * @mld_mac: mld mac address 19347 * @link_mac: link mac address 19348 * @link_id: link id 19349 * @quiet_status: quiet is started or stopped 19350 * 19351 * Return: QDF_STATUS 19352 */ 19353 static QDF_STATUS extract_quiet_offload_event_tlv( 19354 wmi_unified_t wmi_handle, void *evt_buf, 19355 struct vdev_sta_quiet_event *quiet_event) 19356 { 19357 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 19358 wmi_quiet_event_fixed_param *event; 19359 19360 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 19361 19362 event = param_buf->fixed_param; 19363 19364 if (!(event->mld_mac_address_present && event->linkid_present) && 19365 !event->link_mac_address_present) { 19366 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 19367 event->mld_mac_address_present, 19368 event->linkid_present, 19369 event->link_mac_address_present); 19370 return QDF_STATUS_E_INVAL; 19371 } 19372 19373 if (event->mld_mac_address_present) 19374 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 19375 quiet_event->mld_mac.bytes); 19376 if (event->link_mac_address_present) 19377 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 19378 quiet_event->link_mac.bytes); 19379 if (event->linkid_present) 19380 quiet_event->link_id = event->linkid; 19381 quiet_event->quiet_status = (event->quiet_status == 19382 WMI_QUIET_EVENT_START); 19383 19384 return QDF_STATUS_SUCCESS; 19385 } 19386 #endif 19387 19388 /** 19389 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 19390 * @wmi_handle: wmi handle 19391 * @params: RxFilter params 19392 * 19393 * Return: QDF_STATUS_SUCCESS for success or error code 19394 */ 19395 static QDF_STATUS 19396 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 19397 struct vdev_pn_mgmt_rxfilter_params *params) 19398 { 19399 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 19400 wmi_buf_t buf; 19401 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 19402 19403 if (!is_service_enabled_tlv(wmi_handle, 19404 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 19405 wmi_err("Rx PN Replay Check not supported by target"); 19406 return QDF_STATUS_E_NOSUPPORT; 19407 } 19408 19409 buf = wmi_buf_alloc(wmi_handle, len); 19410 if (!buf) { 19411 wmi_err("wmi buf alloc failed"); 19412 return QDF_STATUS_E_NOMEM; 19413 } 19414 19415 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 19416 WMITLV_SET_HDR( 19417 &cmd->tlv_header, 19418 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 19419 WMITLV_GET_STRUCT_TLVLEN 19420 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 19421 19422 cmd->vdev_id = params->vdev_id; 19423 cmd->pn_rx_filter = params->pn_rxfilter; 19424 19425 if (wmi_unified_cmd_send(wmi_handle, buf, len, 19426 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 19427 wmi_err("Failed to send WMI command"); 19428 wmi_buf_free(buf); 19429 return QDF_STATUS_E_FAILURE; 19430 } 19431 19432 return QDF_STATUS_SUCCESS; 19433 } 19434 19435 static QDF_STATUS 19436 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19437 uint8_t *pdev_id, uint8_t *software_image, 19438 uint8_t *chip_info, 19439 uint32_t *pktlog_json_version) 19440 { 19441 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 19442 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 19443 19444 param_buf = 19445 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 19446 19447 event = param_buf->fixed_param; 19448 19449 if ((event->software_image[0] == '\0') || 19450 (event->chip_info[0] == '\0')) { 19451 *pdev_id = event->pdev_id; 19452 return QDF_STATUS_E_INVAL; 19453 } 19454 19455 qdf_mem_copy(software_image, event->software_image, 40); 19456 qdf_mem_copy(chip_info, event->chip_info, 40); 19457 *pktlog_json_version = event->pktlog_defs_json_version; 19458 *pdev_id = event->pdev_id; 19459 return QDF_STATUS_SUCCESS; 19460 } 19461 19462 #ifdef HEALTH_MON_SUPPORT 19463 /** 19464 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 19465 * fw 19466 * @wmi_handle: wmi handle 19467 * @evt_buf: pointer to event buffer 19468 * @params: health monitor params 19469 * 19470 * Return: QDF_STATUS_SUCCESS for success or error code 19471 */ 19472 static QDF_STATUS 19473 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 19474 void *evt_buf, 19475 struct wmi_health_mon_params *param) 19476 { 19477 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 19478 wmi_health_mon_init_done_fixed_param *event; 19479 19480 param_buf = 19481 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 19482 19483 event = param_buf->fixed_param; 19484 19485 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 19486 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 19487 param->initial_upload_period_ms = event->initial_upload_period_ms; 19488 param->read_index = 0; 19489 19490 return QDF_STATUS_SUCCESS; 19491 } 19492 #endif /* HEALTH_MON_SUPPORT */ 19493 19494 /** 19495 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 19496 * @wmi_handle: wmi handle 19497 * @evt_buf: pointer to event buffer 19498 * @pdev stats: Pointer to hold pdev telemetry stats 19499 * 19500 * Return: QDF_STATUS_SUCCESS for success or error code 19501 */ 19502 static QDF_STATUS 19503 extract_pdev_telemetry_stats_tlv( 19504 wmi_unified_t wmi_handle, void *evt_buf, 19505 struct wmi_host_pdev_telemetry_stats *pdev_stats) 19506 { 19507 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19508 wmi_pdev_telemetry_stats *ev; 19509 19510 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 19511 19512 if (param_buf->pdev_telemetry_stats) { 19513 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 19514 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 19515 ev->avg_chan_lat_per_ac, 19516 sizeof(ev->avg_chan_lat_per_ac)); 19517 pdev_stats->estimated_air_time_per_ac = 19518 ev->estimated_air_time_per_ac; 19519 } 19520 19521 return QDF_STATUS_SUCCESS; 19522 } 19523 19524 struct wmi_ops tlv_ops = { 19525 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 19526 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 19527 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 19528 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 19529 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 19530 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 19531 .send_peer_param_cmd = send_peer_param_cmd_tlv, 19532 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 19533 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 19534 .send_peer_create_cmd = send_peer_create_cmd_tlv, 19535 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 19536 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 19537 .send_peer_rx_reorder_queue_setup_cmd = 19538 send_peer_rx_reorder_queue_setup_cmd_tlv, 19539 .send_peer_rx_reorder_queue_remove_cmd = 19540 send_peer_rx_reorder_queue_remove_cmd_tlv, 19541 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 19542 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 19543 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 19544 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 19545 .send_suspend_cmd = send_suspend_cmd_tlv, 19546 .send_resume_cmd = send_resume_cmd_tlv, 19547 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 19548 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 19549 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 19550 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 19551 .send_dbglog_cmd = send_dbglog_cmd_tlv, 19552 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 19553 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 19554 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 19555 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 19556 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 19557 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 19558 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 19559 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 19560 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 19561 .send_scan_start_cmd = send_scan_start_cmd_tlv, 19562 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 19563 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 19564 .send_mgmt_cmd = send_mgmt_cmd_tlv, 19565 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 19566 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 19567 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 19568 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 19569 .send_set_sta_uapsd_auto_trig_cmd = 19570 send_set_sta_uapsd_auto_trig_cmd_tlv, 19571 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 19572 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 19573 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 19574 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 19575 .send_lro_config_cmd = send_lro_config_cmd_tlv, 19576 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 19577 .send_probe_rsp_tmpl_send_cmd = 19578 send_probe_rsp_tmpl_send_cmd_tlv, 19579 .send_p2p_go_set_beacon_ie_cmd = 19580 send_p2p_go_set_beacon_ie_cmd_tlv, 19581 .send_setup_install_key_cmd = 19582 send_setup_install_key_cmd_tlv, 19583 .send_scan_probe_setoui_cmd = 19584 send_scan_probe_setoui_cmd_tlv, 19585 #ifdef IPA_OFFLOAD 19586 .send_ipa_offload_control_cmd = 19587 send_ipa_offload_control_cmd_tlv, 19588 #endif 19589 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 19590 .send_pno_start_cmd = send_pno_start_cmd_tlv, 19591 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 19592 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 19593 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 19594 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 19595 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 19596 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 19597 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 19598 .send_unified_ll_stats_get_sta_cmd = 19599 send_unified_ll_stats_get_sta_cmd_tlv, 19600 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 19601 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 19602 .send_congestion_cmd = send_congestion_cmd_tlv, 19603 .send_snr_request_cmd = send_snr_request_cmd_tlv, 19604 .send_snr_cmd = send_snr_cmd_tlv, 19605 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 19606 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 19607 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 19608 #endif 19609 #ifdef WLAN_SUPPORT_GREEN_AP 19610 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 19611 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 19612 .extract_green_ap_egap_status_info = 19613 extract_green_ap_egap_status_info_tlv, 19614 #endif 19615 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 19616 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 19617 #ifdef FEATURE_OEM_DATA 19618 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 19619 #endif 19620 #ifdef WLAN_FEATURE_CIF_CFR 19621 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 19622 #endif 19623 .send_dfs_phyerr_filter_offload_en_cmd = 19624 send_dfs_phyerr_filter_offload_en_cmd_tlv, 19625 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 19626 .send_process_dhcpserver_offload_cmd = 19627 send_process_dhcpserver_offload_cmd_tlv, 19628 .send_pdev_set_regdomain_cmd = 19629 send_pdev_set_regdomain_cmd_tlv, 19630 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 19631 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 19632 .save_fw_version_cmd = save_fw_version_cmd_tlv, 19633 .check_and_update_fw_version = 19634 check_and_update_fw_version_cmd_tlv, 19635 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 19636 .send_enable_specific_fw_logs_cmd = 19637 send_enable_specific_fw_logs_cmd_tlv, 19638 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 19639 .send_unit_test_cmd = send_unit_test_cmd_tlv, 19640 #ifdef FEATURE_WLAN_APF 19641 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 19642 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 19643 .send_apf_write_work_memory_cmd = 19644 wmi_send_apf_write_work_memory_cmd_tlv, 19645 .send_apf_read_work_memory_cmd = 19646 wmi_send_apf_read_work_memory_cmd_tlv, 19647 .extract_apf_read_memory_resp_event = 19648 wmi_extract_apf_read_memory_resp_event_tlv, 19649 #endif /* FEATURE_WLAN_APF */ 19650 .init_cmd_send = init_cmd_send_tlv, 19651 .send_vdev_set_custom_aggr_size_cmd = 19652 send_vdev_set_custom_aggr_size_cmd_tlv, 19653 .send_vdev_set_qdepth_thresh_cmd = 19654 send_vdev_set_qdepth_thresh_cmd_tlv, 19655 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 19656 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 19657 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 19658 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 19659 .send_periodic_chan_stats_config_cmd = 19660 send_periodic_chan_stats_config_cmd_tlv, 19661 #ifdef WLAN_IOT_SIM_SUPPORT 19662 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 19663 #endif 19664 .send_vdev_spectral_configure_cmd = 19665 send_vdev_spectral_configure_cmd_tlv, 19666 .send_vdev_spectral_enable_cmd = 19667 send_vdev_spectral_enable_cmd_tlv, 19668 #ifdef WLAN_CONV_SPECTRAL_ENABLE 19669 .extract_pdev_sscan_fw_cmd_fixed_param = 19670 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 19671 .extract_pdev_sscan_fft_bin_index = 19672 extract_pdev_sscan_fft_bin_index_tlv, 19673 .extract_pdev_spectral_session_chan_info = 19674 extract_pdev_spectral_session_chan_info_tlv, 19675 .extract_pdev_spectral_session_detector_info = 19676 extract_pdev_spectral_session_detector_info_tlv, 19677 .extract_spectral_caps_fixed_param = 19678 extract_spectral_caps_fixed_param_tlv, 19679 .extract_spectral_scan_bw_caps = 19680 extract_spectral_scan_bw_caps_tlv, 19681 .extract_spectral_fft_size_caps = 19682 extract_spectral_fft_size_caps_tlv, 19683 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 19684 .send_thermal_mitigation_param_cmd = 19685 send_thermal_mitigation_param_cmd_tlv, 19686 .send_process_update_edca_param_cmd = 19687 send_process_update_edca_param_cmd_tlv, 19688 .send_bss_color_change_enable_cmd = 19689 send_bss_color_change_enable_cmd_tlv, 19690 .send_coex_config_cmd = send_coex_config_cmd_tlv, 19691 .send_set_country_cmd = send_set_country_cmd_tlv, 19692 .send_addba_send_cmd = send_addba_send_cmd_tlv, 19693 .send_delba_send_cmd = send_delba_send_cmd_tlv, 19694 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 19695 .get_target_cap_from_service_ready = extract_service_ready_tlv, 19696 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 19697 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 19698 .extract_host_mem_req = extract_host_mem_req_tlv, 19699 .save_service_bitmap = save_service_bitmap_tlv, 19700 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 19701 .is_service_enabled = is_service_enabled_tlv, 19702 .save_fw_version = save_fw_version_in_service_ready_tlv, 19703 .ready_extract_init_status = ready_extract_init_status_tlv, 19704 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 19705 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 19706 .extract_ready_event_params = extract_ready_event_params_tlv, 19707 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 19708 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 19709 .extract_frame_pn_params = extract_frame_pn_params_tlv, 19710 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 19711 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 19712 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 19713 #ifdef FEATURE_WLAN_SCAN_PNO 19714 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 19715 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 19716 #endif 19717 .extract_unit_test = extract_unit_test_tlv, 19718 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 19719 .extract_bcn_stats = extract_bcn_stats_tlv, 19720 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 19721 .extract_chan_stats = extract_chan_stats_tlv, 19722 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 19723 .extract_profile_ctx = extract_profile_ctx_tlv, 19724 .extract_profile_data = extract_profile_data_tlv, 19725 .send_fw_test_cmd = send_fw_test_cmd_tlv, 19726 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 19727 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 19728 .extract_service_ready_ext = extract_service_ready_ext_tlv, 19729 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 19730 .extract_dbs_or_sbs_service_ready_ext2 = 19731 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 19732 .extract_hw_mode_cap_service_ready_ext = 19733 extract_hw_mode_cap_service_ready_ext_tlv, 19734 .extract_mac_phy_cap_service_ready_ext = 19735 extract_mac_phy_cap_service_ready_ext_tlv, 19736 .extract_mac_phy_cap_service_ready_ext2 = 19737 extract_mac_phy_cap_service_ready_ext2_tlv, 19738 .extract_reg_cap_service_ready_ext = 19739 extract_reg_cap_service_ready_ext_tlv, 19740 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 19741 .extract_dbr_ring_cap_service_ready_ext = 19742 extract_dbr_ring_cap_service_ready_ext_tlv, 19743 .extract_dbr_ring_cap_service_ready_ext2 = 19744 extract_dbr_ring_cap_service_ready_ext2_tlv, 19745 .extract_scan_radio_cap_service_ready_ext2 = 19746 extract_scan_radio_cap_service_ready_ext2_tlv, 19747 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 19748 .extract_sar_cap_service_ready_ext = 19749 extract_sar_cap_service_ready_ext_tlv, 19750 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 19751 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 19752 .extract_fips_event_data = extract_fips_event_data_tlv, 19753 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19754 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 19755 #endif 19756 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 19757 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 19758 #endif 19759 #ifdef WLAN_FEATURE_DISA 19760 .extract_encrypt_decrypt_resp_event = 19761 extract_encrypt_decrypt_resp_event_tlv, 19762 #endif 19763 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 19764 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19765 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 19766 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 19767 #endif 19768 .extract_get_pn_data = extract_get_pn_data_tlv, 19769 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 19770 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 19771 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 19772 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 19773 #ifdef WLAN_FEATURE_DISA 19774 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 19775 #endif 19776 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 19777 .send_wlan_profile_hist_intvl_cmd = 19778 send_wlan_profile_hist_intvl_cmd_tlv, 19779 .is_management_record = is_management_record_tlv, 19780 .is_diag_event = is_diag_event_tlv, 19781 #ifdef WLAN_FEATURE_ACTION_OUI 19782 .send_action_oui_cmd = send_action_oui_cmd_tlv, 19783 #endif 19784 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 19785 #ifdef QCA_SUPPORT_AGILE_DFS 19786 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 19787 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 19788 #endif 19789 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 19790 .extract_reg_chan_list_update_event = 19791 extract_reg_chan_list_update_event_tlv, 19792 #ifdef CONFIG_BAND_6GHZ 19793 .extract_reg_chan_list_ext_update_event = 19794 extract_reg_chan_list_ext_update_event_tlv, 19795 #ifdef CONFIG_AFC_SUPPORT 19796 .extract_afc_event = extract_afc_event_tlv, 19797 #endif 19798 #endif 19799 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 19800 .extract_num_rf_characterization_entries = 19801 extract_num_rf_characterization_entries_tlv, 19802 .extract_rf_characterization_entries = 19803 extract_rf_characterization_entries_tlv, 19804 #endif 19805 .extract_chainmask_tables = 19806 extract_chainmask_tables_tlv, 19807 .extract_thermal_stats = extract_thermal_stats_tlv, 19808 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 19809 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 19810 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 19811 #ifdef DFS_COMPONENT_ENABLE 19812 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 19813 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 19814 .extract_dfs_radar_detection_event = 19815 extract_dfs_radar_detection_event_tlv, 19816 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 19817 #endif 19818 .convert_pdev_id_host_to_target = 19819 convert_host_pdev_id_to_target_pdev_id_legacy, 19820 .convert_pdev_id_target_to_host = 19821 convert_target_pdev_id_to_host_pdev_id_legacy, 19822 19823 .convert_host_pdev_id_to_target = 19824 convert_host_pdev_id_to_target_pdev_id, 19825 .convert_target_pdev_id_to_host = 19826 convert_target_pdev_id_to_host_pdev_id, 19827 19828 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 19829 19830 .convert_phy_id_host_to_target = 19831 convert_host_phy_id_to_target_phy_id_legacy, 19832 .convert_phy_id_target_to_host = 19833 convert_target_phy_id_to_host_phy_id_legacy, 19834 19835 .convert_host_phy_id_to_target = 19836 convert_host_phy_id_to_target_phy_id, 19837 .convert_target_phy_id_to_host = 19838 convert_target_phy_id_to_host_phy_id, 19839 19840 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 19841 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 19842 .extract_reg_11d_new_country_event = 19843 extract_reg_11d_new_country_event_tlv, 19844 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 19845 .extract_reg_ch_avoid_event = 19846 extract_reg_ch_avoid_event_tlv, 19847 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 19848 .extract_obss_detection_info = extract_obss_detection_info_tlv, 19849 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 19850 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 19851 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 19852 .wmi_check_command_params = wmitlv_check_command_tlv_params, 19853 .extract_comb_phyerr = extract_comb_phyerr_tlv, 19854 .extract_single_phyerr = extract_single_phyerr_tlv, 19855 #ifdef QCA_SUPPORT_CP_STATS 19856 .extract_cca_stats = extract_cca_stats_tlv, 19857 #endif 19858 .extract_esp_estimation_ev_param = 19859 extract_esp_estimation_ev_param_tlv, 19860 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 19861 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 19862 #ifdef OBSS_PD 19863 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 19864 .send_obss_spatial_reuse_set_def_thresh = 19865 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 19866 .send_self_srg_bss_color_bitmap_set = 19867 send_self_srg_bss_color_bitmap_set_cmd_tlv, 19868 .send_self_srg_partial_bssid_bitmap_set = 19869 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 19870 .send_self_srg_obss_color_enable_bitmap = 19871 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 19872 .send_self_srg_obss_bssid_enable_bitmap = 19873 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 19874 .send_self_non_srg_obss_color_enable_bitmap = 19875 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 19876 .send_self_non_srg_obss_bssid_enable_bitmap = 19877 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 19878 #endif 19879 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 19880 .extract_ctl_failsafe_check_ev_param = 19881 extract_ctl_failsafe_check_ev_param_tlv, 19882 #ifdef WIFI_POS_CONVERGED 19883 .extract_oem_response_param = extract_oem_response_param_tlv, 19884 #endif /* WIFI_POS_CONVERGED */ 19885 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 19886 .extract_pasn_peer_create_req_event = 19887 extract_pasn_peer_create_req_event_tlv, 19888 .extract_pasn_peer_delete_req_event = 19889 extract_pasn_peer_delete_req_event_tlv, 19890 .send_rtt_pasn_auth_status_cmd = 19891 send_rtt_pasn_auth_status_cmd_tlv, 19892 .send_rtt_pasn_deauth_cmd = 19893 send_rtt_pasn_deauth_cmd_tlv, 19894 #endif 19895 #ifdef WLAN_MWS_INFO_DEBUGFS 19896 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 19897 #endif 19898 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 19899 #ifdef FEATURE_ANI_LEVEL_REQUEST 19900 .send_ani_level_cmd = send_ani_level_cmd_tlv, 19901 .extract_ani_level = extract_ani_level_tlv, 19902 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19903 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 19904 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 19905 .extract_roam_result_stats = extract_roam_result_stats_tlv, 19906 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 19907 #ifdef WLAN_FEATURE_PKT_CAPTURE 19908 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 19909 #endif 19910 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19911 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 19912 #endif 19913 19914 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19915 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 19916 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 19917 .extract_time_sync_ftm_start_stop_event = 19918 extract_time_sync_ftm_start_stop_event_tlv, 19919 .extract_time_sync_ftm_offset_event = 19920 extract_time_sync_ftm_offset_event_tlv, 19921 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 19922 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 19923 .send_injector_config_cmd = send_injector_config_cmd_tlv, 19924 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 19925 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 19926 #ifdef FEATURE_MEC_OFFLOAD 19927 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 19928 #endif 19929 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 19930 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 19931 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 19932 .extract_cp_stats_more_pending = 19933 extract_cp_stats_more_pending_tlv, 19934 .extract_halphy_stats_end_of_event = 19935 extract_halphy_stats_end_of_event_tlv, 19936 .extract_halphy_stats_event_count = 19937 extract_halphy_stats_event_count_tlv, 19938 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 19939 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 19940 .extract_pdev_csa_switch_count_status = 19941 extract_pdev_csa_switch_count_status_tlv, 19942 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 19943 #ifdef CONFIG_AFC_SUPPORT 19944 .send_afc_cmd = send_afc_cmd_tlv, 19945 #endif 19946 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 19947 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 19948 .send_vdev_set_ltf_key_seed_cmd = 19949 send_vdev_set_ltf_key_seed_cmd_tlv, 19950 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 19951 .send_set_halphy_cal = send_set_halphy_cal_tlv, 19952 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 19953 #ifdef WLAN_MGMT_RX_REO_SUPPORT 19954 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 19955 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 19956 .send_mgmt_rx_reo_filter_config_cmd = 19957 send_mgmt_rx_reo_filter_config_cmd_tlv, 19958 #endif 19959 19960 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19961 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 19962 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 19963 19964 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19965 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 19966 .extract_update_mac_address_event = 19967 extract_update_mac_address_event_tlv, 19968 #endif 19969 19970 #ifdef WLAN_FEATURE_11BE_MLO 19971 .extract_quiet_offload_event = 19972 extract_quiet_offload_event_tlv, 19973 #endif 19974 19975 #ifdef WLAN_SUPPORT_PPEDS 19976 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 19977 #endif /* WLAN_SUPPORT_PPEDS */ 19978 19979 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 19980 .extract_pktlog_decode_info_event = 19981 extract_pktlog_decode_info_event_tlv, 19982 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 19983 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 19984 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 19985 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 19986 #endif 19987 #ifdef WLAN_FEATURE_DBAM_CONFIG 19988 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 19989 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 19990 #endif 19991 #ifdef FEATURE_SET 19992 .feature_set_cmd_send = feature_set_cmd_send_tlv, 19993 #endif 19994 #ifdef HEALTH_MON_SUPPORT 19995 .extract_health_mon_init_done_info_event = 19996 extract_health_mon_init_done_info_event_tlv, 19997 #endif /* HEALTH_MON_SUPPORT */ 19998 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 19999 }; 20000 20001 #ifdef WLAN_FEATURE_11BE_MLO 20002 static void populate_tlv_events_id_mlo(uint32_t *event_ids) 20003 { 20004 event_ids[wmi_mlo_setup_complete_event_id] = 20005 WMI_MLO_SETUP_COMPLETE_EVENTID; 20006 event_ids[wmi_mlo_teardown_complete_event_id] = 20007 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 20008 event_ids[wmi_mlo_link_set_active_resp_eventid] = 20009 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 20010 event_ids[wmi_vdev_quiet_offload_eventid] = 20011 WMI_QUIET_HANDLING_EVENTID; 20012 } 20013 #else /* WLAN_FEATURE_11BE_MLO */ 20014 static inline void populate_tlv_events_id_mlo(uint32_t *event_ids) 20015 { 20016 } 20017 #endif /* WLAN_FEATURE_11BE_MLO */ 20018 20019 /** 20020 * populate_tlv_event_id() - populates wmi event ids 20021 * 20022 * @param event_ids: Pointer to hold event ids 20023 * Return: None 20024 */ 20025 static void populate_tlv_events_id(uint32_t *event_ids) 20026 { 20027 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 20028 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 20029 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 20030 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20031 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 20032 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 20033 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 20034 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 20035 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 20036 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 20037 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 20038 event_ids[wmi_service_ready_ext_event_id] = 20039 WMI_SERVICE_READY_EXT_EVENTID; 20040 event_ids[wmi_service_ready_ext2_event_id] = 20041 WMI_SERVICE_READY_EXT2_EVENTID; 20042 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 20043 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 20044 event_ids[wmi_vdev_install_key_complete_event_id] = 20045 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 20046 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 20047 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 20048 20049 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 20050 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 20051 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 20052 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 20053 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 20054 event_ids[wmi_peer_estimated_linkspeed_event_id] = 20055 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 20056 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 20057 event_ids[wmi_peer_create_conf_event_id] = 20058 WMI_PEER_CREATE_CONF_EVENTID; 20059 event_ids[wmi_peer_delete_response_event_id] = 20060 WMI_PEER_DELETE_RESP_EVENTID; 20061 event_ids[wmi_peer_delete_all_response_event_id] = 20062 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 20063 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 20064 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 20065 event_ids[wmi_tbttoffset_update_event_id] = 20066 WMI_TBTTOFFSET_UPDATE_EVENTID; 20067 event_ids[wmi_ext_tbttoffset_update_event_id] = 20068 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 20069 event_ids[wmi_offload_bcn_tx_status_event_id] = 20070 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 20071 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 20072 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 20073 event_ids[wmi_mgmt_tx_completion_event_id] = 20074 WMI_MGMT_TX_COMPLETION_EVENTID; 20075 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 20076 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 20077 event_ids[wmi_tx_delba_complete_event_id] = 20078 WMI_TX_DELBA_COMPLETE_EVENTID; 20079 event_ids[wmi_tx_addba_complete_event_id] = 20080 WMI_TX_ADDBA_COMPLETE_EVENTID; 20081 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 20082 20083 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 20084 20085 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 20086 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 20087 20088 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 20089 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 20090 20091 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 20092 20093 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 20094 event_ids[wmi_p2p_lo_stop_event_id] = 20095 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 20096 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 20097 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 20098 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 20099 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 20100 event_ids[wmi_d0_wow_disable_ack_event_id] = 20101 WMI_D0_WOW_DISABLE_ACK_EVENTID; 20102 event_ids[wmi_wow_initial_wakeup_event_id] = 20103 WMI_WOW_INITIAL_WAKEUP_EVENTID; 20104 20105 event_ids[wmi_rtt_meas_report_event_id] = 20106 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 20107 event_ids[wmi_tsf_meas_report_event_id] = 20108 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 20109 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 20110 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 20111 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 20112 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 20113 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 20114 event_ids[wmi_diag_event_id_log_supported_event_id] = 20115 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 20116 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 20117 event_ids[wmi_nlo_scan_complete_event_id] = 20118 WMI_NLO_SCAN_COMPLETE_EVENTID; 20119 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 20120 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 20121 20122 event_ids[wmi_gtk_offload_status_event_id] = 20123 WMI_GTK_OFFLOAD_STATUS_EVENTID; 20124 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 20125 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 20126 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 20127 20128 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 20129 20130 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 20131 20132 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 20133 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 20134 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 20135 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 20136 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 20137 event_ids[wmi_wlan_profile_data_event_id] = 20138 WMI_WLAN_PROFILE_DATA_EVENTID; 20139 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 20140 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 20141 event_ids[wmi_vdev_get_keepalive_event_id] = 20142 WMI_VDEV_GET_KEEPALIVE_EVENTID; 20143 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 20144 20145 event_ids[wmi_diag_container_event_id] = 20146 WMI_DIAG_DATA_CONTAINER_EVENTID; 20147 20148 event_ids[wmi_host_auto_shutdown_event_id] = 20149 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 20150 20151 event_ids[wmi_update_whal_mib_stats_event_id] = 20152 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 20153 20154 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 20155 event_ids[wmi_update_vdev_rate_stats_event_id] = 20156 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 20157 20158 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 20159 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 20160 20161 /** Set OCB Sched Response, deprecated */ 20162 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 20163 20164 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 20165 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 20166 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 20167 20168 /* GPIO Event */ 20169 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 20170 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 20171 20172 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 20173 event_ids[wmi_rfkill_state_change_event_id] = 20174 WMI_RFKILL_STATE_CHANGE_EVENTID; 20175 20176 /* TDLS Event */ 20177 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 20178 20179 event_ids[wmi_batch_scan_enabled_event_id] = 20180 WMI_BATCH_SCAN_ENABLED_EVENTID; 20181 event_ids[wmi_batch_scan_result_event_id] = 20182 WMI_BATCH_SCAN_RESULT_EVENTID; 20183 /* OEM Event */ 20184 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 20185 event_ids[wmi_oem_meas_report_event_id] = 20186 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 20187 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 20188 20189 /* NAN Event */ 20190 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 20191 20192 /* LPI Event */ 20193 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 20194 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 20195 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 20196 20197 /* ExtScan events */ 20198 event_ids[wmi_extscan_start_stop_event_id] = 20199 WMI_EXTSCAN_START_STOP_EVENTID; 20200 event_ids[wmi_extscan_operation_event_id] = 20201 WMI_EXTSCAN_OPERATION_EVENTID; 20202 event_ids[wmi_extscan_table_usage_event_id] = 20203 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 20204 event_ids[wmi_extscan_cached_results_event_id] = 20205 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 20206 event_ids[wmi_extscan_wlan_change_results_event_id] = 20207 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 20208 event_ids[wmi_extscan_hotlist_match_event_id] = 20209 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 20210 event_ids[wmi_extscan_capabilities_event_id] = 20211 WMI_EXTSCAN_CAPABILITIES_EVENTID; 20212 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 20213 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 20214 20215 /* mDNS offload events */ 20216 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 20217 20218 /* SAP Authentication offload events */ 20219 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 20220 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 20221 20222 /** Out-of-context-of-bss (OCB) events */ 20223 event_ids[wmi_ocb_set_config_resp_event_id] = 20224 WMI_OCB_SET_CONFIG_RESP_EVENTID; 20225 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 20226 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 20227 event_ids[wmi_dcc_get_stats_resp_event_id] = 20228 WMI_DCC_GET_STATS_RESP_EVENTID; 20229 event_ids[wmi_dcc_update_ndl_resp_event_id] = 20230 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 20231 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 20232 /* System-On-Chip events */ 20233 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 20234 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 20235 event_ids[wmi_soc_hw_mode_transition_event_id] = 20236 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 20237 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 20238 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 20239 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 20240 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20241 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 20242 #endif 20243 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 20244 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 20245 event_ids[wmi_vdev_ocac_complete_event_id] = 20246 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 20247 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 20248 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 20249 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 20250 #ifdef CONFIG_AFC_SUPPORT 20251 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 20252 #endif 20253 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 20254 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20255 event_ids[wmi_peer_sta_ps_statechg_event_id] = 20256 WMI_PEER_STA_PS_STATECHG_EVENTID; 20257 event_ids[wmi_pdev_channel_hopping_event_id] = 20258 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 20259 event_ids[wmi_offchan_data_tx_completion_event] = 20260 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 20261 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 20262 event_ids[wmi_dfs_radar_detection_event_id] = 20263 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 20264 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 20265 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 20266 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 20267 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 20268 event_ids[wmi_service_available_event_id] = 20269 WMI_SERVICE_AVAILABLE_EVENTID; 20270 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 20271 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 20272 /* NDP events */ 20273 event_ids[wmi_ndp_initiator_rsp_event_id] = 20274 WMI_NDP_INITIATOR_RSP_EVENTID; 20275 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 20276 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 20277 event_ids[wmi_ndp_responder_rsp_event_id] = 20278 WMI_NDP_RESPONDER_RSP_EVENTID; 20279 event_ids[wmi_ndp_end_indication_event_id] = 20280 WMI_NDP_END_INDICATION_EVENTID; 20281 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 20282 event_ids[wmi_ndl_schedule_update_event_id] = 20283 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 20284 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 20285 20286 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 20287 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 20288 event_ids[wmi_pdev_chip_power_stats_event_id] = 20289 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 20290 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 20291 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 20292 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 20293 event_ids[wmi_apf_capability_info_event_id] = 20294 WMI_BPF_CAPABILIY_INFO_EVENTID; 20295 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 20296 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 20297 event_ids[wmi_report_rx_aggr_failure_event_id] = 20298 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 20299 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 20300 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 20301 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 20302 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 20303 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 20304 event_ids[wmi_pdev_hw_mode_transition_event_id] = 20305 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 20306 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 20307 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 20308 event_ids[wmi_coex_bt_activity_event_id] = 20309 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 20310 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 20311 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 20312 event_ids[wmi_radio_tx_power_level_stats_event_id] = 20313 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 20314 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 20315 event_ids[wmi_dma_buf_release_event_id] = 20316 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 20317 event_ids[wmi_sap_obss_detection_report_event_id] = 20318 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 20319 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 20320 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 20321 event_ids[wmi_obss_color_collision_report_event_id] = 20322 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 20323 event_ids[wmi_pdev_div_rssi_antid_event_id] = 20324 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 20325 #ifdef WLAN_SUPPORT_TWT 20326 event_ids[wmi_twt_enable_complete_event_id] = 20327 WMI_TWT_ENABLE_COMPLETE_EVENTID; 20328 event_ids[wmi_twt_disable_complete_event_id] = 20329 WMI_TWT_DISABLE_COMPLETE_EVENTID; 20330 event_ids[wmi_twt_add_dialog_complete_event_id] = 20331 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 20332 event_ids[wmi_twt_del_dialog_complete_event_id] = 20333 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 20334 event_ids[wmi_twt_pause_dialog_complete_event_id] = 20335 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 20336 event_ids[wmi_twt_resume_dialog_complete_event_id] = 20337 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 20338 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 20339 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 20340 event_ids[wmi_twt_session_stats_event_id] = 20341 WMI_TWT_SESSION_STATS_EVENTID; 20342 event_ids[wmi_twt_notify_event_id] = 20343 WMI_TWT_NOTIFY_EVENTID; 20344 event_ids[wmi_twt_ack_complete_event_id] = 20345 WMI_TWT_ACK_EVENTID; 20346 #endif 20347 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 20348 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 20349 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 20350 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 20351 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 20352 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 20353 event_ids[wmi_pdev_interop_issues_ap_event_id] = 20354 WMI_PDEV_RAP_INFO_EVENTID; 20355 #endif 20356 #ifdef AST_HKV1_WORKAROUND 20357 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 20358 #endif 20359 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 20360 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 20361 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 20362 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 20363 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 20364 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 20365 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 20366 event_ids[wmi_pdev_cold_boot_cal_event_id] = 20367 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 20368 #ifdef WLAN_MWS_INFO_DEBUGFS 20369 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 20370 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 20371 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 20372 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 20373 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 20374 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 20375 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 20376 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 20377 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 20378 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 20379 #endif 20380 event_ids[wmi_coex_report_antenna_isolation_event_id] = 20381 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 20382 event_ids[wmi_peer_ratecode_list_event_id] = 20383 WMI_PEER_RATECODE_LIST_EVENTID; 20384 event_ids[wmi_chan_rf_characterization_info_event_id] = 20385 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 20386 event_ids[wmi_roam_auth_offload_event_id] = 20387 WMI_ROAM_PREAUTH_START_EVENTID; 20388 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 20389 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 20390 event_ids[wmi_motion_det_base_line_host_eventid] = 20391 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 20392 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 20393 event_ids[wmi_peer_tx_pn_response_event_id] = 20394 WMI_PEER_TX_PN_RESPONSE_EVENTID; 20395 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 20396 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 20397 event_ids[wmi_mgmt_offload_data_event_id] = 20398 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 20399 event_ids[wmi_nan_dmesg_event_id] = 20400 WMI_NAN_DMESG_EVENTID; 20401 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 20402 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 20403 event_ids[wmi_roam_pmkid_request_event_id] = 20404 WMI_ROAM_PMKID_REQUEST_EVENTID; 20405 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20406 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 20407 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 20408 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 20409 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 20410 #endif 20411 event_ids[wmi_roam_scan_chan_list_id] = 20412 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 20413 event_ids[wmi_muedca_params_config_eventid] = 20414 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 20415 event_ids[wmi_pdev_sscan_fw_param_eventid] = 20416 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 20417 event_ids[wmi_roam_cap_report_event_id] = 20418 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 20419 event_ids[wmi_vdev_bcn_latency_event_id] = 20420 WMI_VDEV_BCN_LATENCY_EVENTID; 20421 event_ids[wmi_vdev_disconnect_event_id] = 20422 WMI_VDEV_DISCONNECT_EVENTID; 20423 event_ids[wmi_peer_create_conf_event_id] = 20424 WMI_PEER_CREATE_CONF_EVENTID; 20425 event_ids[wmi_pdev_cp_fwstats_eventid] = 20426 WMI_CTRL_PATH_STATS_EVENTID; 20427 event_ids[wmi_pdev_halphy_fwstats_eventid] = 20428 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 20429 event_ids[wmi_vdev_send_big_data_p2_eventid] = 20430 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 20431 event_ids[wmi_pdev_get_dpd_status_event_id] = 20432 WMI_PDEV_GET_DPD_STATUS_EVENTID; 20433 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20434 event_ids[wmi_vdev_smart_monitor_event_id] = 20435 WMI_VDEV_SMART_MONITOR_EVENTID; 20436 #endif 20437 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 20438 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 20439 event_ids[wmi_pdev_set_halphy_cal_event_id] = 20440 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 20441 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 20442 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 20443 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20444 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 20445 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 20446 #endif 20447 populate_tlv_events_id_mlo(event_ids); 20448 event_ids[wmi_roam_frame_event_id] = 20449 WMI_ROAM_FRAME_EVENTID; 20450 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20451 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 20452 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 20453 #endif 20454 #ifdef WLAN_FEATURE_MCC_QUOTA 20455 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 20456 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 20457 #endif 20458 event_ids[wmi_peer_rx_pn_response_event_id] = 20459 WMI_PEER_RX_PN_RESPONSE_EVENTID; 20460 event_ids[wmi_extract_pktlog_decode_info_eventid] = 20461 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 20462 #ifdef QCA_RSSI_DB2DBM 20463 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 20464 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 20465 #endif 20466 #ifdef MULTI_CLIENT_LL_SUPPORT 20467 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 20468 #endif 20469 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20470 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 20471 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 20472 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 20473 WMI_RTT_PASN_PEER_DELETE_EVENTID; 20474 #endif 20475 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 20476 event_ids[wmi_get_roam_vendor_control_param_event_id] = 20477 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 20478 #endif 20479 #ifdef WLAN_FEATURE_DBAM_CONFIG 20480 event_ids[wmi_coex_dbam_complete_event_id] = 20481 WMI_COEX_DBAM_COMPLETE_EVENTID; 20482 #endif 20483 event_ids[wmi_spectral_capabilities_eventid] = 20484 WMI_SPECTRAL_CAPABILITIES_EVENTID; 20485 #ifdef WLAN_FEATURE_COAP 20486 event_ids[wmi_wow_coap_buf_info_eventid] = 20487 WMI_WOW_COAP_BUF_INFO_EVENTID; 20488 #endif 20489 #ifdef HEALTH_MON_SUPPORT 20490 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 20491 WMI_HEALTH_MON_INIT_DONE_EVENTID; 20492 #endif /* HEALTH_MON_SUPPORT */ 20493 } 20494 20495 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20496 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20497 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20498 { 20499 wmi_service[wmi_service_get_station_in_ll_stats_req] = 20500 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 20501 } 20502 #else 20503 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20504 { 20505 } 20506 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 20507 #else 20508 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20509 { 20510 } 20511 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 20512 20513 #ifdef WLAN_FEATURE_11BE_MLO 20514 static void populate_tlv_service_mlo(uint32_t *wmi_service) 20515 { 20516 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 20517 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 20518 } 20519 #else /* WLAN_FEATURE_11BE_MLO */ 20520 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 20521 { 20522 } 20523 #endif /* WLAN_FEATURE_11BE_MLO */ 20524 20525 /** 20526 * populate_tlv_service() - populates wmi services 20527 * 20528 * @param wmi_service: Pointer to hold wmi_service 20529 * Return: None 20530 */ 20531 static void populate_tlv_service(uint32_t *wmi_service) 20532 { 20533 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 20534 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 20535 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 20536 wmi_service[wmi_service_roam_scan_offload] = 20537 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 20538 wmi_service[wmi_service_bcn_miss_offload] = 20539 WMI_SERVICE_BCN_MISS_OFFLOAD; 20540 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 20541 wmi_service[wmi_service_sta_advanced_pwrsave] = 20542 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 20543 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 20544 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 20545 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 20546 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 20547 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 20548 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 20549 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 20550 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 20551 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 20552 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 20553 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 20554 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 20555 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 20556 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 20557 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 20558 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 20559 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 20560 wmi_service[wmi_service_packet_power_save] = 20561 WMI_SERVICE_PACKET_POWER_SAVE; 20562 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 20563 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 20564 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 20565 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 20566 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 20567 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 20568 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 20569 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 20570 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 20571 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 20572 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 20573 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 20574 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 20575 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 20576 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 20577 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 20578 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 20579 wmi_service[wmi_service_mcc_bcn_interval_change] = 20580 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 20581 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 20582 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 20583 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 20584 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 20585 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 20586 wmi_service[wmi_service_lte_ant_share_support] = 20587 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 20588 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 20589 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 20590 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 20591 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 20592 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 20593 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 20594 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 20595 wmi_service[wmi_service_bcn_txrate_override] = 20596 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 20597 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 20598 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 20599 wmi_service[wmi_service_estimate_linkspeed] = 20600 WMI_SERVICE_ESTIMATE_LINKSPEED; 20601 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 20602 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 20603 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 20604 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 20605 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 20606 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 20607 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 20608 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 20609 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 20610 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 20611 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 20612 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 20613 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 20614 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 20615 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 20616 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 20617 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 20618 wmi_service[wmi_service_sap_auth_offload] = 20619 WMI_SERVICE_SAP_AUTH_OFFLOAD; 20620 wmi_service[wmi_service_dual_band_simultaneous_support] = 20621 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 20622 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 20623 wmi_service[wmi_service_ap_arpns_offload] = 20624 WMI_SERVICE_AP_ARPNS_OFFLOAD; 20625 wmi_service[wmi_service_per_band_chainmask_support] = 20626 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 20627 wmi_service[wmi_service_packet_filter_offload] = 20628 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 20629 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 20630 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 20631 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 20632 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 20633 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 20634 wmi_service[wmi_service_multiple_vdev_restart] = 20635 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 20636 wmi_service[wmi_service_smart_antenna_sw_support] = 20637 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 20638 wmi_service[wmi_service_smart_antenna_hw_support] = 20639 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 20640 20641 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 20642 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 20643 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 20644 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 20645 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 20646 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 20647 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 20648 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 20649 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 20650 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 20651 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 20652 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 20653 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 20654 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 20655 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 20656 wmi_service[wmi_service_periodic_chan_stat_support] = 20657 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 20658 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 20659 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 20660 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 20661 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 20662 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 20663 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 20664 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 20665 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 20666 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 20667 wmi_service[wmi_service_unified_wow_capability] = 20668 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 20669 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 20670 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 20671 wmi_service[wmi_service_sync_delete_cmds] = 20672 WMI_SERVICE_SYNC_DELETE_CMDS; 20673 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 20674 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 20675 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 20676 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 20677 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 20678 wmi_service[wmi_service_deprecated_replace] = 20679 WMI_SERVICE_DEPRECATED_REPLACE; 20680 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 20681 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 20682 wmi_service[wmi_service_enhanced_mcast_filter] = 20683 WMI_SERVICE_ENHANCED_MCAST_FILTER; 20684 wmi_service[wmi_service_half_rate_quarter_rate_support] = 20685 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 20686 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 20687 wmi_service[wmi_service_p2p_listen_offload_support] = 20688 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 20689 wmi_service[wmi_service_mark_first_wakeup_packet] = 20690 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 20691 wmi_service[wmi_service_multiple_mcast_filter_set] = 20692 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 20693 wmi_service[wmi_service_host_managed_rx_reorder] = 20694 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 20695 wmi_service[wmi_service_flash_rdwr_support] = 20696 WMI_SERVICE_FLASH_RDWR_SUPPORT; 20697 wmi_service[wmi_service_wlan_stats_report] = 20698 WMI_SERVICE_WLAN_STATS_REPORT; 20699 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 20700 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 20701 wmi_service[wmi_service_dfs_phyerr_offload] = 20702 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 20703 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 20704 wmi_service[wmi_service_fw_mem_dump_support] = 20705 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 20706 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 20707 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 20708 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 20709 wmi_service[wmi_service_hw_data_filtering] = 20710 WMI_SERVICE_HW_DATA_FILTERING; 20711 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 20712 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 20713 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 20714 wmi_service[wmi_service_extended_nss_support] = 20715 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 20716 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 20717 wmi_service[wmi_service_bcn_offload_start_stop_support] = 20718 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 20719 wmi_service[wmi_service_offchan_data_tid_support] = 20720 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 20721 wmi_service[wmi_service_support_dma] = 20722 WMI_SERVICE_SUPPORT_DIRECT_DMA; 20723 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 20724 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 20725 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 20726 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 20727 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 20728 wmi_service[wmi_service_11k_neighbour_report_support] = 20729 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 20730 wmi_service[wmi_service_ap_obss_detection_offload] = 20731 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 20732 wmi_service[wmi_service_bss_color_offload] = 20733 WMI_SERVICE_BSS_COLOR_OFFLOAD; 20734 wmi_service[wmi_service_gmac_offload_support] = 20735 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 20736 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 20737 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 20738 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 20739 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 20740 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 20741 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 20742 wmi_service[wmi_service_listen_interval_offload_support] = 20743 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 20744 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 20745 wmi_service[wmi_service_obss_spatial_reuse] = 20746 WMI_SERVICE_OBSS_SPATIAL_REUSE; 20747 wmi_service[wmi_service_per_vdev_chain_support] = 20748 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 20749 wmi_service[wmi_service_new_htt_msg_format] = 20750 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 20751 wmi_service[wmi_service_peer_unmap_cnf_support] = 20752 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 20753 wmi_service[wmi_service_beacon_reception_stats] = 20754 WMI_SERVICE_BEACON_RECEPTION_STATS; 20755 wmi_service[wmi_service_vdev_latency_config] = 20756 WMI_SERVICE_VDEV_LATENCY_CONFIG; 20757 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 20758 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 20759 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 20760 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 20761 wmi_service[wmi_service_nan_disable_support] = 20762 WMI_SERVICE_NAN_DISABLE_SUPPORT; 20763 wmi_service[wmi_service_sta_plus_sta_support] = 20764 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 20765 wmi_service[wmi_service_hw_db2dbm_support] = 20766 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 20767 wmi_service[wmi_service_wlm_stats_support] = 20768 WMI_SERVICE_WLM_STATS_REQUEST; 20769 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 20770 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 20771 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 20772 wmi_service[wmi_service_cfr_capture_support] = 20773 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 20774 wmi_service[wmi_service_bcast_twt_support] = 20775 WMI_SERVICE_BROADCAST_TWT; 20776 wmi_service[wmi_service_wpa3_ft_sae_support] = 20777 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 20778 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 20779 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 20780 wmi_service[wmi_service_ft_fils] = 20781 WMI_SERVICE_WPA3_FT_FILS; 20782 wmi_service[wmi_service_adaptive_11r_support] = 20783 WMI_SERVICE_ADAPTIVE_11R_ROAM; 20784 wmi_service[wmi_service_tx_compl_tsf64] = 20785 WMI_SERVICE_TX_COMPL_TSF64; 20786 wmi_service[wmi_service_data_stall_recovery_support] = 20787 WMI_SERVICE_DSM_ROAM_FILTER; 20788 wmi_service[wmi_service_vdev_delete_all_peer] = 20789 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 20790 wmi_service[wmi_service_three_way_coex_config_legacy] = 20791 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 20792 wmi_service[wmi_service_rx_fse_support] = 20793 WMI_SERVICE_RX_FSE_SUPPORT; 20794 wmi_service[wmi_service_sae_roam_support] = 20795 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 20796 wmi_service[wmi_service_owe_roam_support] = 20797 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 20798 wmi_service[wmi_service_6ghz_support] = 20799 WMI_SERVICE_6GHZ_SUPPORT; 20800 wmi_service[wmi_service_bw_165mhz_support] = 20801 WMI_SERVICE_BW_165MHZ_SUPPORT; 20802 wmi_service[wmi_service_bw_restricted_80p80_support] = 20803 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 20804 wmi_service[wmi_service_packet_capture_support] = 20805 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 20806 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 20807 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 20808 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 20809 wmi_service[wmi_service_multiple_vdev_restart_ext] = 20810 WMI_SERVICE_UNAVAILABLE; 20811 wmi_service[wmi_service_time_sync_ftm] = 20812 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 20813 wmi_service[wmi_service_nss_ratio_to_host_support] = 20814 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 20815 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 20816 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 20817 wmi_service[wmi_beacon_protection_support] = 20818 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 20819 wmi_service[wmi_service_sta_nan_ndi_four_port] = 20820 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 20821 wmi_service[wmi_service_host_scan_stop_vdev_all] = 20822 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 20823 wmi_service[wmi_support_extend_address] = 20824 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 20825 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 20826 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 20827 wmi_service[wmi_service_suiteb_roam_support] = 20828 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 20829 wmi_service[wmi_service_no_interband_mcc_support] = 20830 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 20831 wmi_service[wmi_service_dual_sta_roam_support] = 20832 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 20833 wmi_service[wmi_service_peer_create_conf] = 20834 WMI_SERVICE_PEER_CREATE_CONF; 20835 wmi_service[wmi_service_configure_roam_trigger_param_support] = 20836 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 20837 wmi_service[wmi_service_5dot9_ghz_support] = 20838 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 20839 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 20840 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 20841 wmi_service[wmi_service_cfr_capture_count_support] = 20842 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 20843 wmi_service[wmi_service_ocv_support] = 20844 WMI_SERVICE_OCV_SUPPORT; 20845 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 20846 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 20847 wmi_service[wmi_service_thermal_multi_client_support] = 20848 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 20849 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 20850 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 20851 wmi_service[wmi_service_fse_cmem_alloc_support] = 20852 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 20853 wmi_service[wmi_service_scan_conf_per_ch_support] = 20854 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 20855 wmi_service[wmi_service_csa_beacon_template] = 20856 WMI_SERVICE_CSA_BEACON_TEMPLATE; 20857 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20858 wmi_service[wmi_service_rtt_11az_ntb_support] = 20859 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 20860 wmi_service[wmi_service_rtt_11az_tb_support] = 20861 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 20862 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 20863 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 20864 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 20865 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 20866 #endif 20867 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 20868 wmi_service[wmi_service_igmp_offload_support] = 20869 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 20870 #endif 20871 20872 #ifdef FEATURE_WLAN_TDLS 20873 #ifdef WLAN_FEATURE_11AX 20874 wmi_service[wmi_service_tdls_ax_support] = 20875 WMI_SERVICE_11AX_TDLS_SUPPORT; 20876 wmi_service[wmi_service_tdls_6g_support] = 20877 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 20878 #endif 20879 wmi_service[wmi_service_tdls_wideband_support] = 20880 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 20881 #endif 20882 20883 #ifdef WLAN_SUPPORT_TWT 20884 wmi_service[wmi_service_twt_bcast_req_support] = 20885 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 20886 wmi_service[wmi_service_twt_bcast_resp_support] = 20887 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 20888 wmi_service[wmi_service_twt_nudge] = 20889 WMI_SERVICE_TWT_NUDGE; 20890 wmi_service[wmi_service_all_twt] = 20891 WMI_SERVICE_TWT_ALL_DIALOG_ID; 20892 wmi_service[wmi_service_twt_statistics] = 20893 WMI_SERVICE_TWT_STATS; 20894 #endif 20895 wmi_service[wmi_service_spectral_scan_disabled] = 20896 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 20897 wmi_service[wmi_service_sae_eapol_offload_support] = 20898 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 20899 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 20900 20901 wmi_service[wmi_service_wapi_concurrency_supported] = 20902 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 20903 wmi_service[wmi_service_sap_connected_d3_wow] = 20904 WMI_SERVICE_SAP_CONNECTED_D3WOW; 20905 wmi_service[wmi_service_go_connected_d3_wow] = 20906 WMI_SERVICE_SAP_CONNECTED_D3WOW; 20907 wmi_service[wmi_service_ext_tpc_reg_support] = 20908 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 20909 wmi_service[wmi_service_ndi_txbf_support] = 20910 WMI_SERVICE_NDI_TXBF_SUPPORT; 20911 wmi_service[wmi_service_reg_cc_ext_event_support] = 20912 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 20913 wmi_service[wmi_service_bang_radar_320_support] = 20914 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 20915 #if defined(CONFIG_BAND_6GHZ) 20916 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 20917 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 20918 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 20919 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 20920 #endif 20921 wmi_service[wmi_service_dcs_awgn_int_support] = 20922 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 20923 wmi_populate_service_11be(wmi_service); 20924 20925 #ifdef WLAN_FEATURE_BIG_DATA_STATS 20926 wmi_service[wmi_service_big_data_support] = 20927 WMI_SERVICE_BIG_DATA_SUPPORT; 20928 #endif 20929 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 20930 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 20931 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 20932 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 20933 wmi_service[wmi_service_halphy_cal_status] = 20934 WMI_SERVICE_HALPHY_CAL_STATUS; 20935 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 20936 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 20937 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 20938 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 20939 wmi_service[wmi_service_ema_multiple_group_supported] = 20940 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 20941 wmi_service[wmi_service_large_beacon_supported] = 20942 WMI_SERVICE_LARGE_BEACON_SUPPORT; 20943 wmi_service[wmi_service_aoa_for_rcc_supported] = 20944 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 20945 #ifdef WLAN_FEATURE_P2P_P2P_STA 20946 wmi_service[wmi_service_p2p_p2p_cc_support] = 20947 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 20948 #endif 20949 #ifdef THERMAL_STATS_SUPPORT 20950 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 20951 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 20952 #endif 20953 wmi_service[wmi_service_hw_mode_policy_offload_support] = 20954 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 20955 wmi_service[wmi_service_mgmt_rx_reo_supported] = 20956 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 20957 wmi_service[wmi_service_phy_dma_byte_swap_support] = 20958 WMI_SERVICE_UNAVAILABLE; 20959 wmi_service[wmi_service_spectral_session_info_support] = 20960 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 20961 wmi_service[wmi_service_umac_hang_recovery_support] = 20962 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 20963 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 20964 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20965 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 20966 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 20967 #endif 20968 wmi_service[wmi_service_probe_all_bw_support] = 20969 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 20970 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 20971 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 20972 #ifdef QCA_UNDECODED_METADATA_SUPPORT 20973 wmi_service[wmi_service_fp_phy_err_filter_support] = 20974 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 20975 #endif 20976 populate_tlv_service_mlo(wmi_service); 20977 wmi_service[wmi_service_pdev_rate_config_support] = 20978 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 20979 wmi_service[wmi_service_multi_peer_group_cmd_support] = 20980 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 20981 #ifdef WLAN_FEATURE_11BE 20982 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 20983 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 20984 #endif 20985 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 20986 wmi_service[wmi_service_combined_set_param_support] = 20987 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 20988 #endif 20989 wmi_service[wmi_service_pn_replay_check_support] = 20990 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 20991 #ifdef QCA_RSSI_DB2DBM 20992 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 20993 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 20994 #endif 20995 wmi_service[wmi_service_pktlog_decode_info_support] = 20996 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 20997 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 20998 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 20999 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 21000 #endif 21001 #ifdef MULTI_CLIENT_LL_SUPPORT 21002 wmi_service[wmi_service_configure_multi_client_ll_support] = 21003 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 21004 #endif 21005 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 21006 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 21007 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 21008 #endif 21009 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 21010 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 21011 #ifdef FEATURE_SET 21012 wmi_service[wmi_service_feature_set_event_support] = 21013 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 21014 #endif 21015 } 21016 21017 /** 21018 * wmi_ocb_ut_attach() - Attach OCB test framework 21019 * @wmi_handle: wmi handle 21020 * 21021 * Return: None 21022 */ 21023 #ifdef WLAN_OCB_UT 21024 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 21025 #else 21026 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 21027 { 21028 return; 21029 } 21030 #endif 21031 21032 /** 21033 * wmi_tlv_attach() - Attach TLV APIs 21034 * 21035 * Return: None 21036 */ 21037 void wmi_tlv_attach(wmi_unified_t wmi_handle) 21038 { 21039 wmi_handle->ops = &tlv_ops; 21040 wmi_ocb_ut_attach(wmi_handle); 21041 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 21042 #ifdef WMI_INTERFACE_EVENT_LOGGING 21043 /* Skip saving WMI_CMD_HDR and TLV HDR */ 21044 wmi_handle->soc->buf_offset_command = 8; 21045 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 21046 wmi_handle->soc->buf_offset_event = 4; 21047 #endif 21048 populate_tlv_events_id(wmi_handle->wmi_events); 21049 populate_tlv_service(wmi_handle->services); 21050 wmi_wds_attach_tlv(wmi_handle); 21051 wmi_twt_attach_tlv(wmi_handle); 21052 wmi_extscan_attach_tlv(wmi_handle); 21053 wmi_smart_ant_attach_tlv(wmi_handle); 21054 wmi_dbr_attach_tlv(wmi_handle); 21055 wmi_atf_attach_tlv(wmi_handle); 21056 wmi_ap_attach_tlv(wmi_handle); 21057 wmi_bcn_attach_tlv(wmi_handle); 21058 wmi_ocb_attach_tlv(wmi_handle); 21059 wmi_nan_attach_tlv(wmi_handle); 21060 wmi_p2p_attach_tlv(wmi_handle); 21061 wmi_interop_issues_ap_attach_tlv(wmi_handle); 21062 wmi_dcs_attach_tlv(wmi_handle); 21063 wmi_roam_attach_tlv(wmi_handle); 21064 wmi_concurrency_attach_tlv(wmi_handle); 21065 wmi_pmo_attach_tlv(wmi_handle); 21066 wmi_sta_attach_tlv(wmi_handle); 21067 wmi_11ax_bss_color_attach_tlv(wmi_handle); 21068 wmi_fwol_attach_tlv(wmi_handle); 21069 wmi_vdev_attach_tlv(wmi_handle); 21070 wmi_cfr_attach_tlv(wmi_handle); 21071 wmi_cp_stats_attach_tlv(wmi_handle); 21072 wmi_gpio_attach_tlv(wmi_handle); 21073 wmi_11be_attach_tlv(wmi_handle); 21074 wmi_coap_attach_tlv(wmi_handle); 21075 } 21076 qdf_export_symbol(wmi_tlv_attach); 21077 21078 /** 21079 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 21080 * 21081 * Return: None 21082 */ 21083 void wmi_tlv_init(void) 21084 { 21085 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 21086 } 21087