1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "wmi_unified_api.h" 21 #include "wmi.h" 22 #include "wmi_version.h" 23 #include "wmi_unified_priv.h" 24 #include "wmi_version_allowlist.h" 25 #include "wifi_pos_public_struct.h" 26 #include <qdf_module.h> 27 #include <wlan_defs.h> 28 #include <wlan_cmn.h> 29 #include <htc_services.h> 30 #ifdef FEATURE_WLAN_APF 31 #include "wmi_unified_apf_tlv.h" 32 #endif 33 #ifdef WLAN_FEATURE_ACTION_OUI 34 #include "wmi_unified_action_oui_tlv.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #include "wmi_unified_twt_api.h" 45 #include "wmi_unified_wds_api.h" 46 47 #ifdef WLAN_POLICY_MGR_ENABLE 48 #include "wlan_policy_mgr_public_struct.h" 49 #endif 50 51 #ifdef WMI_SMART_ANT_SUPPORT 52 #include "wmi_unified_smart_ant_api.h" 53 #endif 54 55 #ifdef WMI_DBR_SUPPORT 56 #include "wmi_unified_dbr_api.h" 57 #endif 58 59 #ifdef WMI_ATF_SUPPORT 60 #include "wmi_unified_atf_api.h" 61 #endif 62 63 #ifdef WMI_AP_SUPPORT 64 #include "wmi_unified_ap_api.h" 65 #endif 66 67 #include <wmi_unified_vdev_api.h> 68 #include <wmi_unified_vdev_tlv.h> 69 #include <wmi_unified_11be_tlv.h> 70 71 /* 72 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 73 * then channel_list may fill the upper 12 bits with channel flags, 74 * while using only the lower 20 bits for channel frequency. 75 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 76 * then channel_list only holds the frequency value. 77 */ 78 #define CHAN_LIST_FLAG_MASK_POS 20 79 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 80 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 81 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 82 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 83 84 /* HTC service ids for WMI for multi-radio */ 85 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 86 WMI_CONTROL_SVC_WMAC1, 87 WMI_CONTROL_SVC_WMAC2}; 88 89 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 90 /*Populate peer_param array whose index as host id and 91 *value as target id 92 */ 93 static const uint32_t peer_param_tlv[] = { 94 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 95 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 96 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 97 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 98 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 99 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 100 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 101 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 102 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 103 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 104 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 105 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 106 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 107 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 108 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 109 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 110 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 111 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_WHITELIST, 112 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 113 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 114 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 115 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 116 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 117 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 118 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 119 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 120 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 121 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 122 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 123 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 124 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 125 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 126 }; 127 128 /** 129 * Populate pdev_param_value whose index is host param and value is target 130 * param 131 */ 132 static const uint32_t pdev_param_tlv[] = { 133 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 134 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 135 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 136 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 137 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 138 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 139 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 140 [wmi_pdev_param_resmgr_offchan_mode] = 141 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 142 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 143 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 144 [wmi_pdev_param_non_agg_sw_retry_th] = 145 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 146 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 147 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 148 [wmi_pdev_param_ac_aggrsize_scaling] = 149 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 150 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 151 [wmi_pdev_param_ltr_ac_latency_be] = 152 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 153 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 154 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 155 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 156 [wmi_pdev_param_ltr_ac_latency_timeout] = 157 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 158 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 159 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 160 [wmi_pdev_param_ltr_tx_activity_timeout] = 161 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 162 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 163 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 164 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 165 [wmi_pdev_param_pcielp_txbuf_watermark] = 166 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 167 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 168 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 169 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 170 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 171 [wmi_pdev_param_pdev_stats_update_period] = 172 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 173 [wmi_pdev_param_vdev_stats_update_period] = 174 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 175 [wmi_pdev_param_peer_stats_update_period] = 176 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 177 [wmi_pdev_param_bcnflt_stats_update_period] = 178 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 179 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 180 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 181 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 182 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 183 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 184 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 185 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 186 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 187 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 188 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 189 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 190 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 191 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 192 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 193 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 194 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 195 [wmi_pdev_param_low_power_rf_enable] = 196 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 197 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 198 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 199 [wmi_pdev_param_power_collapse_enable] = 200 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 201 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 202 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 203 [wmi_pdev_param_audio_over_wlan_latency] = 204 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 205 [wmi_pdev_param_audio_over_wlan_enable] = 206 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 207 [wmi_pdev_param_whal_mib_stats_update_enable] = 208 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 209 [wmi_pdev_param_vdev_rate_stats_update_period] = 210 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 211 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 212 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 213 [wmi_pdev_param_adaptive_early_rx_enable] = 214 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 215 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 216 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 217 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 218 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 219 [wmi_pdev_param_early_rx_fix_sleep_slop] = 220 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 221 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 222 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 223 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 224 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 225 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 226 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 227 [wmi_pdev_param_bto_fix_bcn_timeout] = 228 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 229 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 230 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 231 [wmi_pdev_param_ce_bto_combo_ce_value] = 232 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 233 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 234 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 235 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 236 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 237 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 238 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 239 [wmi_pdev_param_soft_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 240 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 241 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 242 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 243 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 244 [wmi_pdev_peer_sta_ps_statechg_enable] = 245 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 246 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 247 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 248 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 249 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 250 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 251 [wmi_pdev_param_set_mcast_bcast_echo] = 252 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 253 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 254 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 255 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 256 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 257 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 258 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 259 [wmi_pdev_param_enable_per_tid_amsdu] = 260 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 261 [wmi_pdev_param_enable_per_tid_ampdu] = 262 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 263 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 264 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 265 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 266 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 267 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 268 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 269 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 270 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 271 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 272 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 273 [wmi_pdev_param_atf_obss_noise_sch] = 274 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 275 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 276 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 277 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 278 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 279 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 280 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 281 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 282 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 283 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 284 [wmi_pdev_param_set_disable_reset_cmdid] = 285 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 286 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 287 [wmi_pdev_param_txbf_sound_period_cmdid] = 288 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 289 [wmi_pdev_param_set_burst_mode_cmdid] = 290 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 291 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 292 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 293 [wmi_pdev_param_set_promisc_mode_cmdid] = 294 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 295 [wmi_pdev_param_set_ppdu_duration_cmdid] = 296 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 297 [wmi_pdev_param_remove_mcast2ucast_buffer] = 298 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 299 [wmi_pdev_param_set_mcast2ucast_buffer] = 300 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 301 [wmi_pdev_param_set_mcast2ucast_mode] = 302 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 303 [wmi_pdev_param_smart_antenna_default_antenna] = 304 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 305 [wmi_pdev_param_fast_channel_reset] = 306 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 307 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 308 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 309 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 310 [wmi_pdev_param_antenna_gain_half_db] = 311 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 312 [wmi_pdev_param_esp_indication_period] = 313 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 314 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 315 [wmi_pdev_param_esp_airtime_fraction] = 316 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 317 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 318 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 319 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 320 /* Trigger interval for all trigger types. */ 321 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 322 [wmi_pdev_param_sub_channel_marking] = 323 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 324 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 325 [wmi_pdev_param_equal_ru_allocation_enable] = 326 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 327 [wmi_pdev_param_per_peer_prd_cfr_enable] = 328 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 329 [wmi_pdev_param_nav_override_config] = 330 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 331 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 332 [wmi_pdev_param_set_prb_rsp_ttl] = 333 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 334 [wmi_pdev_param_set_mu_ppdu_duration] = 335 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 336 [wmi_pdev_param_set_tbtt_ctrl] = 337 WMI_PDEV_PARAM_SET_TBTT_CTRL, 338 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 339 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 340 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 341 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 342 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 343 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 344 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 345 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 346 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 347 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 348 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 349 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 350 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 351 [wmi_pdev_param_set_mesh_params] = WMI_PDEV_PARAM_SET_MESH_PARAMS, 352 [wmi_pdev_param_mpd_userpd_ssr] = WMI_PDEV_PARAM_MPD_USERPD_SSR, 353 [wmi_pdev_param_low_latency_mode] = 354 WMI_PDEV_PARAM_LOW_LATENCY_SCHED_MODE, 355 [wmi_pdev_param_scan_radio_tx_on_dfs] = 356 WMI_PDEV_PARAM_SCAN_RADIO_TX_ON_DFS, 357 [wmi_pdev_param_en_probe_all_bw] = 358 WMI_PDEV_PARAM_EN_PROBE_ALL_BW, 359 [wmi_pdev_param_obss_min_duration_check_for_sr] = 360 WMI_PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR, 361 [wmi_pdev_param_truncate_sr] = WMI_PDEV_PARAM_TRUNCATE_SR, 362 [wmi_pdev_param_ctrl_frame_obss_pd_threshold] = 363 WMI_PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD, 364 [wmi_pdev_param_rate_upper_cap] = WMI_PDEV_PARAM_RATE_UPPER_CAP, 365 [wmi_pdev_param_rate_retry_mcs_drop] = 366 WMI_PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH, 367 [wmi_pdev_param_mcs_probe_intvl] = 368 WMI_PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL, 369 [wmi_pdev_param_nss_probe_intvl] = 370 WMI_PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL, 371 }; 372 373 /** 374 * Populate vdev_param_value_tlv array whose index is host param 375 * and value is target param 376 */ 377 static const uint32_t vdev_param_tlv[] = { 378 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 379 [wmi_vdev_param_fragmentation_threshold] = 380 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 381 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 382 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 383 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 384 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 385 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 386 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 387 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 388 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 389 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 390 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 391 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 392 [wmi_vdev_oc_scheduler_air_time_limit] = 393 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 394 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 395 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 396 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 397 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 398 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 399 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 400 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 401 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 402 [wmi_vdev_param_disable_htprotection] = 403 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 404 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 405 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 406 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 407 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 408 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 409 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 410 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 411 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 412 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 413 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 414 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 415 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 416 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 417 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 418 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 419 [wmi_vdev_param_unknown_dest_indicate] = 420 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 421 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 422 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 423 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 424 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 425 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 426 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 427 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 428 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 429 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 430 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 431 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 432 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 433 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 434 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 435 [wmi_vdev_param_early_rx_adjust_enable] = 436 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 437 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 438 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 439 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 440 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 441 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 442 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 443 [wmi_vdev_param_early_rx_adjust_pause] = 444 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 445 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 446 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 447 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 448 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 449 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 450 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 451 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 452 [wmi_vdev_param_early_rx_drift_sample] = 453 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 454 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 455 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 456 [wmi_vdev_param_ebt_resync_timeout] = 457 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 458 [wmi_vdev_param_aggr_trig_event_enable] = 459 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 460 [wmi_vdev_param_is_ibss_power_save_allowed] = 461 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 462 [wmi_vdev_param_is_power_collapse_allowed] = 463 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 464 [wmi_vdev_param_is_awake_on_txrx_enabled] = 465 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 466 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 467 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 468 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 469 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 470 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 471 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 472 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 473 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 474 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 475 [wmi_vdev_param_stats_avg_factor] = 476 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 477 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 478 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 479 [wmi_vdev_param_mcc_rtscts_protection_enable] = 480 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 481 [wmi_vdev_param_mcc_broadcast_probe_enable] = 482 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 483 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 484 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 485 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 486 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 487 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 488 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 489 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 490 [wmi_vdev_param_set_he_sounding_mode] = 491 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 492 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 493 #ifdef WLAN_FEATURE_11BE 494 [wmi_vdev_param_set_ehtop] = WMI_VDEV_PARAM_EHTOPS_0_31, 495 [wmi_vdev_param_set_eht_mu_mode] = WMI_VDEV_PARAM_SET_EHT_MU_MODE, 496 [wmi_vdev_param_set_eht_puncturing_mode] = 497 WMI_VDEV_PARAM_SET_EHT_PUNCTURING_MODE, 498 [wmi_vdev_param_set_eht_ltf] = WMI_VDEV_PARAM_EHT_LTF, 499 [wmi_vdev_param_set_ul_eht_ltf] = WMI_VDEV_PARAM_UL_EHT_LTF, 500 [wmi_vdev_param_set_eht_dcm] = WMI_VDEV_PARAM_EHT_DCM, 501 [wmi_vdev_param_set_eht_range_ext] = WMI_VDEV_PARAM_EHT_RANGE_EXT, 502 [wmi_vdev_param_set_non_data_eht_range_ext] = 503 WMI_VDEV_PARAM_NON_DATA_EHT_RANGE_EXT, 504 #endif 505 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 506 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 507 [wmi_vdev_param_atf_ssid_sched_policy] = 508 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 509 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 510 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 511 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 512 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 513 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 514 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 515 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 516 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 517 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 518 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 519 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 520 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 521 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 522 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 523 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 524 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 525 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 526 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 527 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 528 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 529 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 530 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 531 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 532 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 533 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 534 [wmi_vdev_param_mcast_rc_stale_period] = 535 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 536 [wmi_vdev_param_enable_multi_group_key] = 537 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 538 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 539 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 540 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 541 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 542 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 543 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 544 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 545 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 546 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 547 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 548 [wmi_vdev_param_nan_config_features] = 549 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 550 [wmi_vdev_param_enable_disable_rtt_responder_role] = 551 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, 552 [wmi_vdev_param_enable_disable_rtt_initiator_role] = 553 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE, 554 [wmi_vdev_param_mcast_steer] = WMI_VDEV_PARAM_MCAST_STEERING, 555 #ifdef MULTI_CLIENT_LL_SUPPORT 556 [wmi_vdev_param_set_normal_latency_flags_config] = 557 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 558 [wmi_vdev_param_set_xr_latency_flags_config] = 559 WMI_VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION, 560 [wmi_vdev_param_set_low_latency_flags_config] = 561 WMI_VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION, 562 [wmi_vdev_param_set_ultra_low_latency_flags_config] = 563 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION, 564 [wmi_vdev_param_set_normal_latency_ul_dl_config] = 565 WMI_VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION, 566 [wmi_vdev_param_set_xr_latency_ul_dl_config] = 567 WMI_VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION, 568 [wmi_vdev_param_set_low_latency_ul_dl_config] = 569 WMI_VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION, 570 [wmi_vdev_param_set_ultra_low_latency_ul_dl_config] = 571 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION, 572 [wmi_vdev_param_set_default_ll_config] = 573 WMI_VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION, 574 [wmi_vdev_param_set_multi_client_ll_feature_config] = 575 WMI_VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION, 576 #endif 577 [wmi_vdev_param_set_traffic_config] = 578 WMI_VDEV_PARAM_VDEV_TRAFFIC_CONFIG, 579 }; 580 #endif 581 582 #ifndef WMI_PKTLOG_EVENT_CBF 583 #define WMI_PKTLOG_EVENT_CBF 0x100 584 #endif 585 586 /** 587 * Populate the pktlog event tlv array, where 588 * the values are the FW WMI events, which host 589 * uses to communicate with FW for pktlog 590 */ 591 592 static const uint32_t pktlog_event_tlv[] = { 593 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 594 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 595 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 596 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 597 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 598 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 599 WMI_PKTLOG_EVENT_SMART_ANTENNA, 600 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 601 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 602 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 603 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 604 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 605 #ifdef BE_PKTLOG_SUPPORT 606 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 607 #endif 608 }; 609 610 /** 611 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 612 * host to target defines. 613 * @wmi_handle: pointer to wmi_handle 614 * @param pdev_id: host pdev_id to be converted. 615 * Return: target pdev_id after conversion. 616 */ 617 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 618 uint32_t pdev_id) 619 { 620 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 621 if (!wmi_handle->soc->is_pdev_is_map_enable) { 622 switch (pdev_id) { 623 case WMI_HOST_PDEV_ID_0: 624 return WMI_PDEV_ID_1ST; 625 case WMI_HOST_PDEV_ID_1: 626 return WMI_PDEV_ID_2ND; 627 case WMI_HOST_PDEV_ID_2: 628 return WMI_PDEV_ID_3RD; 629 } 630 } else { 631 return wmi_handle->cmd_pdev_id_map[pdev_id]; 632 } 633 } else { 634 return WMI_PDEV_ID_SOC; 635 } 636 637 QDF_ASSERT(0); 638 639 return WMI_PDEV_ID_SOC; 640 } 641 642 /** 643 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 644 * target to host defines. 645 * @wmi_handle: pointer to wmi_handle 646 * @param pdev_id: target pdev_id to be converted. 647 * Return: host pdev_id after conversion. 648 */ 649 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 650 uint32_t pdev_id) 651 { 652 653 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 654 if (!wmi_handle->soc->is_pdev_is_map_enable) { 655 switch (pdev_id) { 656 case WMI_PDEV_ID_1ST: 657 return WMI_HOST_PDEV_ID_0; 658 case WMI_PDEV_ID_2ND: 659 return WMI_HOST_PDEV_ID_1; 660 case WMI_PDEV_ID_3RD: 661 return WMI_HOST_PDEV_ID_2; 662 } 663 } else { 664 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 665 } 666 } else if (pdev_id == WMI_PDEV_ID_SOC) { 667 return WMI_HOST_PDEV_ID_SOC; 668 } else { 669 wmi_err("Invalid pdev_id"); 670 } 671 672 return WMI_HOST_PDEV_ID_INVALID; 673 } 674 675 /** 676 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 677 * host to target defines. 678 * @wmi_handle: pointer to wmi_handle 679 * @param phy_id: host pdev_id to be converted. 680 * Return: target phy_id after conversion. 681 */ 682 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 683 uint32_t phy_id) 684 { 685 if (!wmi_handle->soc->is_phy_id_map_enable || 686 phy_id >= WMI_MAX_RADIOS) { 687 return phy_id; 688 } 689 690 return wmi_handle->cmd_phy_id_map[phy_id]; 691 } 692 693 /** 694 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 695 * target to host defines. 696 * @wmi_handle: pointer to wmi_handle 697 * @param phy_id: target phy_id to be converted. 698 * Return: host phy_id after conversion. 699 */ 700 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 701 uint32_t phy_id) 702 { 703 if (!wmi_handle->soc->is_phy_id_map_enable || 704 phy_id >= WMI_MAX_RADIOS) { 705 return phy_id; 706 } 707 708 return wmi_handle->evt_phy_id_map[phy_id]; 709 } 710 711 /** 712 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 713 * 714 * Return None. 715 */ 716 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 717 uint32_t *pdev_id_map, 718 uint8_t size) 719 { 720 int i = 0; 721 722 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 723 for (i = 0; i < size; i++) { 724 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 725 wmi_handle->evt_pdev_id_map[i] = 726 WMI_HOST_PDEV_ID_INVALID; 727 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 728 wmi_handle->evt_phy_id_map[i] = 729 WMI_HOST_PDEV_ID_INVALID; 730 } 731 732 for (i = 0; i < size; i++) { 733 if (wmi_handle->cmd_pdev_id_map[i] != 734 WMI_HOST_PDEV_ID_INVALID) { 735 wmi_handle->evt_pdev_id_map 736 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 737 } 738 if (wmi_handle->cmd_phy_id_map[i] != 739 WMI_HOST_PDEV_ID_INVALID) { 740 wmi_handle->evt_phy_id_map 741 [wmi_handle->cmd_phy_id_map[i]] = i; 742 } 743 } 744 wmi_handle->soc->is_pdev_is_map_enable = true; 745 wmi_handle->soc->is_phy_id_map_enable = true; 746 } else { 747 wmi_handle->soc->is_pdev_is_map_enable = false; 748 wmi_handle->soc->is_phy_id_map_enable = false; 749 } 750 751 wmi_handle->ops->convert_pdev_id_host_to_target = 752 convert_host_pdev_id_to_target_pdev_id; 753 wmi_handle->ops->convert_pdev_id_target_to_host = 754 convert_target_pdev_id_to_host_pdev_id; 755 756 /* phy_id convert function assignments */ 757 wmi_handle->ops->convert_phy_id_host_to_target = 758 convert_host_phy_id_to_target_phy_id; 759 wmi_handle->ops->convert_phy_id_target_to_host = 760 convert_target_phy_id_to_host_phy_id; 761 } 762 763 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 764 * buffer. 765 * @wmi_handle: pointer to wmi_handle 766 * @cmd: pointer target vdev create command buffer 767 * @param: pointer host params for vdev create 768 * 769 * Return: None 770 */ 771 static inline void copy_vdev_create_pdev_id( 772 struct wmi_unified *wmi_handle, 773 wmi_vdev_create_cmd_fixed_param * cmd, 774 struct vdev_create_params *param) 775 { 776 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 777 wmi_handle, 778 param->pdev_id); 779 } 780 781 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 782 { 783 uint16_t mtrace_message_id; 784 785 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 786 (QDF_WMI_MTRACE_GRP_ID(message_id) << 787 QDF_WMI_MTRACE_CMD_NUM_BITS); 788 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 789 mtrace_message_id, vdev_id, data); 790 } 791 qdf_export_symbol(wmi_mtrace); 792 793 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 794 wmi_buf_t buf, 795 uint32_t buflen, uint32_t cmd_id, 796 bool is_qmi_send_support) 797 { 798 if (!is_qmi_send_support) 799 goto send_over_wmi; 800 801 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 802 goto send_over_wmi; 803 804 if (wmi_is_target_suspend_acked(wmi_handle)) { 805 if (QDF_IS_STATUS_SUCCESS( 806 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 807 buflen, cmd_id))) 808 return QDF_STATUS_SUCCESS; 809 } 810 811 send_over_wmi: 812 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 813 814 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 815 } 816 817 /** 818 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 819 * @wmi_handle: wmi handle 820 * @param: pointer to hold vdev create parameter 821 * @macaddr: vdev mac address 822 * 823 * Return: QDF_STATUS_SUCCESS for success or error code 824 */ 825 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 826 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 827 struct vdev_create_params *param) 828 { 829 wmi_vdev_create_cmd_fixed_param *cmd; 830 wmi_buf_t buf; 831 int32_t len = sizeof(*cmd); 832 QDF_STATUS ret; 833 int num_bands = 2; 834 uint8_t *buf_ptr; 835 wmi_vdev_txrx_streams *txrx_streams; 836 837 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 838 len += vdev_create_mlo_params_size(param); 839 840 buf = wmi_buf_alloc(wmi_handle, len); 841 if (!buf) 842 return QDF_STATUS_E_NOMEM; 843 844 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 845 WMITLV_SET_HDR(&cmd->tlv_header, 846 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 847 WMITLV_GET_STRUCT_TLVLEN 848 (wmi_vdev_create_cmd_fixed_param)); 849 cmd->vdev_id = param->vdev_id; 850 cmd->vdev_type = param->type; 851 cmd->vdev_subtype = param->subtype; 852 cmd->flags = param->mbssid_flags; 853 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 854 cmd->vdevid_trans = param->vdevid_trans; 855 cmd->num_cfg_txrx_streams = num_bands; 856 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 857 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 858 cmd->vdev_stats_id = param->vdev_stats_id; 859 #endif 860 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 861 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 862 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 863 param->vdev_id, cmd->pdev_id, 864 QDF_MAC_ADDR_REF(macaddr)); 865 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 866 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 867 (num_bands * sizeof(wmi_vdev_txrx_streams))); 868 buf_ptr += WMI_TLV_HDR_SIZE; 869 870 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 871 param->type, param->subtype, 872 param->nss_2g, param->nss_5g); 873 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 874 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 875 txrx_streams->supported_tx_streams = param->nss_2g; 876 txrx_streams->supported_rx_streams = param->nss_2g; 877 WMITLV_SET_HDR(&txrx_streams->tlv_header, 878 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 879 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 880 881 txrx_streams++; 882 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 883 txrx_streams->supported_tx_streams = param->nss_5g; 884 txrx_streams->supported_rx_streams = param->nss_5g; 885 WMITLV_SET_HDR(&txrx_streams->tlv_header, 886 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 887 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 888 889 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 890 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 891 892 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 893 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 894 if (QDF_IS_STATUS_ERROR(ret)) { 895 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 896 wmi_buf_free(buf); 897 } 898 899 return ret; 900 } 901 902 /** 903 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 904 * @wmi_handle: wmi handle 905 * @if_id: vdev id 906 * 907 * Return: QDF_STATUS_SUCCESS for success or error code 908 */ 909 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 910 uint8_t if_id) 911 { 912 wmi_vdev_delete_cmd_fixed_param *cmd; 913 wmi_buf_t buf; 914 QDF_STATUS ret; 915 916 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 917 if (!buf) 918 return QDF_STATUS_E_NOMEM; 919 920 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 921 WMITLV_SET_HDR(&cmd->tlv_header, 922 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 923 WMITLV_GET_STRUCT_TLVLEN 924 (wmi_vdev_delete_cmd_fixed_param)); 925 cmd->vdev_id = if_id; 926 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 927 ret = wmi_unified_cmd_send(wmi_handle, buf, 928 sizeof(wmi_vdev_delete_cmd_fixed_param), 929 WMI_VDEV_DELETE_CMDID); 930 if (QDF_IS_STATUS_ERROR(ret)) { 931 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 932 wmi_buf_free(buf); 933 } 934 wmi_debug("vdev id = %d", if_id); 935 936 return ret; 937 } 938 939 /** 940 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 941 * @wmi_handle: wmi handle 942 * @vdev_id: vdev id 943 * @nss_chains_user_cfg: user configured nss chain params 944 * 945 * Return: QDF_STATUS_SUCCESS for success or error code 946 */ 947 static QDF_STATUS 948 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 949 uint8_t vdev_id, 950 struct vdev_nss_chains *user_cfg) 951 { 952 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 953 wmi_buf_t buf; 954 QDF_STATUS ret; 955 956 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 957 if (!buf) 958 return QDF_STATUS_E_NOMEM; 959 960 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 961 WMITLV_SET_HDR(&cmd->tlv_header, 962 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 963 WMITLV_GET_STRUCT_TLVLEN 964 (wmi_vdev_chainmask_config_cmd_fixed_param)); 965 cmd->vdev_id = vdev_id; 966 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 967 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 968 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 969 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 970 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 971 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 972 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 973 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 974 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 975 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 976 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 977 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 978 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 979 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 980 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 981 982 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 983 ret = wmi_unified_cmd_send(wmi_handle, buf, 984 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 985 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 986 if (QDF_IS_STATUS_ERROR(ret)) { 987 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 988 wmi_buf_free(buf); 989 } 990 wmi_debug("vdev_id %d", vdev_id); 991 992 return ret; 993 } 994 995 /** 996 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 997 * @wmi: wmi handle 998 * @vdev_id: vdev id 999 * 1000 * Return: QDF_STATUS_SUCCESS for success or erro code 1001 */ 1002 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1003 uint8_t vdev_id) 1004 { 1005 wmi_vdev_stop_cmd_fixed_param *cmd; 1006 wmi_buf_t buf; 1007 int32_t len = sizeof(*cmd); 1008 1009 buf = wmi_buf_alloc(wmi, len); 1010 if (!buf) 1011 return QDF_STATUS_E_NOMEM; 1012 1013 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1014 WMITLV_SET_HDR(&cmd->tlv_header, 1015 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1016 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1017 cmd->vdev_id = vdev_id; 1018 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1019 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1020 wmi_err("Failed to send vdev stop command"); 1021 wmi_buf_free(buf); 1022 return QDF_STATUS_E_FAILURE; 1023 } 1024 wmi_debug("vdev id = %d", vdev_id); 1025 1026 return 0; 1027 } 1028 1029 /** 1030 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1031 * @wmi: wmi handle 1032 * @vdev_id: vdev id 1033 * 1034 * Return: QDF_STATUS_SUCCESS for success or error code 1035 */ 1036 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1037 { 1038 wmi_vdev_down_cmd_fixed_param *cmd; 1039 wmi_buf_t buf; 1040 int32_t len = sizeof(*cmd); 1041 1042 buf = wmi_buf_alloc(wmi, len); 1043 if (!buf) 1044 return QDF_STATUS_E_NOMEM; 1045 1046 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1047 WMITLV_SET_HDR(&cmd->tlv_header, 1048 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1049 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1050 cmd->vdev_id = vdev_id; 1051 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1052 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1053 wmi_err("Failed to send vdev down"); 1054 wmi_buf_free(buf); 1055 return QDF_STATUS_E_FAILURE; 1056 } 1057 wmi_debug("vdev_id %d", vdev_id); 1058 1059 return 0; 1060 } 1061 1062 static inline void copy_channel_info( 1063 wmi_vdev_start_request_cmd_fixed_param * cmd, 1064 wmi_channel *chan, 1065 struct vdev_start_params *req) 1066 { 1067 chan->mhz = req->channel.mhz; 1068 1069 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1070 1071 chan->band_center_freq1 = req->channel.cfreq1; 1072 chan->band_center_freq2 = req->channel.cfreq2; 1073 1074 if (req->channel.half_rate) 1075 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1076 else if (req->channel.quarter_rate) 1077 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1078 1079 if (req->channel.dfs_set) { 1080 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1081 cmd->disable_hw_ack = req->disable_hw_ack; 1082 } 1083 1084 if (req->channel.dfs_set_cfreq2) 1085 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1086 1087 if (req->channel.is_stadfs_en) 1088 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1089 1090 /* According to firmware both reg power and max tx power 1091 * on set channel power is used and set it to max reg 1092 * power from regulatory. 1093 */ 1094 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1095 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1096 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1097 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1098 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1099 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1100 1101 } 1102 1103 /** 1104 * vdev_start_cmd_fill_11be() - 11be information fiiling in vdev_ststart 1105 * @cmd: wmi cmd 1106 * @req: vdev start params 1107 * 1108 * Return: QDF status 1109 */ 1110 #ifdef WLAN_FEATURE_11BE 1111 static void 1112 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1113 struct vdev_start_params *req) 1114 { 1115 cmd->eht_ops = req->eht_ops; 1116 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1117 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1118 req->eht_ops, req->channel.puncture_bitmap, 1119 cmd->puncture_20mhz_bitmap); 1120 } 1121 #else 1122 static void 1123 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1124 struct vdev_start_params *req) 1125 { 1126 } 1127 #endif 1128 1129 /** 1130 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1131 * @wmi_handle: wmi handle 1132 * @req: vdev start params 1133 * 1134 * Return: QDF status 1135 */ 1136 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1137 struct vdev_start_params *req) 1138 { 1139 wmi_vdev_start_request_cmd_fixed_param *cmd; 1140 wmi_buf_t buf; 1141 wmi_channel *chan; 1142 int32_t len, ret; 1143 uint8_t *buf_ptr; 1144 1145 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1146 if (!req->is_restart) 1147 len += vdev_start_mlo_params_size(req); 1148 buf = wmi_buf_alloc(wmi_handle, len); 1149 if (!buf) 1150 return QDF_STATUS_E_NOMEM; 1151 1152 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1153 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1154 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1155 WMITLV_SET_HDR(&cmd->tlv_header, 1156 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1157 WMITLV_GET_STRUCT_TLVLEN 1158 (wmi_vdev_start_request_cmd_fixed_param)); 1159 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1160 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1161 cmd->vdev_id = req->vdev_id; 1162 1163 /* Fill channel info */ 1164 copy_channel_info(cmd, chan, req); 1165 cmd->beacon_interval = req->beacon_interval; 1166 cmd->dtim_period = req->dtim_period; 1167 1168 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1169 if (req->bcn_tx_rate_code) 1170 wmi_enable_bcn_ratecode(&cmd->flags); 1171 1172 if (!req->is_restart) { 1173 if (req->pmf_enabled) 1174 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1175 1176 cmd->mbss_capability_flags = req->mbssid_flags; 1177 cmd->vdevid_trans = req->vdevid_trans; 1178 } 1179 1180 /* Copy the SSID */ 1181 if (req->ssid.length) { 1182 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1183 cmd->ssid.ssid_len = req->ssid.length; 1184 else 1185 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1186 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1187 cmd->ssid.ssid_len); 1188 } 1189 1190 if (req->hidden_ssid) 1191 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1192 1193 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1194 cmd->num_noa_descriptors = req->num_noa_descriptors; 1195 cmd->preferred_rx_streams = req->preferred_rx_streams; 1196 cmd->preferred_tx_streams = req->preferred_tx_streams; 1197 cmd->cac_duration_ms = req->cac_duration_ms; 1198 cmd->regdomain = req->regdomain; 1199 cmd->he_ops = req->he_ops; 1200 1201 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1202 sizeof(wmi_channel)); 1203 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1204 cmd->num_noa_descriptors * 1205 sizeof(wmi_p2p_noa_descriptor)); 1206 if (!req->is_restart) { 1207 buf_ptr += WMI_TLV_HDR_SIZE + 1208 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1209 1210 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1211 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1212 } 1213 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1214 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1215 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1216 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1217 "req->dis_hw_ack: %d ", req->vdev_id, 1218 chan->mhz, req->channel.phy_mode, chan->info, 1219 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1220 chan->band_center_freq1, chan->band_center_freq2, 1221 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1222 req->preferred_tx_streams, req->preferred_rx_streams, 1223 req->ldpc_rx_enabled, req->cac_duration_ms, 1224 req->regdomain, req->he_ops, 1225 req->disable_hw_ack); 1226 1227 vdev_start_cmd_fill_11be(cmd, req); 1228 1229 if (req->is_restart) { 1230 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1231 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1232 WMI_VDEV_RESTART_REQUEST_CMDID); 1233 } else { 1234 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1235 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1236 WMI_VDEV_START_REQUEST_CMDID); 1237 } 1238 if (ret) { 1239 wmi_err("Failed to send vdev start command"); 1240 wmi_buf_free(buf); 1241 return QDF_STATUS_E_FAILURE; 1242 } 1243 1244 return QDF_STATUS_SUCCESS; 1245 } 1246 1247 /** 1248 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1249 * @wmi: wmi handle 1250 * @peer_addr: peer mac address 1251 * @param: pointer to hold peer flush tid parameter 1252 * 1253 * Return: 0 for success or error code 1254 */ 1255 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1256 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1257 struct peer_flush_params *param) 1258 { 1259 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1260 wmi_buf_t buf; 1261 int32_t len = sizeof(*cmd); 1262 1263 buf = wmi_buf_alloc(wmi, len); 1264 if (!buf) 1265 return QDF_STATUS_E_NOMEM; 1266 1267 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1268 WMITLV_SET_HDR(&cmd->tlv_header, 1269 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1270 WMITLV_GET_STRUCT_TLVLEN 1271 (wmi_peer_flush_tids_cmd_fixed_param)); 1272 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1273 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1274 cmd->vdev_id = param->vdev_id; 1275 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1276 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1277 param->peer_tid_bitmap); 1278 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1279 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1280 wmi_err("Failed to send flush tid command"); 1281 wmi_buf_free(buf); 1282 return QDF_STATUS_E_FAILURE; 1283 } 1284 1285 return 0; 1286 } 1287 1288 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1289 /** 1290 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1291 * @policy: The target i/f flush policy value 1292 * 1293 * Return: WMI layer flush policy 1294 */ 1295 static wmi_peer_flush_policy 1296 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1297 { 1298 switch (policy) { 1299 case PEER_TXQ_FLUSH_POLICY_NONE: 1300 return WMI_NO_FLUSH; 1301 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1302 return WMI_TWT_FLUSH; 1303 default: 1304 return WMI_MAX_FLUSH_POLICY; 1305 } 1306 } 1307 1308 /** 1309 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1310 * @wmi: wmi handle 1311 * @para: Peer txq flush configuration 1312 * 1313 * Return: QDF status 1314 */ 1315 static QDF_STATUS 1316 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1317 struct peer_txq_flush_config_params *param) 1318 { 1319 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1320 wmi_buf_t buf; 1321 int32_t len = sizeof(*cmd); 1322 1323 buf = wmi_buf_alloc(wmi, len); 1324 if (!buf) 1325 return QDF_STATUS_E_NOMEM; 1326 1327 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1328 1329 WMITLV_SET_HDR(&cmd->tlv_header, 1330 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1331 WMITLV_GET_STRUCT_TLVLEN 1332 (wmi_peer_flush_policy_cmd_fixed_param)); 1333 1334 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1335 cmd->peer_tid_bitmap = param->tid_mask; 1336 cmd->vdev_id = param->vdev_id; 1337 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1338 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1339 wmi_buf_free(buf); 1340 wmi_err("Invalid policy"); 1341 return QDF_STATUS_E_INVAL; 1342 } 1343 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1344 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1345 param->tid_mask, param->policy); 1346 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1347 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1348 wmi_err("Failed to send flush policy command"); 1349 wmi_buf_free(buf); 1350 return QDF_STATUS_E_FAILURE; 1351 } 1352 1353 return QDF_STATUS_SUCCESS; 1354 } 1355 #endif 1356 /** 1357 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1358 * @wmi: wmi handle 1359 * @peer_addr: peer mac addr 1360 * @param: peer delete parameters 1361 * 1362 * Return: QDF_STATUS_SUCCESS for success or error code 1363 */ 1364 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1365 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1366 struct peer_delete_cmd_params *param) 1367 { 1368 wmi_peer_delete_cmd_fixed_param *cmd; 1369 wmi_buf_t buf; 1370 int32_t len = sizeof(*cmd); 1371 uint8_t *buf_ptr; 1372 1373 len += peer_delete_mlo_params_size(param); 1374 buf = wmi_buf_alloc(wmi, len); 1375 if (!buf) 1376 return QDF_STATUS_E_NOMEM; 1377 1378 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1379 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1380 WMITLV_SET_HDR(&cmd->tlv_header, 1381 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1382 WMITLV_GET_STRUCT_TLVLEN 1383 (wmi_peer_delete_cmd_fixed_param)); 1384 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1385 cmd->vdev_id = param->vdev_id; 1386 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1387 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1388 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1389 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1390 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1391 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1392 wmi_err("Failed to send peer delete command"); 1393 wmi_buf_free(buf); 1394 return QDF_STATUS_E_FAILURE; 1395 } 1396 return 0; 1397 } 1398 1399 static void 1400 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1401 { 1402 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1403 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1404 WMI_PEER_TYPE_DEFAULT); 1405 1406 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1407 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1408 WMI_PEER_TYPE_BSS); 1409 1410 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1411 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1412 WMI_PEER_TYPE_TDLS); 1413 1414 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1415 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1416 WMI_PEER_TYPE_NAN_DATA); 1417 1418 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1419 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1420 WMI_PEER_TYPE_PASN); 1421 } 1422 1423 /** 1424 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1425 * @wmi: wmi handle 1426 * @param: pointer to hold peer delete all parameter 1427 * 1428 * Return: QDF_STATUS_SUCCESS for success or error code 1429 */ 1430 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1431 wmi_unified_t wmi, 1432 struct peer_delete_all_params *param) 1433 { 1434 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1435 wmi_buf_t buf; 1436 int32_t len = sizeof(*cmd); 1437 1438 buf = wmi_buf_alloc(wmi, len); 1439 if (!buf) 1440 return QDF_STATUS_E_NOMEM; 1441 1442 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1443 WMITLV_SET_HDR( 1444 &cmd->tlv_header, 1445 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1446 WMITLV_GET_STRUCT_TLVLEN 1447 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1448 cmd->vdev_id = param->vdev_id; 1449 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1450 cmd->peer_type_bitmap); 1451 1452 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1453 param->peer_type_bitmap); 1454 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1455 if (wmi_unified_cmd_send(wmi, buf, len, 1456 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1457 wmi_err("Failed to send peer del all command"); 1458 wmi_buf_free(buf); 1459 return QDF_STATUS_E_FAILURE; 1460 } 1461 1462 return QDF_STATUS_SUCCESS; 1463 } 1464 1465 /** 1466 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1467 * to target id. 1468 * @peer_param_id: host param id. 1469 * 1470 * Return: Target param id. 1471 */ 1472 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1473 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1474 uint32_t peer_param_id) 1475 { 1476 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1477 return peer_param_tlv[peer_param_id]; 1478 return WMI_UNAVAILABLE_PARAM; 1479 } 1480 #else 1481 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1482 uint32_t peer_param_id) 1483 { 1484 return peer_param_id; 1485 } 1486 #endif 1487 1488 #ifdef WLAN_SUPPORT_PPEDS 1489 /** 1490 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1491 * @wmi: wmi handle 1492 * @param: pointer to hold PPE DS config 1493 * 1494 * Return: QDF_STATUS_SUCCESS for success or error code 1495 */ 1496 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1497 struct peer_ppe_ds_param *param) 1498 { 1499 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1500 wmi_buf_t buf; 1501 int32_t err; 1502 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1503 1504 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1505 if (!buf) 1506 return QDF_STATUS_E_NOMEM; 1507 1508 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1509 WMITLV_SET_HDR(&cmd->tlv_header, 1510 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1511 WMITLV_GET_STRUCT_TLVLEN 1512 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1513 1514 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1515 1516 if (param->ppe_routing_enabled) 1517 cmd->ppe_routing_enable = param->use_ppe ? 1518 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1519 else 1520 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1521 1522 cmd->service_code = param->service_code; 1523 cmd->priority_valid = param->priority_valid; 1524 cmd->src_info = param->src_info; 1525 cmd->vdev_id = param->vdev_id; 1526 1527 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1528 "ppe_routing_enable: %u service_code: %u\n" 1529 "priority_valid:%d src_info:%u", 1530 param->vdev_id, 1531 QDF_MAC_ADDR_REF(param->peer_macaddr), 1532 param->ppe_routing_enabled, 1533 param->service_code, 1534 param->priority_valid, 1535 param->src_info); 1536 1537 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1538 err = wmi_unified_cmd_send(wmi, buf, 1539 len, 1540 WMI_PEER_CONFIG_PPE_DS_CMDID); 1541 if (err) { 1542 wmi_err("Failed to send ppeds config cmd"); 1543 wmi_buf_free(buf); 1544 return QDF_STATUS_E_FAILURE; 1545 } 1546 1547 return 0; 1548 } 1549 #endif /* WLAN_SUPPORT_PPEDS */ 1550 1551 /** 1552 * send_peer_param_cmd_tlv() - set peer parameter in fw 1553 * @wmi: wmi handle 1554 * @peer_addr: peer mac address 1555 * @param : pointer to hold peer set parameter 1556 * 1557 * Return: QDF_STATUS_SUCCESS for success or error code 1558 */ 1559 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1560 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1561 struct peer_set_params *param) 1562 { 1563 wmi_peer_set_param_cmd_fixed_param *cmd; 1564 wmi_buf_t buf; 1565 int32_t err; 1566 uint32_t param_id; 1567 1568 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1569 if (param_id == WMI_UNAVAILABLE_PARAM) { 1570 wmi_err("Unavailable param %d", param->param_id); 1571 return QDF_STATUS_E_NOSUPPORT; 1572 } 1573 1574 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1575 if (!buf) 1576 return QDF_STATUS_E_NOMEM; 1577 1578 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1579 WMITLV_SET_HDR(&cmd->tlv_header, 1580 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1581 WMITLV_GET_STRUCT_TLVLEN 1582 (wmi_peer_set_param_cmd_fixed_param)); 1583 cmd->vdev_id = param->vdev_id; 1584 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1585 cmd->param_id = param_id; 1586 cmd->param_value = param->param_value; 1587 1588 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1589 cmd->vdev_id, 1590 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1591 cmd->param_value); 1592 1593 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1594 err = wmi_unified_cmd_send(wmi, buf, 1595 sizeof(wmi_peer_set_param_cmd_fixed_param), 1596 WMI_PEER_SET_PARAM_CMDID); 1597 if (err) { 1598 wmi_err("Failed to send set_param cmd"); 1599 wmi_buf_free(buf); 1600 return QDF_STATUS_E_FAILURE; 1601 } 1602 1603 return 0; 1604 } 1605 1606 /** 1607 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1608 * @wmi: wmi handle 1609 * @bssid: bssid 1610 * @vdev_up_params: pointer to hold vdev up parameter 1611 * 1612 * Return: QDF_STATUS_SUCCESS for success or error code 1613 */ 1614 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1615 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1616 struct vdev_up_params *params) 1617 { 1618 wmi_vdev_up_cmd_fixed_param *cmd; 1619 wmi_buf_t buf; 1620 int32_t len = sizeof(*cmd); 1621 1622 wmi_debug("VDEV_UP"); 1623 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1624 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1625 buf = wmi_buf_alloc(wmi, len); 1626 if (!buf) 1627 return QDF_STATUS_E_NOMEM; 1628 1629 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1630 WMITLV_SET_HDR(&cmd->tlv_header, 1631 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1632 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1633 cmd->vdev_id = params->vdev_id; 1634 cmd->vdev_assoc_id = params->assoc_id; 1635 cmd->profile_idx = params->profile_idx; 1636 cmd->profile_num = params->profile_num; 1637 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1638 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1639 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1640 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1641 wmi_err("Failed to send vdev up command"); 1642 wmi_buf_free(buf); 1643 return QDF_STATUS_E_FAILURE; 1644 } 1645 1646 return 0; 1647 } 1648 1649 /** 1650 * send_peer_create_cmd_tlv() - send peer create command to fw 1651 * @wmi: wmi handle 1652 * @peer_addr: peer mac address 1653 * @peer_type: peer type 1654 * @vdev_id: vdev id 1655 * 1656 * Return: QDF_STATUS_SUCCESS for success or error code 1657 */ 1658 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1659 struct peer_create_params *param) 1660 { 1661 wmi_peer_create_cmd_fixed_param *cmd; 1662 wmi_buf_t buf; 1663 uint8_t *buf_ptr; 1664 int32_t len = sizeof(*cmd); 1665 1666 len += peer_create_mlo_params_size(param); 1667 buf = wmi_buf_alloc(wmi, len); 1668 if (!buf) 1669 return QDF_STATUS_E_NOMEM; 1670 1671 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1672 WMITLV_SET_HDR(&cmd->tlv_header, 1673 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1674 WMITLV_GET_STRUCT_TLVLEN 1675 (wmi_peer_create_cmd_fixed_param)); 1676 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1677 cmd->peer_type = param->peer_type; 1678 cmd->vdev_id = param->vdev_id; 1679 1680 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1681 buf_ptr += sizeof(*cmd); 1682 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1683 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1684 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1685 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1686 wmi_buf_free(buf); 1687 return QDF_STATUS_E_FAILURE; 1688 } 1689 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1690 QDF_MAC_ADDR_REF(param->peer_addr), 1691 param->vdev_id); 1692 1693 return 0; 1694 } 1695 1696 /** 1697 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1698 * command to fw 1699 * @wmi: wmi handle 1700 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1701 * 1702 * Return: 0 for success or error code 1703 */ 1704 static 1705 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1706 struct rx_reorder_queue_setup_params *param) 1707 { 1708 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1709 wmi_buf_t buf; 1710 int32_t len = sizeof(*cmd); 1711 1712 buf = wmi_buf_alloc(wmi, len); 1713 if (!buf) 1714 return QDF_STATUS_E_NOMEM; 1715 1716 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1717 WMITLV_SET_HDR(&cmd->tlv_header, 1718 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1719 WMITLV_GET_STRUCT_TLVLEN 1720 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1721 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1722 cmd->vdev_id = param->vdev_id; 1723 cmd->tid = param->tid; 1724 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1725 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1726 cmd->queue_no = param->queue_no; 1727 cmd->ba_window_size_valid = param->ba_window_size_valid; 1728 cmd->ba_window_size = param->ba_window_size; 1729 1730 1731 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1732 if (wmi_unified_cmd_send(wmi, buf, len, 1733 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1734 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1735 wmi_buf_free(buf); 1736 return QDF_STATUS_E_FAILURE; 1737 } 1738 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1739 QDF_MAC_ADDR_REF(param->peer_macaddr), 1740 param->vdev_id, param->tid); 1741 1742 return QDF_STATUS_SUCCESS; 1743 } 1744 1745 /** 1746 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1747 * command to fw 1748 * @wmi: wmi handle 1749 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1750 * 1751 * Return: 0 for success or error code 1752 */ 1753 static 1754 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1755 struct rx_reorder_queue_remove_params *param) 1756 { 1757 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1758 wmi_buf_t buf; 1759 int32_t len = sizeof(*cmd); 1760 1761 buf = wmi_buf_alloc(wmi, len); 1762 if (!buf) 1763 return QDF_STATUS_E_NOMEM; 1764 1765 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1766 wmi_buf_data(buf); 1767 WMITLV_SET_HDR(&cmd->tlv_header, 1768 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1769 WMITLV_GET_STRUCT_TLVLEN 1770 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1771 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1772 cmd->vdev_id = param->vdev_id; 1773 cmd->tid_mask = param->peer_tid_bitmap; 1774 1775 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1776 if (wmi_unified_cmd_send(wmi, buf, len, 1777 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1778 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1779 wmi_buf_free(buf); 1780 return QDF_STATUS_E_FAILURE; 1781 } 1782 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 1783 QDF_MAC_ADDR_REF(param->peer_macaddr), 1784 param->vdev_id, param->peer_tid_bitmap); 1785 1786 return QDF_STATUS_SUCCESS; 1787 } 1788 1789 #ifdef WLAN_SUPPORT_GREEN_AP 1790 /** 1791 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1792 * @wmi_handle: wmi handle 1793 * @value: value 1794 * @pdev_id: pdev id to have radio context 1795 * 1796 * Return: QDF_STATUS_SUCCESS for success or error code 1797 */ 1798 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1799 uint32_t value, uint8_t pdev_id) 1800 { 1801 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1802 wmi_buf_t buf; 1803 int32_t len = sizeof(*cmd); 1804 1805 wmi_debug("Set Green AP PS val %d", value); 1806 1807 buf = wmi_buf_alloc(wmi_handle, len); 1808 if (!buf) 1809 return QDF_STATUS_E_NOMEM; 1810 1811 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1812 WMITLV_SET_HDR(&cmd->tlv_header, 1813 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1814 WMITLV_GET_STRUCT_TLVLEN 1815 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1816 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1817 wmi_handle, 1818 pdev_id); 1819 cmd->enable = value; 1820 1821 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1822 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1823 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1824 wmi_err("Set Green AP PS param Failed val %d", value); 1825 wmi_buf_free(buf); 1826 return QDF_STATUS_E_FAILURE; 1827 } 1828 1829 return 0; 1830 } 1831 #endif 1832 1833 /** 1834 * send_pdev_utf_cmd_tlv() - send utf command to fw 1835 * @wmi_handle: wmi handle 1836 * @param: pointer to pdev_utf_params 1837 * @mac_id: mac id to have radio context 1838 * 1839 * Return: QDF_STATUS_SUCCESS for success or error code 1840 */ 1841 static QDF_STATUS 1842 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1843 struct pdev_utf_params *param, 1844 uint8_t mac_id) 1845 { 1846 wmi_buf_t buf; 1847 uint8_t *cmd; 1848 /* if param->len is 0 no data is sent, return error */ 1849 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1850 static uint8_t msgref = 1; 1851 uint8_t segNumber = 0, segInfo, numSegments; 1852 uint16_t chunk_len, total_bytes; 1853 uint8_t *bufpos; 1854 struct seg_hdr_info segHdrInfo; 1855 1856 bufpos = param->utf_payload; 1857 total_bytes = param->len; 1858 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1859 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1860 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1861 1862 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1863 numSegments++; 1864 1865 while (param->len) { 1866 if (param->len > MAX_WMI_UTF_LEN) 1867 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1868 else 1869 chunk_len = param->len; 1870 1871 buf = wmi_buf_alloc(wmi_handle, 1872 (chunk_len + sizeof(segHdrInfo) + 1873 WMI_TLV_HDR_SIZE)); 1874 if (!buf) 1875 return QDF_STATUS_E_NOMEM; 1876 1877 cmd = (uint8_t *) wmi_buf_data(buf); 1878 1879 segHdrInfo.len = total_bytes; 1880 segHdrInfo.msgref = msgref; 1881 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1882 segHdrInfo.segmentInfo = segInfo; 1883 segHdrInfo.pad = 0; 1884 1885 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1886 " segHdrInfo.segmentInfo = %d", 1887 segHdrInfo.len, segHdrInfo.msgref, 1888 segHdrInfo.segmentInfo); 1889 1890 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 1891 " chunk len %d", total_bytes, segNumber, 1892 numSegments, chunk_len); 1893 1894 segNumber++; 1895 1896 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1897 (chunk_len + sizeof(segHdrInfo))); 1898 cmd += WMI_TLV_HDR_SIZE; 1899 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1900 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 1901 bufpos, chunk_len); 1902 1903 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1904 ret = wmi_unified_cmd_send(wmi_handle, buf, 1905 (chunk_len + sizeof(segHdrInfo) + 1906 WMI_TLV_HDR_SIZE), 1907 WMI_PDEV_UTF_CMDID); 1908 1909 if (QDF_IS_STATUS_ERROR(ret)) { 1910 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 1911 wmi_buf_free(buf); 1912 break; 1913 } 1914 1915 param->len -= chunk_len; 1916 bufpos += chunk_len; 1917 } 1918 1919 msgref++; 1920 1921 return ret; 1922 } 1923 1924 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1925 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1926 { 1927 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1928 return pdev_param_tlv[host_param]; 1929 return WMI_UNAVAILABLE_PARAM; 1930 } 1931 #else 1932 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1933 { 1934 return host_param; 1935 } 1936 #endif 1937 1938 /** 1939 * send_pdev_param_cmd_tlv() - set pdev parameters 1940 * @wmi_handle: wmi handle 1941 * @param: pointer to pdev parameter 1942 * @mac_id: radio context 1943 * 1944 * Return: 0 on success, errno on failure 1945 */ 1946 static QDF_STATUS 1947 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1948 struct pdev_params *param, 1949 uint8_t mac_id) 1950 { 1951 QDF_STATUS ret; 1952 wmi_pdev_set_param_cmd_fixed_param *cmd; 1953 wmi_buf_t buf; 1954 uint16_t len = sizeof(*cmd); 1955 uint32_t pdev_param; 1956 1957 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1958 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1959 wmi_err("Unavailable param %d", param->param_id); 1960 return QDF_STATUS_E_INVAL; 1961 } 1962 1963 buf = wmi_buf_alloc(wmi_handle, len); 1964 if (!buf) 1965 return QDF_STATUS_E_NOMEM; 1966 1967 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1968 WMITLV_SET_HDR(&cmd->tlv_header, 1969 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1970 WMITLV_GET_STRUCT_TLVLEN 1971 (wmi_pdev_set_param_cmd_fixed_param)); 1972 if (param->is_host_pdev_id) 1973 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 1974 wmi_handle, 1975 mac_id); 1976 else 1977 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1978 wmi_handle, 1979 mac_id); 1980 cmd->param_id = pdev_param; 1981 cmd->param_value = param->param_value; 1982 wmi_debug("Setting pdev param = %x, value = %u", param->param_id, 1983 param->param_value); 1984 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1985 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1986 WMI_PDEV_SET_PARAM_CMDID); 1987 if (QDF_IS_STATUS_ERROR(ret)) { 1988 wmi_err("Failed to send set param command ret = %d", ret); 1989 wmi_buf_free(buf); 1990 } 1991 return ret; 1992 } 1993 1994 /** 1995 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1996 * @wmi_handle: wmi handle 1997 * @msg: Structure containing the following parameters 1998 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1999 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2000 * 2001 * Provides notification to the WLAN firmware that host driver is requesting a 2002 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2003 * configurations that include the Dual Band Simultaneous (DBS) feature. 2004 * 2005 * Return: Success if the cmd is sent successfully to the firmware 2006 */ 2007 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2008 uint32_t hw_mode_index) 2009 { 2010 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2011 wmi_buf_t buf; 2012 uint32_t len; 2013 2014 len = sizeof(*cmd); 2015 2016 buf = wmi_buf_alloc(wmi_handle, len); 2017 if (!buf) 2018 return QDF_STATUS_E_NOMEM; 2019 2020 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2021 WMITLV_SET_HDR(&cmd->tlv_header, 2022 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2023 WMITLV_GET_STRUCT_TLVLEN( 2024 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2025 2026 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2027 wmi_handle, 2028 WMI_HOST_PDEV_ID_SOC); 2029 cmd->hw_mode_index = hw_mode_index; 2030 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2031 2032 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2033 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2034 WMI_PDEV_SET_HW_MODE_CMDID)) { 2035 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2036 wmi_buf_free(buf); 2037 return QDF_STATUS_E_FAILURE; 2038 } 2039 2040 return QDF_STATUS_SUCCESS; 2041 } 2042 2043 /** 2044 * send_suspend_cmd_tlv() - WMI suspend function 2045 * @param wmi_handle : handle to WMI. 2046 * @param param : pointer to hold suspend parameter 2047 * @mac_id: radio context 2048 * 2049 * Return 0 on success and -ve on failure. 2050 */ 2051 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2052 struct suspend_params *param, 2053 uint8_t mac_id) 2054 { 2055 wmi_pdev_suspend_cmd_fixed_param *cmd; 2056 wmi_buf_t wmibuf; 2057 uint32_t len = sizeof(*cmd); 2058 int32_t ret; 2059 2060 /* 2061 * send the command to Target to ignore the 2062 * PCIE reset so as to ensure that Host and target 2063 * states are in sync 2064 */ 2065 wmibuf = wmi_buf_alloc(wmi_handle, len); 2066 if (!wmibuf) 2067 return QDF_STATUS_E_NOMEM; 2068 2069 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2070 WMITLV_SET_HDR(&cmd->tlv_header, 2071 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2072 WMITLV_GET_STRUCT_TLVLEN 2073 (wmi_pdev_suspend_cmd_fixed_param)); 2074 if (param->disable_target_intr) 2075 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2076 else 2077 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2078 2079 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2080 wmi_handle, 2081 mac_id); 2082 2083 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2084 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2085 WMI_PDEV_SUSPEND_CMDID); 2086 if (ret) { 2087 wmi_buf_free(wmibuf); 2088 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2089 } 2090 2091 return ret; 2092 } 2093 2094 /** 2095 * send_resume_cmd_tlv() - WMI resume function 2096 * @param wmi_handle : handle to WMI. 2097 * @mac_id: radio context 2098 * 2099 * Return: 0 on success and -ve on failure. 2100 */ 2101 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2102 uint8_t mac_id) 2103 { 2104 wmi_buf_t wmibuf; 2105 wmi_pdev_resume_cmd_fixed_param *cmd; 2106 QDF_STATUS ret; 2107 2108 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2109 if (!wmibuf) 2110 return QDF_STATUS_E_NOMEM; 2111 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2112 WMITLV_SET_HDR(&cmd->tlv_header, 2113 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2114 WMITLV_GET_STRUCT_TLVLEN 2115 (wmi_pdev_resume_cmd_fixed_param)); 2116 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2117 wmi_handle, 2118 mac_id); 2119 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2120 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2121 WMI_PDEV_RESUME_CMDID); 2122 if (QDF_IS_STATUS_ERROR(ret)) { 2123 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2124 wmi_buf_free(wmibuf); 2125 } 2126 2127 return ret; 2128 } 2129 2130 /** 2131 * send_wow_enable_cmd_tlv() - WMI wow enable function 2132 * @param wmi_handle : handle to WMI. 2133 * @param param : pointer to hold wow enable parameter 2134 * @mac_id: radio context 2135 * 2136 * Return: 0 on success and -ve on failure. 2137 */ 2138 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2139 struct wow_cmd_params *param, 2140 uint8_t mac_id) 2141 { 2142 wmi_wow_enable_cmd_fixed_param *cmd; 2143 wmi_buf_t buf; 2144 int32_t len; 2145 int32_t ret; 2146 2147 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2148 2149 buf = wmi_buf_alloc(wmi_handle, len); 2150 if (!buf) 2151 return QDF_STATUS_E_NOMEM; 2152 2153 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2154 WMITLV_SET_HDR(&cmd->tlv_header, 2155 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2156 WMITLV_GET_STRUCT_TLVLEN 2157 (wmi_wow_enable_cmd_fixed_param)); 2158 cmd->enable = param->enable; 2159 if (param->can_suspend_link) 2160 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2161 else 2162 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2163 cmd->flags = param->flags; 2164 2165 wmi_debug("suspend type: %s flag is 0x%x", 2166 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2167 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2168 cmd->flags); 2169 2170 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2171 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2172 WMI_WOW_ENABLE_CMDID); 2173 if (ret) 2174 wmi_buf_free(buf); 2175 2176 return ret; 2177 } 2178 2179 /** 2180 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2181 * @wmi_handle: wmi handle 2182 * @peer_addr: peer mac address 2183 * @param: pointer to ap_ps parameter structure 2184 * 2185 * Return: QDF_STATUS_SUCCESS for success or error code 2186 */ 2187 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2188 uint8_t *peer_addr, 2189 struct ap_ps_params *param) 2190 { 2191 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2192 wmi_buf_t buf; 2193 int32_t err; 2194 2195 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2196 if (!buf) 2197 return QDF_STATUS_E_NOMEM; 2198 2199 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2200 WMITLV_SET_HDR(&cmd->tlv_header, 2201 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2202 WMITLV_GET_STRUCT_TLVLEN 2203 (wmi_ap_ps_peer_cmd_fixed_param)); 2204 cmd->vdev_id = param->vdev_id; 2205 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2206 cmd->param = param->param; 2207 cmd->value = param->value; 2208 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2209 err = wmi_unified_cmd_send(wmi_handle, buf, 2210 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2211 if (err) { 2212 wmi_err("Failed to send set_ap_ps_param cmd"); 2213 wmi_buf_free(buf); 2214 return QDF_STATUS_E_FAILURE; 2215 } 2216 2217 return 0; 2218 } 2219 2220 /** 2221 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2222 * @wmi_handle: wmi handle 2223 * @peer_addr: peer mac address 2224 * @param: pointer to sta_ps parameter structure 2225 * 2226 * Return: QDF_STATUS_SUCCESS for success or error code 2227 */ 2228 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2229 struct sta_ps_params *param) 2230 { 2231 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2232 wmi_buf_t buf; 2233 int32_t len = sizeof(*cmd); 2234 2235 buf = wmi_buf_alloc(wmi_handle, len); 2236 if (!buf) 2237 return QDF_STATUS_E_NOMEM; 2238 2239 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2240 WMITLV_SET_HDR(&cmd->tlv_header, 2241 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2242 WMITLV_GET_STRUCT_TLVLEN 2243 (wmi_sta_powersave_param_cmd_fixed_param)); 2244 cmd->vdev_id = param->vdev_id; 2245 cmd->param = param->param_id; 2246 cmd->value = param->value; 2247 2248 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2249 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2250 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2251 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2252 param->vdev_id, param->param_id, param->value); 2253 wmi_buf_free(buf); 2254 return QDF_STATUS_E_FAILURE; 2255 } 2256 2257 return 0; 2258 } 2259 2260 /** 2261 * send_crash_inject_cmd_tlv() - inject fw crash 2262 * @wmi_handle: wmi handle 2263 * @param: ponirt to crash inject parameter structure 2264 * 2265 * Return: QDF_STATUS_SUCCESS for success or return error 2266 */ 2267 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2268 struct crash_inject *param) 2269 { 2270 int32_t ret = 0; 2271 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2272 uint16_t len = sizeof(*cmd); 2273 wmi_buf_t buf; 2274 2275 buf = wmi_buf_alloc(wmi_handle, len); 2276 if (!buf) 2277 return QDF_STATUS_E_NOMEM; 2278 2279 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2280 WMITLV_SET_HDR(&cmd->tlv_header, 2281 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2282 WMITLV_GET_STRUCT_TLVLEN 2283 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2284 cmd->type = param->type; 2285 cmd->delay_time_ms = param->delay_time_ms; 2286 2287 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2288 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2289 WMI_FORCE_FW_HANG_CMDID); 2290 if (ret) { 2291 wmi_err("Failed to send set param command, ret = %d", ret); 2292 wmi_buf_free(buf); 2293 } 2294 2295 return ret; 2296 } 2297 2298 /** 2299 * send_dbglog_cmd_tlv() - set debug log level 2300 * @param wmi_handle : handle to WMI. 2301 * @param param : pointer to hold dbglog level parameter 2302 * 2303 * Return: 0 on success and -ve on failure. 2304 */ 2305 static QDF_STATUS 2306 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2307 struct dbglog_params *dbglog_param) 2308 { 2309 wmi_buf_t buf; 2310 wmi_debug_log_config_cmd_fixed_param *configmsg; 2311 QDF_STATUS status; 2312 int32_t i; 2313 int32_t len; 2314 int8_t *buf_ptr; 2315 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2316 2317 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2318 2319 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2320 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2321 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2322 buf = wmi_buf_alloc(wmi_handle, len); 2323 if (!buf) 2324 return QDF_STATUS_E_NOMEM; 2325 2326 configmsg = 2327 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2328 buf_ptr = (int8_t *) configmsg; 2329 WMITLV_SET_HDR(&configmsg->tlv_header, 2330 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2331 WMITLV_GET_STRUCT_TLVLEN 2332 (wmi_debug_log_config_cmd_fixed_param)); 2333 configmsg->dbg_log_param = dbglog_param->param; 2334 configmsg->value = dbglog_param->val; 2335 /* Filling in the data part of second tlv -- should 2336 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2337 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2338 sizeof 2339 (wmi_debug_log_config_cmd_fixed_param) 2340 + WMI_TLV_HDR_SIZE); 2341 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2342 WMITLV_TAG_ARRAY_UINT32, 2343 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2344 if (dbglog_param->module_id_bitmap) { 2345 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2346 module_id_bitmap_array[i] = 2347 dbglog_param->module_id_bitmap[i]; 2348 } 2349 } 2350 2351 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2352 status = wmi_unified_cmd_send(wmi_handle, buf, 2353 len, WMI_DBGLOG_CFG_CMDID); 2354 2355 if (status != QDF_STATUS_SUCCESS) 2356 wmi_buf_free(buf); 2357 2358 return status; 2359 } 2360 2361 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2362 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2363 { 2364 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2365 return vdev_param_tlv[host_param]; 2366 return WMI_UNAVAILABLE_PARAM; 2367 } 2368 #else 2369 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2370 { 2371 return host_param; 2372 } 2373 #endif 2374 2375 /** 2376 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2377 * @param wmi_handle : handle to WMI. 2378 * @param macaddr : MAC address 2379 * @param param : pointer to hold vdev set parameter 2380 * 2381 * Return: 0 on success and -ve on failure. 2382 */ 2383 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2384 struct vdev_set_params *param) 2385 { 2386 QDF_STATUS ret; 2387 wmi_vdev_set_param_cmd_fixed_param *cmd; 2388 wmi_buf_t buf; 2389 uint16_t len = sizeof(*cmd); 2390 uint32_t vdev_param; 2391 2392 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2393 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2394 wmi_err("Vdev param %d not available", param->param_id); 2395 return QDF_STATUS_E_INVAL; 2396 2397 } 2398 2399 buf = wmi_buf_alloc(wmi_handle, len); 2400 if (!buf) 2401 return QDF_STATUS_E_NOMEM; 2402 2403 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2404 WMITLV_SET_HDR(&cmd->tlv_header, 2405 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2406 WMITLV_GET_STRUCT_TLVLEN 2407 (wmi_vdev_set_param_cmd_fixed_param)); 2408 cmd->vdev_id = param->vdev_id; 2409 cmd->param_id = vdev_param; 2410 cmd->param_value = param->param_value; 2411 wmi_debug("Setting vdev %d param = %x, value = %u", 2412 cmd->vdev_id, cmd->param_id, cmd->param_value); 2413 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2414 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2415 WMI_VDEV_SET_PARAM_CMDID); 2416 if (QDF_IS_STATUS_ERROR(ret)) { 2417 wmi_err("Failed to send set param command ret = %d", ret); 2418 wmi_buf_free(buf); 2419 } 2420 2421 return ret; 2422 } 2423 2424 /** 2425 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2426 * @param wmi_handle : handle to WMI. 2427 * @param param : pointer to hold mu sniffer parameter 2428 * 2429 * Return: 0 on success and -ve on failure. 2430 */ 2431 static 2432 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2433 struct vdev_set_mu_snif_param *param) 2434 { 2435 QDF_STATUS ret; 2436 wmi_vdev_set_mu_snif_cmd_param *cmd; 2437 wmi_buf_t buf; 2438 uint32_t *tmp_ptr; 2439 uint16_t len = sizeof(*cmd); 2440 uint8_t *buf_ptr; 2441 uint32_t i; 2442 2443 /* Length TLV placeholder for array of uint32_t */ 2444 len += WMI_TLV_HDR_SIZE; 2445 2446 if (param->num_aid) 2447 len += param->num_aid * sizeof(uint32_t); 2448 2449 buf = wmi_buf_alloc(wmi_handle, len); 2450 if (!buf) 2451 return QDF_STATUS_E_NOMEM; 2452 2453 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2454 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2455 2456 WMITLV_SET_HDR(&cmd->tlv_header, 2457 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2458 WMITLV_GET_STRUCT_TLVLEN 2459 (wmi_vdev_set_mu_snif_cmd_param)); 2460 2461 cmd->vdev_id = param->vdev_id; 2462 cmd->mode = param->mode; 2463 cmd->max_num_user = param->num_user; 2464 2465 buf_ptr += sizeof(*cmd); 2466 2467 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2468 2469 for (i = 0; i < param->num_aid; ++i) 2470 tmp_ptr[i] = param->aid[i]; 2471 2472 WMITLV_SET_HDR(buf_ptr, 2473 WMITLV_TAG_ARRAY_UINT32, 2474 (param->num_aid * sizeof(uint32_t))); 2475 2476 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2477 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2478 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2479 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2480 WMI_VDEV_SET_MU_SNIF_CMDID); 2481 if (QDF_IS_STATUS_ERROR(ret)) { 2482 wmi_err("Failed to send set param command ret = %d", ret); 2483 wmi_buf_free(buf); 2484 } 2485 2486 return ret; 2487 } 2488 2489 /** 2490 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2491 * @wmi_handle: handle to WMI. 2492 * @macaddr: Peer mac address to be filter 2493 * @mac_id: mac id to have radio context 2494 * @enb_dsb: Enable MAC based filtering or Disable 2495 * 2496 * Return: QDF_STATUS 2497 */ 2498 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2499 uint8_t *macaddr, 2500 uint8_t mac_id, 2501 uint8_t enb_dsb) 2502 { 2503 int32_t ret; 2504 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2505 wmi_pdev_pktlog_filter_info *mac_info; 2506 wmi_buf_t buf; 2507 uint8_t *buf_ptr; 2508 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2509 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2510 2511 buf = wmi_buf_alloc(wmi_handle, len); 2512 if (!buf) 2513 return QDF_STATUS_E_NOMEM; 2514 2515 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2516 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2517 WMITLV_SET_HDR(&cmd->tlv_header, 2518 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2519 WMITLV_GET_STRUCT_TLVLEN 2520 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2521 cmd->pdev_id = mac_id; 2522 cmd->enable = enb_dsb; 2523 cmd->num_of_mac_addresses = 1; 2524 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2525 2526 buf_ptr += sizeof(*cmd); 2527 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2528 sizeof(wmi_pdev_pktlog_filter_info)); 2529 buf_ptr += WMI_TLV_HDR_SIZE; 2530 2531 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2532 2533 WMITLV_SET_HDR(&mac_info->tlv_header, 2534 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2535 WMITLV_GET_STRUCT_TLVLEN 2536 (wmi_pdev_pktlog_filter_info)); 2537 2538 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2539 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2540 WMI_PDEV_PKTLOG_FILTER_CMDID); 2541 if (ret) { 2542 wmi_err("Failed to send peer based pktlog command to FW =%d" 2543 , ret); 2544 wmi_buf_free(buf); 2545 } 2546 2547 return ret; 2548 } 2549 2550 /** 2551 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2552 * @param wmi_handle : handle to WMI. 2553 * @param PKTLOG_EVENT : packet log event 2554 * @mac_id: mac id to have radio context 2555 * 2556 * Return: 0 on success and -ve on failure. 2557 */ 2558 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2559 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2560 { 2561 int32_t ret, idx, max_idx; 2562 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2563 wmi_buf_t buf; 2564 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2565 2566 buf = wmi_buf_alloc(wmi_handle, len); 2567 if (!buf) 2568 return -QDF_STATUS_E_NOMEM; 2569 2570 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2571 WMITLV_SET_HDR(&cmd->tlv_header, 2572 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2573 WMITLV_GET_STRUCT_TLVLEN 2574 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2575 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2576 cmd->evlist = 0; 2577 for (idx = 0; idx < max_idx; idx++) { 2578 if (PKTLOG_EVENT & (1 << idx)) 2579 cmd->evlist |= pktlog_event_tlv[idx]; 2580 } 2581 cmd->pdev_id = mac_id; 2582 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2583 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2584 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2585 if (ret) { 2586 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 2587 wmi_buf_free(buf); 2588 } 2589 2590 return ret; 2591 } 2592 2593 /** 2594 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2595 * @param wmi_handle : handle to WMI. 2596 * @mac_id: mac id to have radio context 2597 * 2598 * Return: 0 on success and -ve on failure. 2599 */ 2600 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2601 uint8_t mac_id) 2602 { 2603 int32_t ret; 2604 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2605 wmi_buf_t buf; 2606 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 2607 2608 buf = wmi_buf_alloc(wmi_handle, len); 2609 if (!buf) 2610 return -QDF_STATUS_E_NOMEM; 2611 2612 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 2613 WMITLV_SET_HDR(&cmd->tlv_header, 2614 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2615 WMITLV_GET_STRUCT_TLVLEN 2616 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2617 cmd->pdev_id = mac_id; 2618 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2619 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2620 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2621 if (ret) { 2622 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 2623 wmi_buf_free(buf); 2624 } 2625 2626 return ret; 2627 } 2628 2629 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2630 /** 2631 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2632 * sync time between bwtween host and firmware 2633 * @param wmi_handle : handle to WMI. 2634 * 2635 * Return: None 2636 */ 2637 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2638 { 2639 wmi_buf_t buf; 2640 QDF_STATUS status = QDF_STATUS_SUCCESS; 2641 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2642 int32_t len; 2643 qdf_time_t time_ms; 2644 2645 len = sizeof(*time_stamp); 2646 buf = wmi_buf_alloc(wmi_handle, len); 2647 2648 if (!buf) 2649 return; 2650 2651 time_stamp = 2652 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2653 (wmi_buf_data(buf)); 2654 WMITLV_SET_HDR(&time_stamp->tlv_header, 2655 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2656 WMITLV_GET_STRUCT_TLVLEN( 2657 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2658 2659 time_ms = qdf_get_time_of_the_day_ms(); 2660 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2661 time_stamp->time_stamp_low = time_ms & 2662 WMI_FW_TIME_STAMP_LOW_MASK; 2663 /* 2664 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2665 * wont exceed 27 bit 2666 */ 2667 time_stamp->time_stamp_high = 0; 2668 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 2669 time_stamp->mode, time_stamp->time_stamp_low, 2670 time_stamp->time_stamp_high); 2671 2672 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2673 status = wmi_unified_cmd_send(wmi_handle, buf, 2674 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2675 if (status) { 2676 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2677 wmi_buf_free(buf); 2678 } 2679 2680 } 2681 2682 /** 2683 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2684 * @param wmi_handle : handle to WMI. 2685 * @param param : pointer to hold FILS Discovery send cmd parameter 2686 * 2687 * Return: 0 on success and -ve on failure. 2688 */ 2689 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2690 struct fils_discovery_tmpl_params *param) 2691 { 2692 int32_t ret; 2693 wmi_fd_tmpl_cmd_fixed_param *cmd; 2694 wmi_buf_t wmi_buf; 2695 uint8_t *buf_ptr; 2696 uint32_t wmi_buf_len; 2697 2698 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2699 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2700 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2701 if (!wmi_buf) 2702 return QDF_STATUS_E_NOMEM; 2703 2704 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2705 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2706 WMITLV_SET_HDR(&cmd->tlv_header, 2707 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2708 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2709 cmd->vdev_id = param->vdev_id; 2710 cmd->buf_len = param->tmpl_len; 2711 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2712 2713 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2714 buf_ptr += WMI_TLV_HDR_SIZE; 2715 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2716 2717 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2718 ret = wmi_unified_cmd_send(wmi_handle, 2719 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2720 2721 if (ret) { 2722 wmi_err("Failed to send fd tmpl: %d", ret); 2723 wmi_buf_free(wmi_buf); 2724 return ret; 2725 } 2726 2727 return 0; 2728 } 2729 2730 /** 2731 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2732 * @param wmi_handle : handle to WMI. 2733 * @param param : pointer to hold beacon send cmd parameter 2734 * 2735 * Return: 0 on success and -ve on failure. 2736 */ 2737 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2738 struct beacon_tmpl_params *param) 2739 { 2740 int32_t ret; 2741 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2742 wmi_bcn_prb_info *bcn_prb_info; 2743 wmi_buf_t wmi_buf; 2744 uint8_t *buf_ptr; 2745 uint32_t wmi_buf_len; 2746 2747 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2748 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2749 param->tmpl_len_aligned + 2750 bcn_tmpl_mlo_param_size(param) + 2751 bcn_tmpl_ml_info_size(param); 2752 2753 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2754 if (!wmi_buf) 2755 return QDF_STATUS_E_NOMEM; 2756 2757 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2758 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2759 WMITLV_SET_HDR(&cmd->tlv_header, 2760 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2761 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2762 cmd->vdev_id = param->vdev_id; 2763 cmd->tim_ie_offset = param->tim_ie_offset; 2764 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2765 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2766 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2767 cmd->esp_ie_offset = param->esp_ie_offset; 2768 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2769 cmd->ema_params = param->ema_params; 2770 cmd->buf_len = param->tmpl_len; 2771 cmd->csa_event_bitmap = param->csa_event_bitmap; 2772 2773 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 2774 param->enable_bigtk); 2775 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2776 2777 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2778 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2779 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2780 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2781 bcn_prb_info->caps = 0; 2782 bcn_prb_info->erp = 0; 2783 buf_ptr += sizeof(wmi_bcn_prb_info); 2784 2785 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2786 buf_ptr += WMI_TLV_HDR_SIZE; 2787 2788 /* for big endian host, copy engine byte_swap is enabled 2789 * But the frame content is in network byte order 2790 * Need to byte swap the frame content - so when copy engine 2791 * does byte_swap - target gets frame content in the correct order 2792 */ 2793 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 2794 param->tmpl_len); 2795 2796 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 2797 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 2798 2799 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 2800 2801 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2802 ret = wmi_unified_cmd_send(wmi_handle, 2803 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2804 if (ret) { 2805 wmi_err("Failed to send bcn tmpl: %d", ret); 2806 wmi_buf_free(wmi_buf); 2807 } 2808 2809 return 0; 2810 } 2811 2812 #ifdef WLAN_FEATURE_11BE 2813 static inline void copy_peer_flags_tlv_11be( 2814 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2815 struct peer_assoc_params *param) 2816 { 2817 if (param->bw_320) 2818 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 2819 if (param->eht_flag) 2820 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 2821 2822 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 2823 } 2824 #else 2825 static inline void copy_peer_flags_tlv_11be( 2826 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2827 struct peer_assoc_params *param) 2828 { 2829 } 2830 #endif 2831 2832 static inline void copy_peer_flags_tlv( 2833 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2834 struct peer_assoc_params *param) 2835 { 2836 /* 2837 * The target only needs a subset of the flags maintained in the host. 2838 * Just populate those flags and send it down 2839 */ 2840 cmd->peer_flags = 0; 2841 if (param->peer_dms_capable) 2842 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 2843 /* 2844 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2845 */ 2846 if (param->is_wme_set) { 2847 2848 if (param->qos_flag) 2849 cmd->peer_flags |= WMI_PEER_QOS; 2850 if (param->apsd_flag) 2851 cmd->peer_flags |= WMI_PEER_APSD; 2852 if (param->ht_flag) 2853 cmd->peer_flags |= WMI_PEER_HT; 2854 if (param->bw_40) 2855 cmd->peer_flags |= WMI_PEER_40MHZ; 2856 if (param->bw_80) 2857 cmd->peer_flags |= WMI_PEER_80MHZ; 2858 if (param->bw_160) 2859 cmd->peer_flags |= WMI_PEER_160MHZ; 2860 2861 copy_peer_flags_tlv_11be(cmd, param); 2862 2863 /* Typically if STBC is enabled for VHT it should be enabled 2864 * for HT as well 2865 **/ 2866 if (param->stbc_flag) 2867 cmd->peer_flags |= WMI_PEER_STBC; 2868 2869 /* Typically if LDPC is enabled for VHT it should be enabled 2870 * for HT as well 2871 **/ 2872 if (param->ldpc_flag) 2873 cmd->peer_flags |= WMI_PEER_LDPC; 2874 2875 if (param->static_mimops_flag) 2876 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2877 if (param->dynamic_mimops_flag) 2878 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2879 if (param->spatial_mux_flag) 2880 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2881 if (param->vht_flag) 2882 cmd->peer_flags |= WMI_PEER_VHT; 2883 if (param->he_flag) 2884 cmd->peer_flags |= WMI_PEER_HE; 2885 if (param->p2p_capable_sta) 2886 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2887 } 2888 2889 if (param->is_pmf_enabled) 2890 cmd->peer_flags |= WMI_PEER_PMF; 2891 /* 2892 * Suppress authorization for all AUTH modes that need 4-way handshake 2893 * (during re-association). 2894 * Authorization will be done for these modes on key installation. 2895 */ 2896 if (param->auth_flag) 2897 cmd->peer_flags |= WMI_PEER_AUTH; 2898 if (param->need_ptk_4_way) 2899 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2900 else 2901 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2902 if (param->need_gtk_2_way) 2903 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2904 /* safe mode bypass the 4-way handshake */ 2905 if (param->safe_mode_enabled) 2906 cmd->peer_flags &= 2907 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2908 /* inter BSS peer */ 2909 if (param->inter_bss_peer) 2910 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2911 /* Disable AMSDU for station transmit, if user configures it */ 2912 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2913 * it 2914 * if (param->amsdu_disable) Add after FW support 2915 **/ 2916 2917 /* Target asserts if node is marked HT and all MCS is set to 0. 2918 * Mark the node as non-HT if all the mcs rates are disabled through 2919 * iwpriv 2920 **/ 2921 if (param->peer_ht_rates.num_rates == 0) 2922 cmd->peer_flags &= ~WMI_PEER_HT; 2923 2924 if (param->twt_requester) 2925 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2926 2927 if (param->twt_responder) 2928 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2929 } 2930 2931 static inline void copy_peer_mac_addr_tlv( 2932 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2933 struct peer_assoc_params *param) 2934 { 2935 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2936 } 2937 2938 #ifdef WLAN_FEATURE_11BE 2939 static uint8_t *update_peer_flags_tlv_ehtinfo( 2940 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2941 struct peer_assoc_params *param, uint8_t *buf_ptr) 2942 { 2943 wmi_eht_rate_set *eht_mcs; 2944 int i; 2945 2946 cmd->peer_eht_ops = param->peer_eht_ops; 2947 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 2948 2949 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 2950 sizeof(param->peer_eht_cap_macinfo)); 2951 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 2952 sizeof(param->peer_eht_cap_phyinfo)); 2953 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 2954 sizeof(param->peer_eht_ppet)); 2955 2956 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2957 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 2958 buf_ptr += WMI_TLV_HDR_SIZE; 2959 2960 /* Loop through the EHT rate set */ 2961 for (i = 0; i < param->peer_eht_mcs_count; i++) { 2962 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 2963 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 2964 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 2965 2966 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 2967 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 2968 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 2969 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 2970 buf_ptr += sizeof(wmi_eht_rate_set); 2971 } 2972 2973 wmi_debug("nss %d ru mask 0x%x", 2974 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 2975 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 2976 wmi_debug("ppet idx %d ppet %x ", 2977 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 2978 } 2979 2980 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 2981 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2982 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 2983 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2984 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2985 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 2986 param->peer_eht_tx_mcs_set 2987 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2988 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 2989 param->peer_eht_rx_mcs_set 2990 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2991 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2992 QDF_MAC_ADDR_REF(param->peer_mac)); 2993 } 2994 2995 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 2996 cmd->peer_eht_cap_mac[0], 2997 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 2998 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 2999 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3000 3001 return buf_ptr; 3002 } 3003 #else 3004 static uint8_t *update_peer_flags_tlv_ehtinfo( 3005 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3006 struct peer_assoc_params *param, uint8_t *buf_ptr) 3007 { 3008 return buf_ptr; 3009 } 3010 #endif 3011 3012 #ifdef WLAN_FEATURE_11BE 3013 static 3014 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3015 { 3016 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3017 + WMI_TLV_HDR_SIZE); 3018 } 3019 3020 static void wmi_populate_service_11be(uint32_t *wmi_service) 3021 { 3022 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3023 } 3024 3025 #else 3026 static 3027 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3028 { 3029 return 0; 3030 } 3031 3032 static void wmi_populate_service_11be(uint32_t *wmi_service) 3033 { 3034 } 3035 3036 #endif 3037 3038 /** 3039 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3040 * @param wmi_handle : handle to WMI. 3041 * @param param : pointer to peer assoc parameter 3042 * 3043 * Return: 0 on success and -ve on failure. 3044 */ 3045 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3046 struct peer_assoc_params *param) 3047 { 3048 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3049 wmi_vht_rate_set *mcs; 3050 wmi_he_rate_set *he_mcs; 3051 wmi_buf_t buf; 3052 int32_t len; 3053 uint8_t *buf_ptr; 3054 QDF_STATUS ret; 3055 uint32_t peer_legacy_rates_align; 3056 uint32_t peer_ht_rates_align; 3057 int32_t i; 3058 3059 3060 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3061 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3062 3063 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3064 (peer_legacy_rates_align * sizeof(uint8_t)) + 3065 WMI_TLV_HDR_SIZE + 3066 (peer_ht_rates_align * sizeof(uint8_t)) + 3067 sizeof(wmi_vht_rate_set) + 3068 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3069 + WMI_TLV_HDR_SIZE) 3070 + wmi_eht_peer_assoc_params_len(param) + 3071 peer_assoc_mlo_params_size(param) + 3072 peer_assoc_t2lm_params_size(param); 3073 3074 buf = wmi_buf_alloc(wmi_handle, len); 3075 if (!buf) 3076 return QDF_STATUS_E_NOMEM; 3077 3078 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3079 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3080 WMITLV_SET_HDR(&cmd->tlv_header, 3081 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3082 WMITLV_GET_STRUCT_TLVLEN 3083 (wmi_peer_assoc_complete_cmd_fixed_param)); 3084 3085 cmd->vdev_id = param->vdev_id; 3086 3087 cmd->peer_new_assoc = param->peer_new_assoc; 3088 cmd->peer_associd = param->peer_associd; 3089 3090 copy_peer_flags_tlv(cmd, param); 3091 copy_peer_mac_addr_tlv(cmd, param); 3092 3093 cmd->peer_rate_caps = param->peer_rate_caps; 3094 cmd->peer_caps = param->peer_caps; 3095 cmd->peer_listen_intval = param->peer_listen_intval; 3096 cmd->peer_ht_caps = param->peer_ht_caps; 3097 cmd->peer_max_mpdu = param->peer_max_mpdu; 3098 cmd->peer_mpdu_density = param->peer_mpdu_density; 3099 cmd->peer_vht_caps = param->peer_vht_caps; 3100 cmd->peer_phymode = param->peer_phymode; 3101 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3102 3103 /* Update 11ax capabilities */ 3104 cmd->peer_he_cap_info = 3105 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3106 cmd->peer_he_cap_info_ext = 3107 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3108 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3109 cmd->peer_he_ops = param->peer_he_ops; 3110 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3111 sizeof(param->peer_he_cap_phyinfo)); 3112 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3113 sizeof(param->peer_ppet)); 3114 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3115 3116 /* Update peer legacy rate information */ 3117 buf_ptr += sizeof(*cmd); 3118 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3119 peer_legacy_rates_align); 3120 buf_ptr += WMI_TLV_HDR_SIZE; 3121 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3122 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3123 param->peer_legacy_rates.num_rates); 3124 3125 /* Update peer HT rate information */ 3126 buf_ptr += peer_legacy_rates_align; 3127 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3128 peer_ht_rates_align); 3129 buf_ptr += WMI_TLV_HDR_SIZE; 3130 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3131 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3132 param->peer_ht_rates.num_rates); 3133 3134 /* VHT Rates */ 3135 buf_ptr += peer_ht_rates_align; 3136 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3137 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3138 3139 cmd->auth_mode = param->akm; 3140 cmd->peer_nss = param->peer_nss; 3141 3142 /* Update bandwidth-NSS mapping */ 3143 cmd->peer_bw_rxnss_override = 0; 3144 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3145 3146 mcs = (wmi_vht_rate_set *) buf_ptr; 3147 if (param->vht_capable) { 3148 mcs->rx_max_rate = param->rx_max_rate; 3149 mcs->rx_mcs_set = param->rx_mcs_set; 3150 mcs->tx_max_rate = param->tx_max_rate; 3151 mcs->tx_mcs_set = param->tx_mcs_set; 3152 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3153 } 3154 3155 /* HE Rates */ 3156 cmd->min_data_rate = param->min_data_rate; 3157 cmd->peer_he_mcs = param->peer_he_mcs_count; 3158 buf_ptr += sizeof(wmi_vht_rate_set); 3159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3160 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3161 buf_ptr += WMI_TLV_HDR_SIZE; 3162 3163 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3164 /* Loop through the HE rate set */ 3165 for (i = 0; i < param->peer_he_mcs_count; i++) { 3166 he_mcs = (wmi_he_rate_set *) buf_ptr; 3167 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3168 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3169 3170 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3171 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3172 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3173 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3174 buf_ptr += sizeof(wmi_he_rate_set); 3175 } 3176 3177 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3178 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3179 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3180 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3181 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3182 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3183 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3184 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3185 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3186 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3187 QDF_MAC_ADDR_REF(param->peer_mac)); 3188 } 3189 3190 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3191 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3192 "nss %d phymode %d peer_mpdu_density %d " 3193 "cmd->peer_vht_caps %x " 3194 "HE cap_info %x ops %x " 3195 "HE cap_info_ext %x " 3196 "HE phy %x %x %x " 3197 "peer_bw_rxnss_override %x", 3198 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3199 cmd->peer_rate_caps, cmd->peer_caps, 3200 cmd->peer_listen_intval, cmd->peer_ht_caps, 3201 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3202 cmd->peer_mpdu_density, 3203 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3204 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3205 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3206 cmd->peer_he_cap_phy[2], 3207 cmd->peer_bw_rxnss_override); 3208 3209 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3210 3211 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3212 3213 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3214 3215 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3216 3217 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3218 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3219 WMI_PEER_ASSOC_CMDID); 3220 if (QDF_IS_STATUS_ERROR(ret)) { 3221 wmi_err("Failed to send peer assoc command ret = %d", ret); 3222 wmi_buf_free(buf); 3223 } 3224 3225 return ret; 3226 } 3227 3228 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3229 */ 3230 static inline void copy_scan_event_cntrl_flags( 3231 wmi_start_scan_cmd_fixed_param * cmd, 3232 struct scan_req_params *param) 3233 { 3234 3235 /* Scan events subscription */ 3236 if (param->scan_ev_started) 3237 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3238 if (param->scan_ev_completed) 3239 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3240 if (param->scan_ev_bss_chan) 3241 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3242 if (param->scan_ev_foreign_chan) 3243 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3244 if (param->scan_ev_dequeued) 3245 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3246 if (param->scan_ev_preempted) 3247 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3248 if (param->scan_ev_start_failed) 3249 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3250 if (param->scan_ev_restarted) 3251 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3252 if (param->scan_ev_foreign_chn_exit) 3253 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3254 if (param->scan_ev_suspended) 3255 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3256 if (param->scan_ev_resumed) 3257 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3258 3259 /** Set scan control flags */ 3260 cmd->scan_ctrl_flags = 0; 3261 if (param->scan_f_passive) 3262 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3263 if (param->scan_f_strict_passive_pch) 3264 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3265 if (param->scan_f_promisc_mode) 3266 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3267 if (param->scan_f_capture_phy_err) 3268 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3269 if (param->scan_f_half_rate) 3270 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3271 if (param->scan_f_quarter_rate) 3272 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3273 if (param->scan_f_cck_rates) 3274 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3275 if (param->scan_f_ofdm_rates) 3276 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3277 if (param->scan_f_chan_stat_evnt) 3278 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3279 if (param->scan_f_filter_prb_req) 3280 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3281 if (param->scan_f_bcast_probe) 3282 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3283 if (param->scan_f_offchan_mgmt_tx) 3284 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3285 if (param->scan_f_offchan_data_tx) 3286 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3287 if (param->scan_f_force_active_dfs_chn) 3288 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3289 if (param->scan_f_add_tpc_ie_in_probe) 3290 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3291 if (param->scan_f_add_ds_ie_in_probe) 3292 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3293 if (param->scan_f_add_spoofed_mac_in_probe) 3294 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3295 if (param->scan_f_add_rand_seq_in_probe) 3296 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3297 if (param->scan_f_en_ie_allowlist_in_probe) 3298 cmd->scan_ctrl_flags |= 3299 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3300 3301 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3302 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3303 param->adaptive_dwell_time_mode); 3304 } 3305 3306 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3307 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3308 struct scan_req_params *params) 3309 { 3310 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3311 } 3312 3313 /** 3314 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3315 * @mac: random mac addr 3316 * @mask: random mac mask 3317 * @mac_addr: wmi random mac 3318 * @mac_mask: wmi random mac mask 3319 * 3320 * Return None. 3321 */ 3322 static inline 3323 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3324 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3325 { 3326 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3327 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3328 } 3329 3330 /* 3331 * wmi_fill_vendor_oui() - fill vendor OUIs 3332 * @buf_ptr: pointer to wmi tlv buffer 3333 * @num_vendor_oui: number of vendor OUIs to be filled 3334 * @param_voui: pointer to OUI buffer 3335 * 3336 * This function populates the wmi tlv buffer when vendor specific OUIs are 3337 * present. 3338 * 3339 * Return: None 3340 */ 3341 static inline 3342 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3343 uint32_t *pvoui) 3344 { 3345 wmi_vendor_oui *voui = NULL; 3346 uint32_t i; 3347 3348 voui = (wmi_vendor_oui *)buf_ptr; 3349 3350 for (i = 0; i < num_vendor_oui; i++) { 3351 WMITLV_SET_HDR(&voui[i].tlv_header, 3352 WMITLV_TAG_STRUC_wmi_vendor_oui, 3353 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3354 voui[i].oui_type_subtype = pvoui[i]; 3355 } 3356 } 3357 3358 /* 3359 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3360 * @ie_bitmap: output pointer to ie bit map in cmd 3361 * @num_vendor_oui: output pointer to num vendor OUIs 3362 * @ie_allowlist: input parameter 3363 * 3364 * This function populates the IE allowlist attrs of scan, pno and 3365 * scan oui commands for ie_allowlist parameter. 3366 * 3367 * Return: None 3368 */ 3369 static inline 3370 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3371 uint32_t *num_vendor_oui, 3372 struct probe_req_allowlist_attr *ie_allowlist) 3373 { 3374 uint32_t i = 0; 3375 3376 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3377 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3378 3379 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3380 } 3381 3382 /** 3383 * send_scan_start_cmd_tlv() - WMI scan start function 3384 * @param wmi_handle : handle to WMI. 3385 * @param param : pointer to hold scan start cmd parameter 3386 * 3387 * Return: 0 on success and -ve on failure. 3388 */ 3389 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3390 struct scan_req_params *params) 3391 { 3392 int32_t ret = 0; 3393 int32_t i; 3394 wmi_buf_t wmi_buf; 3395 wmi_start_scan_cmd_fixed_param *cmd; 3396 uint8_t *buf_ptr; 3397 uint32_t *tmp_ptr; 3398 wmi_ssid *ssid = NULL; 3399 wmi_mac_addr *bssid; 3400 size_t len = sizeof(*cmd); 3401 uint16_t extraie_len_with_pad = 0; 3402 uint8_t phymode_roundup = 0; 3403 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3404 wmi_hint_freq_short_ssid *s_ssid = NULL; 3405 wmi_hint_freq_bssid *hint_bssid = NULL; 3406 3407 /* Length TLV placeholder for array of uint32_t */ 3408 len += WMI_TLV_HDR_SIZE; 3409 /* calculate the length of buffer required */ 3410 if (params->chan_list.num_chan) 3411 len += params->chan_list.num_chan * sizeof(uint32_t); 3412 3413 /* Length TLV placeholder for array of wmi_ssid structures */ 3414 len += WMI_TLV_HDR_SIZE; 3415 if (params->num_ssids) 3416 len += params->num_ssids * sizeof(wmi_ssid); 3417 3418 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3419 len += WMI_TLV_HDR_SIZE; 3420 if (params->num_bssid) 3421 len += sizeof(wmi_mac_addr) * params->num_bssid; 3422 3423 /* Length TLV placeholder for array of bytes */ 3424 len += WMI_TLV_HDR_SIZE; 3425 if (params->extraie.len) 3426 extraie_len_with_pad = 3427 roundup(params->extraie.len, sizeof(uint32_t)); 3428 len += extraie_len_with_pad; 3429 3430 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3431 if (ie_allowlist->num_vendor_oui) 3432 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3433 3434 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3435 if (params->scan_f_wide_band) 3436 phymode_roundup = 3437 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3438 sizeof(uint32_t)); 3439 len += phymode_roundup; 3440 3441 len += WMI_TLV_HDR_SIZE; 3442 if (params->num_hint_bssid) 3443 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3444 3445 len += WMI_TLV_HDR_SIZE; 3446 if (params->num_hint_s_ssid) 3447 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3448 3449 /* Allocate the memory */ 3450 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3451 if (!wmi_buf) 3452 return QDF_STATUS_E_FAILURE; 3453 3454 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3455 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3456 WMITLV_SET_HDR(&cmd->tlv_header, 3457 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3458 WMITLV_GET_STRUCT_TLVLEN 3459 (wmi_start_scan_cmd_fixed_param)); 3460 3461 cmd->scan_id = params->scan_id; 3462 cmd->scan_req_id = params->scan_req_id; 3463 cmd->vdev_id = params->vdev_id; 3464 cmd->scan_priority = params->scan_priority; 3465 3466 copy_scan_event_cntrl_flags(cmd, params); 3467 3468 cmd->dwell_time_active = params->dwell_time_active; 3469 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3470 cmd->dwell_time_passive = params->dwell_time_passive; 3471 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3472 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3473 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3474 cmd->scan_start_offset = params->scan_offset_time; 3475 cmd->min_rest_time = params->min_rest_time; 3476 cmd->max_rest_time = params->max_rest_time; 3477 cmd->repeat_probe_time = params->repeat_probe_time; 3478 cmd->probe_spacing_time = params->probe_spacing_time; 3479 cmd->idle_time = params->idle_time; 3480 cmd->max_scan_time = params->max_scan_time; 3481 cmd->probe_delay = params->probe_delay; 3482 cmd->burst_duration = params->burst_duration; 3483 cmd->num_chan = params->chan_list.num_chan; 3484 cmd->num_bssid = params->num_bssid; 3485 cmd->num_ssids = params->num_ssids; 3486 cmd->ie_len = params->extraie.len; 3487 cmd->n_probes = params->n_probes; 3488 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3489 3490 if (params->scan_random.randomize) 3491 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3492 params->scan_random.mac_mask, 3493 &cmd->mac_addr, 3494 &cmd->mac_mask); 3495 3496 if (ie_allowlist->allow_list) 3497 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 3498 &cmd->num_vendor_oui, 3499 ie_allowlist); 3500 3501 buf_ptr += sizeof(*cmd); 3502 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3503 for (i = 0; i < params->chan_list.num_chan; ++i) { 3504 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 3505 params->chan_list.chan[i].freq); 3506 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 3507 params->chan_list.chan[i].flags); 3508 } 3509 3510 WMITLV_SET_HDR(buf_ptr, 3511 WMITLV_TAG_ARRAY_UINT32, 3512 (params->chan_list.num_chan * sizeof(uint32_t))); 3513 buf_ptr += WMI_TLV_HDR_SIZE + 3514 (params->chan_list.num_chan * sizeof(uint32_t)); 3515 3516 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3517 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 3518 goto error; 3519 } 3520 3521 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3522 (params->num_ssids * sizeof(wmi_ssid))); 3523 3524 if (params->num_ssids) { 3525 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3526 for (i = 0; i < params->num_ssids; ++i) { 3527 ssid->ssid_len = params->ssid[i].length; 3528 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3529 params->ssid[i].length); 3530 ssid++; 3531 } 3532 } 3533 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3534 3535 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3536 (params->num_bssid * sizeof(wmi_mac_addr))); 3537 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3538 3539 if (params->num_bssid) { 3540 for (i = 0; i < params->num_bssid; ++i) { 3541 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3542 ¶ms->bssid_list[i].bytes[0], bssid); 3543 bssid++; 3544 } 3545 } 3546 3547 buf_ptr += WMI_TLV_HDR_SIZE + 3548 (params->num_bssid * sizeof(wmi_mac_addr)); 3549 3550 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3551 if (params->extraie.len) 3552 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3553 params); 3554 3555 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3556 3557 /* probe req ie allowlisting */ 3558 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3559 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3560 3561 buf_ptr += WMI_TLV_HDR_SIZE; 3562 3563 if (cmd->num_vendor_oui) { 3564 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3565 ie_allowlist->voui); 3566 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3567 } 3568 3569 /* Add phy mode TLV if it's a wide band scan */ 3570 if (params->scan_f_wide_band) { 3571 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3572 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3573 for (i = 0; i < params->chan_list.num_chan; ++i) 3574 buf_ptr[i] = 3575 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3576 buf_ptr += phymode_roundup; 3577 } else { 3578 /* Add ZERO legth phy mode TLV */ 3579 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3580 buf_ptr += WMI_TLV_HDR_SIZE; 3581 } 3582 3583 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3584 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3585 if (params->num_hint_s_ssid) { 3586 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3587 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3588 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3589 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3590 s_ssid++; 3591 } 3592 } 3593 buf_ptr += WMI_TLV_HDR_SIZE + 3594 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3595 3596 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3597 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3598 if (params->num_hint_bssid) { 3599 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3600 for (i = 0; i < params->num_hint_bssid; ++i) { 3601 hint_bssid->freq_flags = 3602 params->hint_bssid[i].freq_flags; 3603 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3604 &hint_bssid->bssid); 3605 hint_bssid++; 3606 } 3607 } 3608 3609 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3610 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3611 len, WMI_START_SCAN_CMDID); 3612 if (ret) { 3613 wmi_err("Failed to start scan: %d", ret); 3614 wmi_buf_free(wmi_buf); 3615 } 3616 return ret; 3617 error: 3618 wmi_buf_free(wmi_buf); 3619 return QDF_STATUS_E_FAILURE; 3620 } 3621 3622 /** 3623 * send_scan_stop_cmd_tlv() - WMI scan start function 3624 * @param wmi_handle : handle to WMI. 3625 * @param param : pointer to hold scan cancel cmd parameter 3626 * 3627 * Return: 0 on success and -ve on failure. 3628 */ 3629 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3630 struct scan_cancel_param *param) 3631 { 3632 wmi_stop_scan_cmd_fixed_param *cmd; 3633 int ret; 3634 int len = sizeof(*cmd); 3635 wmi_buf_t wmi_buf; 3636 3637 /* Allocate the memory */ 3638 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3639 if (!wmi_buf) { 3640 ret = QDF_STATUS_E_NOMEM; 3641 goto error; 3642 } 3643 3644 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3645 WMITLV_SET_HDR(&cmd->tlv_header, 3646 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3647 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3648 cmd->vdev_id = param->vdev_id; 3649 cmd->requestor = param->requester; 3650 cmd->scan_id = param->scan_id; 3651 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3652 wmi_handle, 3653 param->pdev_id); 3654 /* stop the scan with the corresponding scan_id */ 3655 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3656 /* Cancelling all scans */ 3657 cmd->req_type = WMI_SCAN_STOP_ALL; 3658 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3659 /* Cancelling VAP scans */ 3660 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3661 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3662 /* Cancelling specific scan */ 3663 cmd->req_type = WMI_SCAN_STOP_ONE; 3664 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 3665 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 3666 } else { 3667 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 3668 wmi_buf_free(wmi_buf); 3669 return QDF_STATUS_E_INVAL; 3670 } 3671 3672 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3673 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3674 len, WMI_STOP_SCAN_CMDID); 3675 if (ret) { 3676 wmi_err("Failed to send stop scan: %d", ret); 3677 wmi_buf_free(wmi_buf); 3678 } 3679 3680 error: 3681 return ret; 3682 } 3683 3684 #define WMI_MAX_CHAN_INFO_LOG 192 3685 3686 /** 3687 * wmi_scan_chanlist_dump() - Dump scan channel list info 3688 * @scan_chan_list: scan channel list 3689 * 3690 * Return: void 3691 */ 3692 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3693 { 3694 uint32_t i; 3695 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3696 uint32_t len = 0; 3697 struct channel_param *chan; 3698 int ret; 3699 3700 wmi_debug("Total chan %d", scan_chan_list->nallchans); 3701 for (i = 0; i < scan_chan_list->nallchans; i++) { 3702 chan = &scan_chan_list->ch_param[i]; 3703 ret = qdf_scnprintf(info + len, sizeof(info) - len, 3704 " %d[%d][%d][%d]", chan->mhz, 3705 chan->maxregpower, 3706 chan->dfs_set, chan->nan_disabled); 3707 if (ret <= 0) 3708 break; 3709 len += ret; 3710 if (len >= (sizeof(info) - 20)) { 3711 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 3712 info); 3713 len = 0; 3714 } 3715 } 3716 if (len) 3717 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3718 } 3719 3720 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3721 struct scan_chan_list_params *chan_list) 3722 { 3723 wmi_buf_t buf; 3724 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3725 wmi_scan_chan_list_cmd_fixed_param *cmd; 3726 int i; 3727 uint8_t *buf_ptr; 3728 wmi_channel *chan_info; 3729 struct channel_param *tchan_info; 3730 uint16_t len; 3731 uint16_t num_send_chans, num_sends = 0; 3732 3733 wmi_scan_chanlist_dump(chan_list); 3734 tchan_info = &chan_list->ch_param[0]; 3735 while (chan_list->nallchans) { 3736 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3737 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3738 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3739 else 3740 num_send_chans = chan_list->nallchans; 3741 3742 chan_list->nallchans -= num_send_chans; 3743 len += sizeof(wmi_channel) * num_send_chans; 3744 buf = wmi_buf_alloc(wmi_handle, len); 3745 if (!buf) { 3746 qdf_status = QDF_STATUS_E_NOMEM; 3747 goto end; 3748 } 3749 3750 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3751 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3752 WMITLV_SET_HDR(&cmd->tlv_header, 3753 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3754 WMITLV_GET_STRUCT_TLVLEN 3755 (wmi_scan_chan_list_cmd_fixed_param)); 3756 3757 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 3758 3759 if (num_sends) 3760 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3761 3762 if (chan_list->max_bw_support_present) 3763 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3764 3765 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3766 wmi_handle, 3767 chan_list->pdev_id); 3768 3769 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3770 3771 cmd->num_scan_chans = num_send_chans; 3772 WMITLV_SET_HDR((buf_ptr + 3773 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3774 WMITLV_TAG_ARRAY_STRUC, 3775 sizeof(wmi_channel) * num_send_chans); 3776 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3777 WMI_TLV_HDR_SIZE); 3778 3779 for (i = 0; i < num_send_chans; ++i) { 3780 WMITLV_SET_HDR(&chan_info->tlv_header, 3781 WMITLV_TAG_STRUC_wmi_channel, 3782 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3783 chan_info->mhz = tchan_info->mhz; 3784 chan_info->band_center_freq1 = 3785 tchan_info->cfreq1; 3786 chan_info->band_center_freq2 = 3787 tchan_info->cfreq2; 3788 3789 if (tchan_info->is_chan_passive) 3790 WMI_SET_CHANNEL_FLAG(chan_info, 3791 WMI_CHAN_FLAG_PASSIVE); 3792 if (tchan_info->dfs_set) 3793 WMI_SET_CHANNEL_FLAG(chan_info, 3794 WMI_CHAN_FLAG_DFS); 3795 3796 if (tchan_info->dfs_set_cfreq2) 3797 WMI_SET_CHANNEL_FLAG(chan_info, 3798 WMI_CHAN_FLAG_DFS_CFREQ2); 3799 3800 if (tchan_info->allow_he) 3801 WMI_SET_CHANNEL_FLAG(chan_info, 3802 WMI_CHAN_FLAG_ALLOW_HE); 3803 3804 if (tchan_info->allow_eht) 3805 WMI_SET_CHANNEL_FLAG(chan_info, 3806 WMI_CHAN_FLAG_ALLOW_EHT); 3807 3808 if (tchan_info->allow_vht) 3809 WMI_SET_CHANNEL_FLAG(chan_info, 3810 WMI_CHAN_FLAG_ALLOW_VHT); 3811 3812 if (tchan_info->allow_ht) 3813 WMI_SET_CHANNEL_FLAG(chan_info, 3814 WMI_CHAN_FLAG_ALLOW_HT); 3815 WMI_SET_CHANNEL_MODE(chan_info, 3816 tchan_info->phy_mode); 3817 3818 if (tchan_info->half_rate) 3819 WMI_SET_CHANNEL_FLAG(chan_info, 3820 WMI_CHAN_FLAG_HALF_RATE); 3821 3822 if (tchan_info->quarter_rate) 3823 WMI_SET_CHANNEL_FLAG(chan_info, 3824 WMI_CHAN_FLAG_QUARTER_RATE); 3825 3826 if (tchan_info->psc_channel) 3827 WMI_SET_CHANNEL_FLAG(chan_info, 3828 WMI_CHAN_FLAG_PSC); 3829 3830 if (tchan_info->nan_disabled) 3831 WMI_SET_CHANNEL_FLAG(chan_info, 3832 WMI_CHAN_FLAG_NAN_DISABLED); 3833 3834 /* also fill in power information */ 3835 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3836 tchan_info->minpower); 3837 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3838 tchan_info->maxpower); 3839 WMI_SET_CHANNEL_REG_POWER(chan_info, 3840 tchan_info->maxregpower); 3841 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3842 tchan_info->antennamax); 3843 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3844 tchan_info->reg_class_id); 3845 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3846 tchan_info->maxregpower); 3847 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3848 tchan_info->max_bw_supported); 3849 3850 tchan_info++; 3851 chan_info++; 3852 } 3853 3854 qdf_status = wmi_unified_cmd_send( 3855 wmi_handle, 3856 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3857 3858 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3859 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3860 wmi_buf_free(buf); 3861 goto end; 3862 } 3863 num_sends++; 3864 } 3865 3866 end: 3867 return qdf_status; 3868 } 3869 3870 /** 3871 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3872 * 3873 * @bufp: Pointer to buffer 3874 * @param: Pointer to tx param 3875 * 3876 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3877 */ 3878 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3879 struct tx_send_params param) 3880 { 3881 wmi_tx_send_params *tx_param; 3882 QDF_STATUS status = QDF_STATUS_SUCCESS; 3883 3884 if (!bufp) { 3885 status = QDF_STATUS_E_FAILURE; 3886 return status; 3887 } 3888 tx_param = (wmi_tx_send_params *)bufp; 3889 WMITLV_SET_HDR(&tx_param->tlv_header, 3890 WMITLV_TAG_STRUC_wmi_tx_send_params, 3891 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3892 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3893 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3894 param.mcs_mask); 3895 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3896 param.nss_mask); 3897 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3898 param.retry_limit); 3899 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3900 param.chain_mask); 3901 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3902 param.bw_mask); 3903 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3904 param.preamble_type); 3905 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3906 param.frame_type); 3907 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3908 param.cfr_enable); 3909 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 3910 param.en_beamforming); 3911 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 3912 param.retry_limit_ext); 3913 3914 return status; 3915 } 3916 3917 #ifdef CONFIG_HL_SUPPORT 3918 /** 3919 * send_mgmt_cmd_tlv() - WMI scan start function 3920 * @wmi_handle : handle to WMI. 3921 * @param : pointer to hold mgmt cmd parameter 3922 * 3923 * Return: 0 on success and -ve on failure. 3924 */ 3925 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3926 struct wmi_mgmt_params *param) 3927 { 3928 wmi_buf_t buf; 3929 uint8_t *bufp; 3930 int32_t cmd_len; 3931 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3932 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3933 mgmt_tx_dl_frm_len; 3934 3935 if (param->frm_len > mgmt_tx_dl_frm_len) { 3936 wmi_err("mgmt frame len %u exceeds %u", 3937 param->frm_len, mgmt_tx_dl_frm_len); 3938 return QDF_STATUS_E_INVAL; 3939 } 3940 3941 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3942 WMI_TLV_HDR_SIZE + 3943 roundup(bufp_len, sizeof(uint32_t)); 3944 3945 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3946 if (!buf) 3947 return QDF_STATUS_E_NOMEM; 3948 3949 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3950 bufp = (uint8_t *) cmd; 3951 WMITLV_SET_HDR(&cmd->tlv_header, 3952 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3953 WMITLV_GET_STRUCT_TLVLEN 3954 (wmi_mgmt_tx_send_cmd_fixed_param)); 3955 3956 cmd->vdev_id = param->vdev_id; 3957 3958 cmd->desc_id = param->desc_id; 3959 cmd->chanfreq = param->chanfreq; 3960 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3961 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3962 sizeof(uint32_t))); 3963 bufp += WMI_TLV_HDR_SIZE; 3964 qdf_mem_copy(bufp, param->pdata, bufp_len); 3965 3966 cmd->frame_len = param->frm_len; 3967 cmd->buf_len = bufp_len; 3968 cmd->tx_params_valid = param->tx_params_valid; 3969 cmd->tx_flags = param->tx_flags; 3970 cmd->peer_rssi = param->peer_rssi; 3971 3972 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3973 bufp, cmd->vdev_id, cmd->chanfreq); 3974 3975 bufp += roundup(bufp_len, sizeof(uint32_t)); 3976 if (param->tx_params_valid) { 3977 if (populate_tx_send_params(bufp, param->tx_param) != 3978 QDF_STATUS_SUCCESS) { 3979 wmi_err("Populate TX send params failed"); 3980 goto free_buf; 3981 } 3982 cmd_len += sizeof(wmi_tx_send_params); 3983 } 3984 3985 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3986 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3987 WMI_MGMT_TX_SEND_CMDID)) { 3988 wmi_err("Failed to send mgmt Tx"); 3989 goto free_buf; 3990 } 3991 return QDF_STATUS_SUCCESS; 3992 3993 free_buf: 3994 wmi_buf_free(buf); 3995 return QDF_STATUS_E_FAILURE; 3996 } 3997 #else 3998 /** 3999 * send_mgmt_cmd_tlv() - WMI scan start function 4000 * @wmi_handle : handle to WMI. 4001 * @param : pointer to hold mgmt cmd parameter 4002 * 4003 * Return: 0 on success and -ve on failure. 4004 */ 4005 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4006 struct wmi_mgmt_params *param) 4007 { 4008 wmi_buf_t buf; 4009 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4010 int32_t cmd_len; 4011 uint64_t dma_addr; 4012 void *qdf_ctx = param->qdf_ctx; 4013 uint8_t *bufp; 4014 QDF_STATUS status = QDF_STATUS_SUCCESS; 4015 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4016 mgmt_tx_dl_frm_len; 4017 4018 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4019 WMI_TLV_HDR_SIZE + 4020 roundup(bufp_len, sizeof(uint32_t)); 4021 4022 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4023 if (!buf) 4024 return QDF_STATUS_E_NOMEM; 4025 4026 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4027 bufp = (uint8_t *) cmd; 4028 WMITLV_SET_HDR(&cmd->tlv_header, 4029 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4030 WMITLV_GET_STRUCT_TLVLEN 4031 (wmi_mgmt_tx_send_cmd_fixed_param)); 4032 4033 cmd->vdev_id = param->vdev_id; 4034 4035 cmd->desc_id = param->desc_id; 4036 cmd->chanfreq = param->chanfreq; 4037 cmd->peer_rssi = param->peer_rssi; 4038 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4039 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4040 sizeof(uint32_t))); 4041 bufp += WMI_TLV_HDR_SIZE; 4042 4043 /* for big endian host, copy engine byte_swap is enabled 4044 * But the frame content is in network byte order 4045 * Need to byte swap the frame content - so when copy engine 4046 * does byte_swap - target gets frame content in the correct order 4047 */ 4048 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4049 4050 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4051 QDF_DMA_TO_DEVICE); 4052 if (status != QDF_STATUS_SUCCESS) { 4053 wmi_err("wmi buf map failed"); 4054 goto free_buf; 4055 } 4056 4057 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4058 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4059 #if defined(HTT_PADDR64) 4060 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4061 #endif 4062 cmd->frame_len = param->frm_len; 4063 cmd->buf_len = bufp_len; 4064 cmd->tx_params_valid = param->tx_params_valid; 4065 cmd->tx_flags = param->tx_flags; 4066 4067 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4068 bufp, cmd->vdev_id, cmd->chanfreq); 4069 4070 bufp += roundup(bufp_len, sizeof(uint32_t)); 4071 if (param->tx_params_valid) { 4072 status = populate_tx_send_params(bufp, param->tx_param); 4073 if (status != QDF_STATUS_SUCCESS) { 4074 wmi_err("Populate TX send params failed"); 4075 goto unmap_tx_frame; 4076 } 4077 cmd_len += sizeof(wmi_tx_send_params); 4078 } 4079 4080 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4081 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4082 WMI_MGMT_TX_SEND_CMDID)) { 4083 wmi_err("Failed to send mgmt Tx"); 4084 goto unmap_tx_frame; 4085 } 4086 return QDF_STATUS_SUCCESS; 4087 4088 unmap_tx_frame: 4089 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4090 QDF_DMA_TO_DEVICE); 4091 free_buf: 4092 wmi_buf_free(buf); 4093 return QDF_STATUS_E_FAILURE; 4094 } 4095 #endif /* CONFIG_HL_SUPPORT */ 4096 4097 /** 4098 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 4099 * @wmi_handle : handle to WMI. 4100 * @param : pointer to offchan data tx cmd parameter 4101 * 4102 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4103 */ 4104 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4105 struct wmi_offchan_data_tx_params *param) 4106 { 4107 wmi_buf_t buf; 4108 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4109 int32_t cmd_len; 4110 uint64_t dma_addr; 4111 void *qdf_ctx = param->qdf_ctx; 4112 uint8_t *bufp; 4113 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4114 param->frm_len : mgmt_tx_dl_frm_len; 4115 QDF_STATUS status = QDF_STATUS_SUCCESS; 4116 4117 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4118 WMI_TLV_HDR_SIZE + 4119 roundup(bufp_len, sizeof(uint32_t)); 4120 4121 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4122 if (!buf) 4123 return QDF_STATUS_E_NOMEM; 4124 4125 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4126 bufp = (uint8_t *) cmd; 4127 WMITLV_SET_HDR(&cmd->tlv_header, 4128 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4129 WMITLV_GET_STRUCT_TLVLEN 4130 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4131 4132 cmd->vdev_id = param->vdev_id; 4133 4134 cmd->desc_id = param->desc_id; 4135 cmd->chanfreq = param->chanfreq; 4136 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4137 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4138 sizeof(uint32_t))); 4139 bufp += WMI_TLV_HDR_SIZE; 4140 qdf_mem_copy(bufp, param->pdata, bufp_len); 4141 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4142 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4143 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4144 #if defined(HTT_PADDR64) 4145 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4146 #endif 4147 cmd->frame_len = param->frm_len; 4148 cmd->buf_len = bufp_len; 4149 cmd->tx_params_valid = param->tx_params_valid; 4150 4151 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4152 bufp, cmd->vdev_id, cmd->chanfreq); 4153 4154 bufp += roundup(bufp_len, sizeof(uint32_t)); 4155 if (param->tx_params_valid) { 4156 status = populate_tx_send_params(bufp, param->tx_param); 4157 if (status != QDF_STATUS_SUCCESS) { 4158 wmi_err("Populate TX send params failed"); 4159 goto err1; 4160 } 4161 cmd_len += sizeof(wmi_tx_send_params); 4162 } 4163 4164 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4165 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4166 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4167 wmi_err("Failed to offchan data Tx"); 4168 goto err1; 4169 } 4170 4171 return QDF_STATUS_SUCCESS; 4172 4173 err1: 4174 wmi_buf_free(buf); 4175 return QDF_STATUS_E_FAILURE; 4176 } 4177 4178 /** 4179 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4180 * @wmi_handle: wmi handle 4181 * @param_value: parameter value 4182 * 4183 * Return: QDF_STATUS_SUCCESS for success or error code 4184 */ 4185 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4186 uint32_t param_value) 4187 { 4188 QDF_STATUS ret; 4189 wmi_modem_power_state_cmd_param *cmd; 4190 wmi_buf_t buf; 4191 uint16_t len = sizeof(*cmd); 4192 4193 buf = wmi_buf_alloc(wmi_handle, len); 4194 if (!buf) 4195 return QDF_STATUS_E_NOMEM; 4196 4197 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4198 WMITLV_SET_HDR(&cmd->tlv_header, 4199 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4200 WMITLV_GET_STRUCT_TLVLEN 4201 (wmi_modem_power_state_cmd_param)); 4202 cmd->modem_power_state = param_value; 4203 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4204 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4205 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4206 WMI_MODEM_POWER_STATE_CMDID); 4207 if (QDF_IS_STATUS_ERROR(ret)) { 4208 wmi_err("Failed to send notify cmd ret = %d", ret); 4209 wmi_buf_free(buf); 4210 } 4211 4212 return ret; 4213 } 4214 4215 /** 4216 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4217 * @wmi_handle: wmi handle 4218 * @vdev_id: vdev id 4219 * @val: value 4220 * 4221 * Return: QDF_STATUS_SUCCESS for success or error code. 4222 */ 4223 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4224 uint32_t vdev_id, uint8_t val) 4225 { 4226 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4227 wmi_buf_t buf; 4228 int32_t len = sizeof(*cmd); 4229 4230 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4231 4232 buf = wmi_buf_alloc(wmi_handle, len); 4233 if (!buf) 4234 return QDF_STATUS_E_NOMEM; 4235 4236 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4237 WMITLV_SET_HDR(&cmd->tlv_header, 4238 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4239 WMITLV_GET_STRUCT_TLVLEN 4240 (wmi_sta_powersave_mode_cmd_fixed_param)); 4241 cmd->vdev_id = vdev_id; 4242 if (val) 4243 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4244 else 4245 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4246 4247 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4248 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4249 WMI_STA_POWERSAVE_MODE_CMDID)) { 4250 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4251 vdev_id, val); 4252 wmi_buf_free(buf); 4253 return QDF_STATUS_E_FAILURE; 4254 } 4255 return QDF_STATUS_SUCCESS; 4256 } 4257 4258 /** 4259 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4260 * @wmi_handle: wmi handle 4261 * @vdev_id: vdev id 4262 * 4263 * Return: QDF_STATUS_SUCCESS for success or error code. 4264 */ 4265 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4266 uint8_t val) 4267 { 4268 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4269 wmi_buf_t buf; 4270 size_t len = sizeof(*cmd); 4271 4272 buf = wmi_buf_alloc(wmi_handle, len); 4273 if (!buf) 4274 return QDF_STATUS_E_NOMEM; 4275 4276 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4277 WMITLV_SET_HDR(&cmd->tlv_header, 4278 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4279 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4280 4281 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4282 WMI_IDLE_TRIGGER_MONITOR_OFF); 4283 4284 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4285 4286 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4287 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4288 wmi_buf_free(buf); 4289 return QDF_STATUS_E_FAILURE; 4290 } 4291 return QDF_STATUS_SUCCESS; 4292 } 4293 4294 /** 4295 * send_set_mimops_cmd_tlv() - set MIMO powersave 4296 * @wmi_handle: wmi handle 4297 * @vdev_id: vdev id 4298 * @value: value 4299 * 4300 * Return: QDF_STATUS_SUCCESS for success or error code. 4301 */ 4302 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4303 uint8_t vdev_id, int value) 4304 { 4305 QDF_STATUS ret; 4306 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4307 wmi_buf_t buf; 4308 uint16_t len = sizeof(*cmd); 4309 4310 buf = wmi_buf_alloc(wmi_handle, len); 4311 if (!buf) 4312 return QDF_STATUS_E_NOMEM; 4313 4314 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4315 WMITLV_SET_HDR(&cmd->tlv_header, 4316 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4317 WMITLV_GET_STRUCT_TLVLEN 4318 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4319 4320 cmd->vdev_id = vdev_id; 4321 4322 /* WMI_SMPS_FORCED_MODE values do not directly map 4323 * to SM power save values defined in the specification. 4324 * Make sure to send the right mapping. 4325 */ 4326 switch (value) { 4327 case 0: 4328 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4329 break; 4330 case 1: 4331 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4332 break; 4333 case 2: 4334 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4335 break; 4336 case 3: 4337 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4338 break; 4339 default: 4340 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4341 wmi_buf_free(buf); 4342 return QDF_STATUS_E_FAILURE; 4343 } 4344 4345 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4346 4347 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4348 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4349 WMI_STA_SMPS_FORCE_MODE_CMDID); 4350 if (QDF_IS_STATUS_ERROR(ret)) { 4351 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4352 wmi_buf_free(buf); 4353 } 4354 4355 return ret; 4356 } 4357 4358 /** 4359 * send_set_smps_params_cmd_tlv() - set smps params 4360 * @wmi_handle: wmi handle 4361 * @vdev_id: vdev id 4362 * @value: value 4363 * 4364 * Return: QDF_STATUS_SUCCESS for success or error code. 4365 */ 4366 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4367 int value) 4368 { 4369 QDF_STATUS ret; 4370 wmi_sta_smps_param_cmd_fixed_param *cmd; 4371 wmi_buf_t buf; 4372 uint16_t len = sizeof(*cmd); 4373 4374 buf = wmi_buf_alloc(wmi_handle, len); 4375 if (!buf) 4376 return QDF_STATUS_E_NOMEM; 4377 4378 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4379 WMITLV_SET_HDR(&cmd->tlv_header, 4380 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4381 WMITLV_GET_STRUCT_TLVLEN 4382 (wmi_sta_smps_param_cmd_fixed_param)); 4383 4384 cmd->vdev_id = vdev_id; 4385 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4386 cmd->param = 4387 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4388 4389 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4390 cmd->param); 4391 4392 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4393 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4394 WMI_STA_SMPS_PARAM_CMDID); 4395 if (QDF_IS_STATUS_ERROR(ret)) { 4396 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4397 wmi_buf_free(buf); 4398 } 4399 4400 return ret; 4401 } 4402 4403 /** 4404 * send_get_temperature_cmd_tlv() - get pdev temperature req 4405 * @wmi_handle: wmi handle 4406 * 4407 * Return: QDF_STATUS_SUCCESS for success or error code. 4408 */ 4409 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4410 { 4411 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4412 wmi_buf_t wmi_buf; 4413 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4414 uint8_t *buf_ptr; 4415 4416 if (!wmi_handle) { 4417 wmi_err("WMI is closed, can not issue cmd"); 4418 return QDF_STATUS_E_INVAL; 4419 } 4420 4421 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4422 if (!wmi_buf) 4423 return QDF_STATUS_E_NOMEM; 4424 4425 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4426 4427 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4428 WMITLV_SET_HDR(&cmd->tlv_header, 4429 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4430 WMITLV_GET_STRUCT_TLVLEN 4431 (wmi_pdev_get_temperature_cmd_fixed_param)); 4432 4433 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4434 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4435 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4436 wmi_err("Failed to send get temperature command"); 4437 wmi_buf_free(wmi_buf); 4438 return QDF_STATUS_E_FAILURE; 4439 } 4440 4441 return QDF_STATUS_SUCCESS; 4442 } 4443 4444 /** 4445 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4446 * @wmi_handle: wmi handle 4447 * @vdevid: vdev id 4448 * @peer_addr: peer mac address 4449 * @auto_triggerparam: auto trigger parameters 4450 * @num_ac: number of access category 4451 * 4452 * This function sets the trigger 4453 * uapsd params such as service interval, delay interval 4454 * and suspend interval which will be used by the firmware 4455 * to send trigger frames periodically when there is no 4456 * traffic on the transmit side. 4457 * 4458 * Return: QDF_STATUS_SUCCESS for success or error code. 4459 */ 4460 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4461 struct sta_uapsd_trig_params *param) 4462 { 4463 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4464 QDF_STATUS ret; 4465 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4466 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4467 uint32_t i; 4468 wmi_buf_t buf; 4469 uint8_t *buf_ptr; 4470 struct sta_uapsd_params *uapsd_param; 4471 wmi_sta_uapsd_auto_trig_param *trig_param; 4472 4473 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4474 if (!buf) 4475 return QDF_STATUS_E_NOMEM; 4476 4477 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4478 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 4479 WMITLV_SET_HDR(&cmd->tlv_header, 4480 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 4481 WMITLV_GET_STRUCT_TLVLEN 4482 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 4483 cmd->vdev_id = param->vdevid; 4484 cmd->num_ac = param->num_ac; 4485 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 4486 4487 /* TLV indicating array of structures to follow */ 4488 buf_ptr += sizeof(*cmd); 4489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 4490 4491 buf_ptr += WMI_TLV_HDR_SIZE; 4492 4493 /* 4494 * Update tag and length for uapsd auto trigger params (this will take 4495 * care of updating tag and length if it is not pre-filled by caller). 4496 */ 4497 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 4498 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 4499 for (i = 0; i < param->num_ac; i++) { 4500 WMITLV_SET_HDR((buf_ptr + 4501 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 4502 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 4503 WMITLV_GET_STRUCT_TLVLEN 4504 (wmi_sta_uapsd_auto_trig_param)); 4505 trig_param->wmm_ac = uapsd_param->wmm_ac; 4506 trig_param->user_priority = uapsd_param->user_priority; 4507 trig_param->service_interval = uapsd_param->service_interval; 4508 trig_param->suspend_interval = uapsd_param->suspend_interval; 4509 trig_param->delay_interval = uapsd_param->delay_interval; 4510 trig_param++; 4511 uapsd_param++; 4512 } 4513 4514 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4515 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4516 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4517 if (QDF_IS_STATUS_ERROR(ret)) { 4518 wmi_err("Failed to send set uapsd param ret = %d", ret); 4519 wmi_buf_free(buf); 4520 } 4521 4522 return ret; 4523 } 4524 4525 /** 4526 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4527 * @wmi_handle: Pointer to wmi handle 4528 * @thermal_info: Thermal command information 4529 * 4530 * This function sends the thermal management command 4531 * to the firmware 4532 * 4533 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4534 */ 4535 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4536 struct thermal_cmd_params *thermal_info) 4537 { 4538 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4539 wmi_buf_t buf = NULL; 4540 QDF_STATUS status; 4541 uint32_t len = 0; 4542 uint8_t action; 4543 4544 switch (thermal_info->thermal_action) { 4545 case THERMAL_MGMT_ACTION_DEFAULT: 4546 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 4547 break; 4548 4549 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 4550 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 4551 break; 4552 4553 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 4554 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 4555 break; 4556 4557 case THERMAL_MGMT_ACTION_CHAINSCALING: 4558 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 4559 break; 4560 4561 default: 4562 wmi_err("Invalid thermal_action code %d", 4563 thermal_info->thermal_action); 4564 return QDF_STATUS_E_FAILURE; 4565 } 4566 4567 len = sizeof(*cmd); 4568 4569 buf = wmi_buf_alloc(wmi_handle, len); 4570 if (!buf) 4571 return QDF_STATUS_E_FAILURE; 4572 4573 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4574 4575 WMITLV_SET_HDR(&cmd->tlv_header, 4576 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4577 WMITLV_GET_STRUCT_TLVLEN 4578 (wmi_thermal_mgmt_cmd_fixed_param)); 4579 4580 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4581 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4582 cmd->enable = thermal_info->thermal_enable; 4583 cmd->action = action; 4584 4585 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 4586 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 4587 cmd->enable, cmd->action); 4588 4589 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4590 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4591 WMI_THERMAL_MGMT_CMDID); 4592 if (QDF_IS_STATUS_ERROR(status)) { 4593 wmi_buf_free(buf); 4594 wmi_err("Failed to send thermal mgmt command"); 4595 } 4596 4597 return status; 4598 } 4599 4600 /** 4601 * send_lro_config_cmd_tlv() - process the LRO config command 4602 * @wmi_handle: Pointer to WMI handle 4603 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4604 * 4605 * This function sends down the LRO configuration parameters to 4606 * the firmware to enable LRO, sets the TCP flags and sets the 4607 * seed values for the toeplitz hash generation 4608 * 4609 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4610 */ 4611 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4612 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4613 { 4614 wmi_lro_info_cmd_fixed_param *cmd; 4615 wmi_buf_t buf; 4616 QDF_STATUS status; 4617 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4618 4619 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4620 if (!buf) 4621 return QDF_STATUS_E_FAILURE; 4622 4623 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4624 4625 WMITLV_SET_HDR(&cmd->tlv_header, 4626 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4627 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4628 4629 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4630 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4631 wmi_lro_cmd->tcp_flag); 4632 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4633 wmi_lro_cmd->tcp_flag_mask); 4634 cmd->toeplitz_hash_ipv4_0_3 = 4635 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4636 cmd->toeplitz_hash_ipv4_4_7 = 4637 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4638 cmd->toeplitz_hash_ipv4_8_11 = 4639 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4640 cmd->toeplitz_hash_ipv4_12_15 = 4641 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4642 cmd->toeplitz_hash_ipv4_16 = 4643 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4644 4645 cmd->toeplitz_hash_ipv6_0_3 = 4646 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4647 cmd->toeplitz_hash_ipv6_4_7 = 4648 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4649 cmd->toeplitz_hash_ipv6_8_11 = 4650 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4651 cmd->toeplitz_hash_ipv6_12_15 = 4652 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4653 cmd->toeplitz_hash_ipv6_16_19 = 4654 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4655 cmd->toeplitz_hash_ipv6_20_23 = 4656 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4657 cmd->toeplitz_hash_ipv6_24_27 = 4658 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4659 cmd->toeplitz_hash_ipv6_28_31 = 4660 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4661 cmd->toeplitz_hash_ipv6_32_35 = 4662 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4663 cmd->toeplitz_hash_ipv6_36_39 = 4664 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4665 cmd->toeplitz_hash_ipv6_40 = 4666 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4667 4668 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4669 wmi_handle, 4670 pdev_id); 4671 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4672 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4673 4674 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4675 status = wmi_unified_cmd_send(wmi_handle, buf, 4676 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4677 if (QDF_IS_STATUS_ERROR(status)) { 4678 wmi_buf_free(buf); 4679 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 4680 } 4681 4682 return status; 4683 } 4684 4685 /** 4686 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4687 * @wmi_handle: Pointer to wmi handle 4688 * @rate_report_params: Pointer to peer rate report parameters 4689 * 4690 * 4691 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4692 */ 4693 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4694 struct wmi_peer_rate_report_params *rate_report_params) 4695 { 4696 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4697 wmi_buf_t buf = NULL; 4698 QDF_STATUS status = 0; 4699 uint32_t len = 0; 4700 uint32_t i, j; 4701 4702 len = sizeof(*cmd); 4703 4704 buf = wmi_buf_alloc(wmi_handle, len); 4705 if (!buf) 4706 return QDF_STATUS_E_FAILURE; 4707 4708 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4709 wmi_buf_data(buf); 4710 4711 WMITLV_SET_HDR( 4712 &cmd->tlv_header, 4713 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4714 WMITLV_GET_STRUCT_TLVLEN( 4715 wmi_peer_set_rate_report_condition_fixed_param)); 4716 4717 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4718 cmd->report_backoff_time = rate_report_params->backoff_time; 4719 cmd->report_timer_period = rate_report_params->timer_period; 4720 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4721 cmd->cond_per_phy[i].val_cond_flags = 4722 rate_report_params->report_per_phy[i].cond_flags; 4723 cmd->cond_per_phy[i].rate_delta.min_delta = 4724 rate_report_params->report_per_phy[i].delta.delta_min; 4725 cmd->cond_per_phy[i].rate_delta.percentage = 4726 rate_report_params->report_per_phy[i].delta.percent; 4727 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4728 cmd->cond_per_phy[i].rate_threshold[j] = 4729 rate_report_params->report_per_phy[i]. 4730 report_rate_threshold[j]; 4731 } 4732 } 4733 4734 wmi_debug("enable %d backoff_time %d period %d", 4735 cmd->enable_rate_report, 4736 cmd->report_backoff_time, cmd->report_timer_period); 4737 4738 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4739 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4740 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4741 if (QDF_IS_STATUS_ERROR(status)) { 4742 wmi_buf_free(buf); 4743 wmi_err("Failed to send peer_set_report_cond command"); 4744 } 4745 return status; 4746 } 4747 4748 /** 4749 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4750 * @wmi_handle: wmi handle 4751 * @vdev_id: vdev id. 4752 * @wmm_vparams: edca parameters 4753 * 4754 * This function updates EDCA parameters to the target 4755 * 4756 * Return: CDF Status 4757 */ 4758 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4759 uint8_t vdev_id, bool mu_edca_param, 4760 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4761 { 4762 uint8_t *buf_ptr; 4763 wmi_buf_t buf; 4764 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4765 wmi_wmm_vparams *wmm_param; 4766 struct wmi_host_wme_vparams *twmm_param; 4767 int len = sizeof(*cmd); 4768 int ac; 4769 4770 buf = wmi_buf_alloc(wmi_handle, len); 4771 4772 if (!buf) 4773 return QDF_STATUS_E_NOMEM; 4774 4775 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4776 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4777 WMITLV_SET_HDR(&cmd->tlv_header, 4778 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4779 WMITLV_GET_STRUCT_TLVLEN 4780 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4781 cmd->vdev_id = vdev_id; 4782 cmd->wmm_param_type = mu_edca_param; 4783 4784 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4785 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4786 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4787 WMITLV_SET_HDR(&wmm_param->tlv_header, 4788 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4789 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4790 wmm_param->cwmin = twmm_param->cwmin; 4791 wmm_param->cwmax = twmm_param->cwmax; 4792 wmm_param->aifs = twmm_param->aifs; 4793 if (mu_edca_param) 4794 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4795 else 4796 wmm_param->txoplimit = twmm_param->txoplimit; 4797 wmm_param->acm = twmm_param->acm; 4798 wmm_param->no_ack = twmm_param->noackpolicy; 4799 } 4800 4801 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4802 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4803 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4804 goto fail; 4805 4806 return QDF_STATUS_SUCCESS; 4807 4808 fail: 4809 wmi_buf_free(buf); 4810 wmi_err("Failed to set WMM Parameters"); 4811 return QDF_STATUS_E_FAILURE; 4812 } 4813 4814 /** 4815 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4816 * @wmi_handle: wmi handle 4817 * @vdev_id: vdev id 4818 * @probe_rsp_info: probe response info 4819 * 4820 * Return: QDF_STATUS_SUCCESS for success or error code 4821 */ 4822 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4823 uint8_t vdev_id, 4824 struct wmi_probe_resp_params *probe_rsp_info) 4825 { 4826 wmi_prb_tmpl_cmd_fixed_param *cmd; 4827 wmi_bcn_prb_info *bcn_prb_info; 4828 wmi_buf_t wmi_buf; 4829 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4830 uint8_t *buf_ptr; 4831 QDF_STATUS ret; 4832 4833 wmi_debug("Send probe response template for vdev %d", vdev_id); 4834 4835 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4836 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4837 4838 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4839 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4840 tmpl_len_aligned; 4841 4842 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4843 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 4844 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4845 return QDF_STATUS_E_INVAL; 4846 } 4847 4848 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4849 if (!wmi_buf) 4850 return QDF_STATUS_E_NOMEM; 4851 4852 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4853 4854 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4855 WMITLV_SET_HDR(&cmd->tlv_header, 4856 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4857 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4858 cmd->vdev_id = vdev_id; 4859 cmd->buf_len = tmpl_len; 4860 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4861 4862 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4863 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4864 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4865 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4866 bcn_prb_info->caps = 0; 4867 bcn_prb_info->erp = 0; 4868 buf_ptr += sizeof(wmi_bcn_prb_info); 4869 4870 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4871 buf_ptr += WMI_TLV_HDR_SIZE; 4872 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4873 4874 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4875 ret = wmi_unified_cmd_send(wmi_handle, 4876 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4877 if (QDF_IS_STATUS_ERROR(ret)) { 4878 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 4879 wmi_buf_free(wmi_buf); 4880 } 4881 4882 return ret; 4883 } 4884 4885 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4886 #define WPI_IV_LEN 16 4887 4888 /** 4889 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4890 * 4891 * @dest_tx: destination address of tsc key counter 4892 * @src_tx: source address of tsc key counter 4893 * @dest_rx: destination address of rsc key counter 4894 * @src_rx: source address of rsc key counter 4895 * 4896 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4897 * 4898 * Return: None 4899 * 4900 */ 4901 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4902 uint8_t *dest_rx, uint8_t *src_rx) 4903 { 4904 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4905 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4906 } 4907 #else 4908 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4909 uint8_t *dest_rx, uint8_t *src_rx) 4910 { 4911 return; 4912 } 4913 #endif 4914 4915 /** 4916 * send_setup_install_key_cmd_tlv() - set key parameters 4917 * @wmi_handle: wmi handle 4918 * @key_params: key parameters 4919 * 4920 * This function fills structure from information 4921 * passed in key_params. 4922 * 4923 * Return: QDF_STATUS_SUCCESS - success 4924 * QDF_STATUS_E_FAILURE - failure 4925 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4926 */ 4927 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4928 struct set_key_params *key_params) 4929 { 4930 wmi_vdev_install_key_cmd_fixed_param *cmd; 4931 wmi_buf_t buf; 4932 uint8_t *buf_ptr; 4933 uint32_t len; 4934 uint8_t *key_data; 4935 QDF_STATUS status; 4936 4937 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4938 WMI_TLV_HDR_SIZE; 4939 4940 buf = wmi_buf_alloc(wmi_handle, len); 4941 if (!buf) 4942 return QDF_STATUS_E_NOMEM; 4943 4944 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4945 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4946 WMITLV_SET_HDR(&cmd->tlv_header, 4947 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4948 WMITLV_GET_STRUCT_TLVLEN 4949 (wmi_vdev_install_key_cmd_fixed_param)); 4950 cmd->vdev_id = key_params->vdev_id; 4951 cmd->key_ix = key_params->key_idx; 4952 if (key_params->group_key_idx) { 4953 cmd->is_group_key_ix_valid = 1; 4954 cmd->group_key_ix = key_params->group_key_idx; 4955 } 4956 4957 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4958 cmd->key_flags |= key_params->key_flags; 4959 cmd->key_cipher = key_params->key_cipher; 4960 if ((key_params->key_txmic_len) && 4961 (key_params->key_rxmic_len)) { 4962 cmd->key_txmic_len = key_params->key_txmic_len; 4963 cmd->key_rxmic_len = key_params->key_rxmic_len; 4964 } 4965 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4966 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4967 key_params->tx_iv, 4968 cmd->wpi_key_rsc_counter, 4969 key_params->rx_iv); 4970 #endif 4971 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4972 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4973 roundup(key_params->key_len, sizeof(uint32_t))); 4974 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4975 4976 /* for big endian host, copy engine byte_swap is enabled 4977 * But key_data is in network byte order 4978 * Need to byte swap the key_data - so when copy engine 4979 * does byte_swap - target gets key_data in the correct order 4980 */ 4981 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 4982 (const void *)key_params->key_data, 4983 key_params->key_len); 4984 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4985 sizeof(wmi_key_seq_counter)); 4986 cmd->key_len = key_params->key_len; 4987 4988 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4989 sizeof(wmi_key_seq_counter)); 4990 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4991 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4992 WMI_VDEV_INSTALL_KEY_CMDID); 4993 if (QDF_IS_STATUS_ERROR(status)) { 4994 qdf_mem_zero(wmi_buf_data(buf), len); 4995 wmi_buf_free(buf); 4996 } 4997 return status; 4998 } 4999 5000 /** 5001 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5002 * @wmi_handle: wmi handle 5003 * @vdev_id: vdev id 5004 * @p2p_ie: p2p IE 5005 * 5006 * Return: QDF_STATUS_SUCCESS for success or error code 5007 */ 5008 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5009 uint32_t vdev_id, uint8_t *p2p_ie) 5010 { 5011 QDF_STATUS ret; 5012 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5013 wmi_buf_t wmi_buf; 5014 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5015 uint8_t *buf_ptr; 5016 5017 ie_len = (uint32_t) (p2p_ie[1] + 2); 5018 5019 /* More than one P2P IE may be included in a single frame. 5020 If multiple P2P IEs are present, the complete P2P attribute 5021 data consists of the concatenation of the P2P Attribute 5022 fields of the P2P IEs. The P2P Attributes field of each 5023 P2P IE may be any length up to the maximum (251 octets). 5024 In this case host sends one P2P IE to firmware so the length 5025 should not exceed more than 251 bytes 5026 */ 5027 if (ie_len > 251) { 5028 wmi_err("Invalid p2p ie length %u", ie_len); 5029 return QDF_STATUS_E_INVAL; 5030 } 5031 5032 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5033 5034 wmi_buf_len = 5035 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5036 WMI_TLV_HDR_SIZE; 5037 5038 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5039 if (!wmi_buf) 5040 return QDF_STATUS_E_NOMEM; 5041 5042 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5043 5044 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5045 WMITLV_SET_HDR(&cmd->tlv_header, 5046 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5047 WMITLV_GET_STRUCT_TLVLEN 5048 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5049 cmd->vdev_id = vdev_id; 5050 cmd->ie_buf_len = ie_len; 5051 5052 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5053 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5054 buf_ptr += WMI_TLV_HDR_SIZE; 5055 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5056 5057 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5058 5059 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5060 ret = wmi_unified_cmd_send(wmi_handle, 5061 wmi_buf, wmi_buf_len, 5062 WMI_P2P_GO_SET_BEACON_IE); 5063 if (QDF_IS_STATUS_ERROR(ret)) { 5064 wmi_err("Failed to send bcn tmpl: %d", ret); 5065 wmi_buf_free(wmi_buf); 5066 } 5067 5068 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5069 return ret; 5070 } 5071 5072 /** 5073 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5074 * @wmi_handle: wmi handle 5075 * @psetoui: OUI parameters 5076 * 5077 * set scan probe OUI parameters in firmware 5078 * 5079 * Return: CDF status 5080 */ 5081 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5082 struct scan_mac_oui *psetoui) 5083 { 5084 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5085 wmi_buf_t wmi_buf; 5086 uint32_t len; 5087 uint8_t *buf_ptr; 5088 uint32_t *oui_buf; 5089 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5090 5091 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5092 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5093 5094 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5095 if (!wmi_buf) 5096 return QDF_STATUS_E_NOMEM; 5097 5098 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5099 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5100 WMITLV_SET_HDR(&cmd->tlv_header, 5101 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5102 WMITLV_GET_STRUCT_TLVLEN 5103 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5104 5105 oui_buf = &cmd->prob_req_oui; 5106 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5107 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5108 | psetoui->oui[2]; 5109 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5110 5111 cmd->vdev_id = psetoui->vdev_id; 5112 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5113 if (psetoui->enb_probe_req_sno_randomization) 5114 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5115 5116 if (ie_allowlist->allow_list) { 5117 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5118 &cmd->num_vendor_oui, 5119 ie_allowlist); 5120 cmd->flags |= 5121 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5122 } 5123 5124 buf_ptr += sizeof(*cmd); 5125 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5126 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5127 buf_ptr += WMI_TLV_HDR_SIZE; 5128 5129 if (cmd->num_vendor_oui != 0) { 5130 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5131 ie_allowlist->voui); 5132 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5133 } 5134 5135 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5136 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5137 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5138 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5139 wmi_buf_free(wmi_buf); 5140 return QDF_STATUS_E_FAILURE; 5141 } 5142 return QDF_STATUS_SUCCESS; 5143 } 5144 5145 #ifdef IPA_OFFLOAD 5146 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5147 * @wmi_handle: wmi handle 5148 * @ipa_offload: ipa offload control parameter 5149 * 5150 * Returns: 0 on success, error number otherwise 5151 */ 5152 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5153 struct ipa_uc_offload_control_params *ipa_offload) 5154 { 5155 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5156 wmi_buf_t wmi_buf; 5157 uint32_t len; 5158 u_int8_t *buf_ptr; 5159 5160 len = sizeof(*cmd); 5161 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5162 if (!wmi_buf) 5163 return QDF_STATUS_E_NOMEM; 5164 5165 wmi_debug("offload_type=%d, enable=%d", 5166 ipa_offload->offload_type, ipa_offload->enable); 5167 5168 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5169 5170 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5171 WMITLV_SET_HDR(&cmd->tlv_header, 5172 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5173 WMITLV_GET_STRUCT_TLVLEN( 5174 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5175 5176 cmd->offload_type = ipa_offload->offload_type; 5177 cmd->vdev_id = ipa_offload->vdev_id; 5178 cmd->enable = ipa_offload->enable; 5179 5180 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5181 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5182 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5183 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5184 wmi_buf_free(wmi_buf); 5185 return QDF_STATUS_E_FAILURE; 5186 } 5187 5188 return QDF_STATUS_SUCCESS; 5189 } 5190 #endif 5191 5192 /** 5193 * send_pno_stop_cmd_tlv() - PNO stop request 5194 * @wmi_handle: wmi handle 5195 * @vdev_id: vdev id 5196 * 5197 * This function request FW to stop ongoing PNO operation. 5198 * 5199 * Return: CDF status 5200 */ 5201 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5202 { 5203 wmi_nlo_config_cmd_fixed_param *cmd; 5204 int32_t len = sizeof(*cmd); 5205 wmi_buf_t buf; 5206 uint8_t *buf_ptr; 5207 int ret; 5208 5209 /* 5210 * TLV place holder for array of structures nlo_configured_parameters 5211 * TLV place holder for array of uint32_t channel_list 5212 * TLV place holder for chnl prediction cfg 5213 */ 5214 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5215 buf = wmi_buf_alloc(wmi_handle, len); 5216 if (!buf) 5217 return QDF_STATUS_E_NOMEM; 5218 5219 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5220 buf_ptr = (uint8_t *) cmd; 5221 5222 WMITLV_SET_HDR(&cmd->tlv_header, 5223 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5224 WMITLV_GET_STRUCT_TLVLEN 5225 (wmi_nlo_config_cmd_fixed_param)); 5226 5227 cmd->vdev_id = vdev_id; 5228 cmd->flags = WMI_NLO_CONFIG_STOP; 5229 buf_ptr += sizeof(*cmd); 5230 5231 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5232 buf_ptr += WMI_TLV_HDR_SIZE; 5233 5234 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5235 buf_ptr += WMI_TLV_HDR_SIZE; 5236 5237 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5238 buf_ptr += WMI_TLV_HDR_SIZE; 5239 5240 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5241 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5242 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5243 if (ret) { 5244 wmi_err("Failed to send nlo wmi cmd"); 5245 wmi_buf_free(buf); 5246 return QDF_STATUS_E_FAILURE; 5247 } 5248 5249 return QDF_STATUS_SUCCESS; 5250 } 5251 5252 /** 5253 * send_obss_disable_cmd_tlv() - disable obss scan request 5254 * @wmi_handle: wmi handle 5255 * @vdev_id: vdev id 5256 * 5257 * This function request FW to disable ongoing obss scan operation. 5258 * 5259 * Return: QDF status 5260 */ 5261 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5262 uint8_t vdev_id) 5263 { 5264 QDF_STATUS status; 5265 wmi_buf_t buf; 5266 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5267 int len = sizeof(*cmd); 5268 5269 buf = wmi_buf_alloc(wmi_handle, len); 5270 if (!buf) 5271 return QDF_STATUS_E_NOMEM; 5272 5273 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5274 5275 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5276 WMITLV_SET_HDR(&cmd->tlv_header, 5277 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5278 WMITLV_GET_STRUCT_TLVLEN( 5279 wmi_obss_scan_disable_cmd_fixed_param)); 5280 5281 cmd->vdev_id = vdev_id; 5282 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5283 WMI_OBSS_SCAN_DISABLE_CMDID); 5284 if (QDF_IS_STATUS_ERROR(status)) 5285 wmi_buf_free(buf); 5286 5287 return status; 5288 } 5289 5290 /** 5291 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5292 * @buf_ptr: Buffer passed by upper layers 5293 * @pno: Buffer to be sent to the firmware 5294 * 5295 * Copy the PNO Channel prediction configuration parameters 5296 * passed by the upper layers to a WMI format TLV and send it 5297 * down to the firmware. 5298 * 5299 * Return: None 5300 */ 5301 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5302 struct pno_scan_req_params *pno) 5303 { 5304 nlo_channel_prediction_cfg *channel_prediction_cfg = 5305 (nlo_channel_prediction_cfg *) buf_ptr; 5306 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5307 WMITLV_TAG_ARRAY_BYTE, 5308 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5309 #ifdef FEATURE_WLAN_SCAN_PNO 5310 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5311 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5312 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5313 channel_prediction_cfg->full_scan_period_ms = 5314 pno->channel_prediction_full_scan; 5315 #endif 5316 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5317 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5318 channel_prediction_cfg->enable, 5319 channel_prediction_cfg->top_k_num, 5320 channel_prediction_cfg->stationary_threshold, 5321 channel_prediction_cfg->full_scan_period_ms); 5322 } 5323 5324 /** 5325 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5326 * @wmi_handle: wmi handle 5327 * @buf_ptr: Buffer passed by upper layers 5328 * @buf_len: Length of passed buffer by upper layer 5329 * 5330 * Copy the buffer passed by the upper layers and send it 5331 * down to the firmware. 5332 * 5333 * Return: None 5334 */ 5335 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5336 void *buf_ptr, uint32_t buf_len) 5337 { 5338 wmi_buf_t buf = NULL; 5339 QDF_STATUS status; 5340 int len; 5341 uint8_t *data_ptr; 5342 5343 len = buf_len; 5344 buf = wmi_buf_alloc(wmi_handle, len); 5345 if (!buf) 5346 return QDF_STATUS_E_NOMEM; 5347 5348 data_ptr = (uint8_t *)wmi_buf_data(buf); 5349 qdf_mem_copy(data_ptr, buf_ptr, len); 5350 5351 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5352 status = wmi_unified_cmd_send(wmi_handle, buf, 5353 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5354 5355 if (QDF_IS_STATUS_ERROR(status)) { 5356 wmi_buf_free(buf); 5357 return QDF_STATUS_E_FAILURE; 5358 } 5359 return QDF_STATUS_SUCCESS; 5360 } 5361 5362 /** 5363 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5364 * @wmi_handle: wmi handle 5365 * @evt_buf: event buffer 5366 * @more_flag: buffer to populate more flag 5367 * 5368 * Return: status of operation 5369 */ 5370 static QDF_STATUS 5371 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5372 uint32_t *more_flag) 5373 { 5374 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5375 wmi_ctrl_path_stats_event_fixed_param *ev; 5376 5377 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5378 if (!param_buf) { 5379 wmi_err_rl("param_buf is NULL"); 5380 return QDF_STATUS_E_FAILURE; 5381 } 5382 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5383 5384 *more_flag = ev->more; 5385 return QDF_STATUS_SUCCESS; 5386 } 5387 5388 /** 5389 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 5390 * @wmi_handle: wmi handle 5391 * @params: configuration parameters 5392 * 5393 * Return: QDF_STATUS 5394 */ 5395 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 5396 struct nlo_mawc_params *params) 5397 { 5398 wmi_buf_t buf = NULL; 5399 QDF_STATUS status; 5400 int len; 5401 uint8_t *buf_ptr; 5402 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 5403 5404 len = sizeof(*wmi_nlo_mawc_params); 5405 buf = wmi_buf_alloc(wmi_handle, len); 5406 if (!buf) 5407 return QDF_STATUS_E_NOMEM; 5408 5409 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5410 wmi_nlo_mawc_params = 5411 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 5412 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 5413 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 5414 WMITLV_GET_STRUCT_TLVLEN 5415 (wmi_nlo_configure_mawc_cmd_fixed_param)); 5416 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 5417 if (params->enable) 5418 wmi_nlo_mawc_params->enable = 1; 5419 else 5420 wmi_nlo_mawc_params->enable = 0; 5421 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 5422 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 5423 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 5424 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 5425 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 5426 wmi_nlo_mawc_params->exp_backoff_ratio, 5427 wmi_nlo_mawc_params->init_scan_interval, 5428 wmi_nlo_mawc_params->max_scan_interval); 5429 5430 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 5431 status = wmi_unified_cmd_send(wmi_handle, buf, 5432 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 5433 if (QDF_IS_STATUS_ERROR(status)) { 5434 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 5435 status); 5436 wmi_buf_free(buf); 5437 return QDF_STATUS_E_FAILURE; 5438 } 5439 5440 return QDF_STATUS_SUCCESS; 5441 } 5442 5443 /** 5444 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 5445 * scan 5446 * @scan_freq_list: frequency list for pno scan 5447 * 5448 * Return: void 5449 */ 5450 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 5451 { 5452 uint32_t i; 5453 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 5454 uint32_t len = 0; 5455 struct chan_info *chan_info; 5456 int ret; 5457 5458 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 5459 for (i = 0; i < scan_freq_list->num_chan; i++) { 5460 chan_info = &scan_freq_list->chan[i]; 5461 ret = qdf_scnprintf(info + len, sizeof(info) - len, 5462 " %d[%d]", chan_info->freq, 5463 chan_info->flags); 5464 if (ret <= 0) 5465 break; 5466 len += ret; 5467 if (len >= (sizeof(info) - 20)) { 5468 wmi_nofl_debug("Freq[flag]:%s", 5469 info); 5470 len = 0; 5471 } 5472 } 5473 if (len) 5474 wmi_nofl_debug("Freq[flag]:%s", info); 5475 } 5476 5477 /** 5478 * send_pno_start_cmd_tlv() - PNO start request 5479 * @wmi_handle: wmi handle 5480 * @pno: PNO request 5481 * 5482 * This function request FW to start PNO request. 5483 * Request: CDF status 5484 */ 5485 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 5486 struct pno_scan_req_params *pno) 5487 { 5488 wmi_nlo_config_cmd_fixed_param *cmd; 5489 nlo_configured_parameters *nlo_list; 5490 uint32_t *channel_list; 5491 int32_t len; 5492 qdf_freq_t freq; 5493 wmi_buf_t buf; 5494 uint8_t *buf_ptr; 5495 uint8_t i; 5496 int ret; 5497 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 5498 connected_nlo_rssi_params *nlo_relative_rssi; 5499 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 5500 5501 /* 5502 * TLV place holder for array nlo_configured_parameters(nlo_list) 5503 * TLV place holder for array of uint32_t channel_list 5504 * TLV place holder for chnnl prediction cfg 5505 * TLV place holder for array of wmi_vendor_oui 5506 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 5507 */ 5508 len = sizeof(*cmd) + 5509 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 5510 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5511 5512 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 5513 len += sizeof(nlo_configured_parameters) * 5514 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5515 len += sizeof(nlo_channel_prediction_cfg); 5516 len += sizeof(enlo_candidate_score_params); 5517 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 5518 len += sizeof(connected_nlo_rssi_params); 5519 len += sizeof(connected_nlo_bss_band_rssi_pref); 5520 5521 buf = wmi_buf_alloc(wmi_handle, len); 5522 if (!buf) 5523 return QDF_STATUS_E_NOMEM; 5524 5525 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5526 5527 buf_ptr = (uint8_t *) cmd; 5528 WMITLV_SET_HDR(&cmd->tlv_header, 5529 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5530 WMITLV_GET_STRUCT_TLVLEN 5531 (wmi_nlo_config_cmd_fixed_param)); 5532 cmd->vdev_id = pno->vdev_id; 5533 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 5534 5535 #ifdef FEATURE_WLAN_SCAN_PNO 5536 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 5537 pno->adaptive_dwell_mode); 5538 #endif 5539 /* Current FW does not support min-max range for dwell time */ 5540 cmd->active_dwell_time = pno->active_dwell_time; 5541 cmd->passive_dwell_time = pno->passive_dwell_time; 5542 5543 if (pno->do_passive_scan) 5544 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 5545 /* Copy scan interval */ 5546 cmd->fast_scan_period = pno->fast_scan_period; 5547 cmd->slow_scan_period = pno->slow_scan_period; 5548 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 5549 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 5550 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 5551 5552 /* mac randomization attributes */ 5553 if (pno->scan_random.randomize) { 5554 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 5555 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 5556 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 5557 pno->scan_random.mac_mask, 5558 &cmd->mac_addr, 5559 &cmd->mac_mask); 5560 } 5561 5562 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 5563 5564 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5565 5566 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5567 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 5568 buf_ptr += WMI_TLV_HDR_SIZE; 5569 5570 nlo_list = (nlo_configured_parameters *) buf_ptr; 5571 for (i = 0; i < cmd->no_of_ssids; i++) { 5572 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 5573 WMITLV_TAG_ARRAY_BYTE, 5574 WMITLV_GET_STRUCT_TLVLEN 5575 (nlo_configured_parameters)); 5576 /* Copy ssid and it's length */ 5577 nlo_list[i].ssid.valid = true; 5578 nlo_list[i].ssid.ssid.ssid_len = 5579 pno->networks_list[i].ssid.length; 5580 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 5581 pno->networks_list[i].ssid.ssid, 5582 nlo_list[i].ssid.ssid.ssid_len); 5583 5584 /* Copy rssi threshold */ 5585 if (pno->networks_list[i].rssi_thresh && 5586 pno->networks_list[i].rssi_thresh > 5587 WMI_RSSI_THOLD_DEFAULT) { 5588 nlo_list[i].rssi_cond.valid = true; 5589 nlo_list[i].rssi_cond.rssi = 5590 pno->networks_list[i].rssi_thresh; 5591 } 5592 nlo_list[i].bcast_nw_type.valid = true; 5593 nlo_list[i].bcast_nw_type.bcast_nw_type = 5594 pno->networks_list[i].bc_new_type; 5595 } 5596 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 5597 5598 /* Copy channel info */ 5599 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 5600 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 5601 (cmd->num_of_channels * sizeof(uint32_t))); 5602 buf_ptr += WMI_TLV_HDR_SIZE; 5603 5604 channel_list = (uint32_t *) buf_ptr; 5605 for (i = 0; i < cmd->num_of_channels; i++) { 5606 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 5607 pno->networks_list[0].pno_chan_list.chan[i].freq); 5608 5609 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 5610 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 5611 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 5612 wlan_chan_to_freq(freq)); 5613 } 5614 5615 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 5616 pno->networks_list[0].pno_chan_list.chan[i].flags); 5617 } 5618 5619 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 5620 5621 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 5622 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5623 sizeof(nlo_channel_prediction_cfg)); 5624 buf_ptr += WMI_TLV_HDR_SIZE; 5625 wmi_set_pno_channel_prediction(buf_ptr, pno); 5626 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5627 /** TODO: Discrete firmware doesn't have command/option to configure 5628 * App IE which comes from wpa_supplicant as of part PNO start request. 5629 */ 5630 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 5631 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 5632 buf_ptr += sizeof(enlo_candidate_score_params); 5633 5634 if (ie_allowlist->allow_list) { 5635 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5636 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5637 &cmd->num_vendor_oui, 5638 ie_allowlist); 5639 } 5640 5641 /* ie allow list */ 5642 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5643 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5644 buf_ptr += WMI_TLV_HDR_SIZE; 5645 if (cmd->num_vendor_oui != 0) { 5646 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5647 ie_allowlist->voui); 5648 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5649 } 5650 5651 if (pno->relative_rssi_set) 5652 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 5653 5654 /* 5655 * Firmware calculation using connected PNO params: 5656 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 5657 * deduction of rssi_pref for chosen band_pref and 5658 * addition of rssi_pref for remaining bands (other than chosen band). 5659 */ 5660 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 5661 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 5662 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 5663 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 5664 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 5665 buf_ptr += sizeof(*nlo_relative_rssi); 5666 5667 /* 5668 * As of now Kernel and Host supports one band and rssi preference. 5669 * Firmware supports array of band and rssi preferences 5670 */ 5671 cmd->num_cnlo_band_pref = 1; 5672 WMITLV_SET_HDR(buf_ptr, 5673 WMITLV_TAG_ARRAY_STRUC, 5674 cmd->num_cnlo_band_pref * 5675 sizeof(connected_nlo_bss_band_rssi_pref)); 5676 buf_ptr += WMI_TLV_HDR_SIZE; 5677 5678 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 5679 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 5680 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 5681 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 5682 WMITLV_GET_STRUCT_TLVLEN( 5683 connected_nlo_bss_band_rssi_pref)); 5684 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 5685 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 5686 } 5687 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 5688 5689 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5690 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5691 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5692 if (ret) { 5693 wmi_err("Failed to send nlo wmi cmd"); 5694 wmi_buf_free(buf); 5695 return QDF_STATUS_E_FAILURE; 5696 } 5697 5698 return QDF_STATUS_SUCCESS; 5699 } 5700 5701 /** 5702 * is_service_enabled_tlv() - Check if service enabled 5703 * @param wmi_handle: wmi handle 5704 * @param service_id: service identifier 5705 * 5706 * Return: 1 enabled, 0 disabled 5707 */ 5708 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 5709 uint32_t service_id) 5710 { 5711 struct wmi_soc *soc = wmi_handle->soc; 5712 5713 if (!soc->wmi_service_bitmap) { 5714 wmi_err("WMI service bit map is not saved yet"); 5715 return false; 5716 } 5717 5718 /* if wmi_service_enabled was received with extended2 bitmap, 5719 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 5720 */ 5721 if (soc->wmi_ext2_service_bitmap) { 5722 if (!soc->wmi_ext_service_bitmap) { 5723 wmi_err("WMI service ext bit map is not saved yet"); 5724 return false; 5725 } 5726 5727 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 5728 soc->wmi_ext_service_bitmap, 5729 soc->wmi_ext2_service_bitmap, 5730 service_id); 5731 } 5732 5733 if (service_id >= WMI_MAX_EXT_SERVICE) { 5734 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 5735 service_id); 5736 return false; 5737 } 5738 /* if wmi_service_enabled was received with extended bitmap, 5739 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 5740 */ 5741 if (soc->wmi_ext_service_bitmap) 5742 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 5743 soc->wmi_ext_service_bitmap, 5744 service_id); 5745 5746 if (service_id >= WMI_MAX_SERVICE) { 5747 wmi_err("Service id %d but WMI ext service bitmap is NULL", 5748 service_id); 5749 return false; 5750 } 5751 5752 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 5753 service_id); 5754 } 5755 5756 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5757 /** 5758 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5759 * @wmi_handle: wmi handle 5760 * @clear_req: ll stats clear request command params 5761 * 5762 * Return: QDF_STATUS_SUCCESS for success or error code 5763 */ 5764 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5765 const struct ll_stats_clear_params *clear_req) 5766 { 5767 wmi_clear_link_stats_cmd_fixed_param *cmd; 5768 int32_t len; 5769 wmi_buf_t buf; 5770 uint8_t *buf_ptr; 5771 int ret; 5772 5773 len = sizeof(*cmd); 5774 buf = wmi_buf_alloc(wmi_handle, len); 5775 5776 if (!buf) 5777 return QDF_STATUS_E_NOMEM; 5778 5779 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5780 qdf_mem_zero(buf_ptr, len); 5781 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5782 5783 WMITLV_SET_HDR(&cmd->tlv_header, 5784 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5785 WMITLV_GET_STRUCT_TLVLEN 5786 (wmi_clear_link_stats_cmd_fixed_param)); 5787 5788 cmd->stop_stats_collection_req = clear_req->stop_req; 5789 cmd->vdev_id = clear_req->vdev_id; 5790 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5791 5792 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5793 &cmd->peer_macaddr); 5794 5795 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 5796 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 5797 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5798 cmd->stop_stats_collection_req, 5799 cmd->vdev_id, cmd->stats_clear_req_mask, 5800 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 5801 5802 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5803 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5804 WMI_CLEAR_LINK_STATS_CMDID); 5805 if (ret) { 5806 wmi_err("Failed to send clear link stats req"); 5807 wmi_buf_free(buf); 5808 return QDF_STATUS_E_FAILURE; 5809 } 5810 5811 wmi_debug("Clear Link Layer Stats request sent successfully"); 5812 return QDF_STATUS_SUCCESS; 5813 } 5814 5815 /** 5816 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5817 * @wmi_handle: wmi handle 5818 * @set_req: ll stats set request command params 5819 * 5820 * Return: QDF_STATUS_SUCCESS for success or error code 5821 */ 5822 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5823 const struct ll_stats_set_params *set_req) 5824 { 5825 wmi_start_link_stats_cmd_fixed_param *cmd; 5826 int32_t len; 5827 wmi_buf_t buf; 5828 uint8_t *buf_ptr; 5829 int ret; 5830 5831 len = sizeof(*cmd); 5832 buf = wmi_buf_alloc(wmi_handle, len); 5833 5834 if (!buf) 5835 return QDF_STATUS_E_NOMEM; 5836 5837 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5838 qdf_mem_zero(buf_ptr, len); 5839 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5840 5841 WMITLV_SET_HDR(&cmd->tlv_header, 5842 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5843 WMITLV_GET_STRUCT_TLVLEN 5844 (wmi_start_link_stats_cmd_fixed_param)); 5845 5846 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5847 cmd->aggressive_statistics_gathering = 5848 set_req->aggressive_statistics_gathering; 5849 5850 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 5851 cmd->mpdu_size_threshold, 5852 cmd->aggressive_statistics_gathering); 5853 5854 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5855 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5856 WMI_START_LINK_STATS_CMDID); 5857 if (ret) { 5858 wmi_err("Failed to send set link stats request"); 5859 wmi_buf_free(buf); 5860 return QDF_STATUS_E_FAILURE; 5861 } 5862 5863 return QDF_STATUS_SUCCESS; 5864 } 5865 5866 /** 5867 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5868 * @wmi_handle: wmi handle 5869 * @get_req: ll stats get request command params 5870 * 5871 * Return: QDF_STATUS_SUCCESS for success or error code 5872 */ 5873 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5874 const struct ll_stats_get_params *get_req) 5875 { 5876 wmi_request_link_stats_cmd_fixed_param *cmd; 5877 int32_t len; 5878 wmi_buf_t buf; 5879 uint8_t *buf_ptr; 5880 int ret; 5881 5882 len = sizeof(*cmd); 5883 buf = wmi_buf_alloc(wmi_handle, len); 5884 5885 if (!buf) 5886 return QDF_STATUS_E_NOMEM; 5887 5888 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5889 qdf_mem_zero(buf_ptr, len); 5890 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5891 5892 WMITLV_SET_HDR(&cmd->tlv_header, 5893 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5894 WMITLV_GET_STRUCT_TLVLEN 5895 (wmi_request_link_stats_cmd_fixed_param)); 5896 5897 cmd->request_id = get_req->req_id; 5898 cmd->stats_type = get_req->param_id_mask; 5899 cmd->vdev_id = get_req->vdev_id; 5900 5901 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5902 &cmd->peer_macaddr); 5903 5904 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5905 cmd->request_id, cmd->stats_type, cmd->vdev_id, 5906 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5907 5908 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 5909 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 5910 WMI_REQUEST_LINK_STATS_CMDID, true); 5911 if (ret) { 5912 wmi_buf_free(buf); 5913 return QDF_STATUS_E_FAILURE; 5914 } 5915 5916 return QDF_STATUS_SUCCESS; 5917 } 5918 5919 #ifdef WLAN_FEATURE_11BE_MLO 5920 static int 5921 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 5922 { 5923 int32_t len = 0; 5924 5925 /* In case of MLO connection, update the length of the buffer. 5926 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 5927 * hence just update the TLV header, but allocate no memory for it. 5928 */ 5929 if (!get_req->is_mlo_req) 5930 return len; 5931 5932 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 5933 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 5934 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 5935 5936 return len; 5937 } 5938 5939 static void 5940 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 5941 void *buf_ptr) 5942 { 5943 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 5944 uint32_t *vdev_id_bitmap; 5945 wmi_mac_addr *mld_mac; 5946 5947 /* In case of MLO connection, update the TLV Headers */ 5948 if (!get_req->is_mlo_req) 5949 return; 5950 5951 buf_ptr += sizeof(*unified_cmd); 5952 5953 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 5954 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5955 buf_ptr += WMI_TLV_HDR_SIZE; 5956 5957 /* Adding vdev_bitmap_id array TLV */ 5958 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 5959 sizeof(*vdev_id_bitmap)); 5960 buf_ptr += WMI_TLV_HDR_SIZE; 5961 vdev_id_bitmap = buf_ptr; 5962 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 5963 buf_ptr += sizeof(*vdev_id_bitmap); 5964 5965 /* Adding mld_macaddr array TLV */ 5966 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 5967 sizeof(*mld_mac)); 5968 buf_ptr += WMI_TLV_HDR_SIZE; 5969 mld_mac = buf_ptr; 5970 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 5971 5972 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 5973 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 5974 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 5975 } 5976 #else 5977 static inline int 5978 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 5979 { 5980 return 0; 5981 } 5982 5983 static inline void 5984 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 5985 void *buf_ptr) 5986 { 5987 } 5988 #endif 5989 5990 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 5991 /** 5992 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 5993 * station request 5994 * @wmi_handle: wmi handle 5995 * @get_req: ll stats get request command params 5996 * 5997 * Return: QDF_STATUS_SUCCESS for success or error code 5998 */ 5999 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6000 wmi_unified_t wmi_handle, 6001 const struct ll_stats_get_params *get_req) 6002 { 6003 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6004 int32_t len; 6005 wmi_buf_t buf; 6006 void *buf_ptr; 6007 QDF_STATUS ret; 6008 bool is_ll_get_sta_stats_over_qmi; 6009 6010 len = sizeof(*unified_cmd); 6011 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6012 6013 buf = wmi_buf_alloc(wmi_handle, len); 6014 if (!buf) 6015 return QDF_STATUS_E_NOMEM; 6016 6017 buf_ptr = wmi_buf_data(buf); 6018 6019 unified_cmd = buf_ptr; 6020 WMITLV_SET_HDR( 6021 &unified_cmd->tlv_header, 6022 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6023 WMITLV_GET_STRUCT_TLVLEN 6024 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6025 6026 unified_cmd->link_stats_type = get_req->param_id_mask; 6027 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6028 WMI_REQUEST_PEER_STAT | 6029 WMI_REQUEST_VDEV_STAT | 6030 WMI_REQUEST_PDEV_STAT | 6031 WMI_REQUEST_PEER_EXTD2_STAT | 6032 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6033 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6034 wmi_handle, 6035 WMI_HOST_PDEV_ID_SOC); 6036 6037 unified_cmd->vdev_id = get_req->vdev_id; 6038 unified_cmd->request_id = get_req->req_id; 6039 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6040 &unified_cmd->peer_macaddr); 6041 6042 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6043 QDF_MAC_ADDR_FMT, 6044 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6045 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6046 6047 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6048 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6049 6050 /** 6051 * FW support for LL_get_sta command. True represents the unified 6052 * ll_get_sta command should be sent over QMI always irrespective of 6053 * WOW state. 6054 */ 6055 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6056 wmi_handle, 6057 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6058 6059 if (is_ll_get_sta_stats_over_qmi) { 6060 ret = wmi_unified_cmd_send_over_qmi( 6061 wmi_handle, buf, len, 6062 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6063 } else { 6064 ret = wmi_unified_cmd_send_pm_chk( 6065 wmi_handle, buf, len, 6066 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6067 true); 6068 } 6069 6070 if (QDF_IS_STATUS_ERROR(ret)) { 6071 wmi_buf_free(buf); 6072 return QDF_STATUS_E_FAILURE; 6073 } 6074 6075 return ret; 6076 } 6077 #endif 6078 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6079 6080 /** 6081 * send_congestion_cmd_tlv() - send request to fw to get CCA 6082 * @wmi_handle: wmi handle 6083 * @vdev_id: vdev id 6084 * 6085 * Return: CDF status 6086 */ 6087 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6088 uint8_t vdev_id) 6089 { 6090 wmi_buf_t buf; 6091 wmi_request_stats_cmd_fixed_param *cmd; 6092 uint8_t len; 6093 uint8_t *buf_ptr; 6094 6095 len = sizeof(*cmd); 6096 buf = wmi_buf_alloc(wmi_handle, len); 6097 if (!buf) 6098 return QDF_STATUS_E_FAILURE; 6099 6100 buf_ptr = wmi_buf_data(buf); 6101 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6102 WMITLV_SET_HDR(&cmd->tlv_header, 6103 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6104 WMITLV_GET_STRUCT_TLVLEN 6105 (wmi_request_stats_cmd_fixed_param)); 6106 6107 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6108 cmd->vdev_id = vdev_id; 6109 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6110 cmd->vdev_id, cmd->stats_id); 6111 6112 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6113 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6114 WMI_REQUEST_STATS_CMDID)) { 6115 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6116 wmi_buf_free(buf); 6117 return QDF_STATUS_E_FAILURE; 6118 } 6119 6120 return QDF_STATUS_SUCCESS; 6121 } 6122 6123 /** 6124 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6125 * @wmi_handle: wmi handle 6126 * @rssi_req: get RSSI request 6127 * 6128 * Return: CDF status 6129 */ 6130 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6131 { 6132 wmi_buf_t buf; 6133 wmi_request_stats_cmd_fixed_param *cmd; 6134 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6135 6136 buf = wmi_buf_alloc(wmi_handle, len); 6137 if (!buf) 6138 return QDF_STATUS_E_FAILURE; 6139 6140 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6141 WMITLV_SET_HDR(&cmd->tlv_header, 6142 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6143 WMITLV_GET_STRUCT_TLVLEN 6144 (wmi_request_stats_cmd_fixed_param)); 6145 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6146 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6147 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6148 WMI_REQUEST_STATS_CMDID)) { 6149 wmi_err("Failed to send host stats request to fw"); 6150 wmi_buf_free(buf); 6151 return QDF_STATUS_E_FAILURE; 6152 } 6153 6154 return QDF_STATUS_SUCCESS; 6155 } 6156 6157 /** 6158 * send_snr_cmd_tlv() - get RSSI from fw 6159 * @wmi_handle: wmi handle 6160 * @vdev_id: vdev id 6161 * 6162 * Return: CDF status 6163 */ 6164 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6165 { 6166 wmi_buf_t buf; 6167 wmi_request_stats_cmd_fixed_param *cmd; 6168 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6169 6170 buf = wmi_buf_alloc(wmi_handle, len); 6171 if (!buf) 6172 return QDF_STATUS_E_FAILURE; 6173 6174 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6175 cmd->vdev_id = vdev_id; 6176 6177 WMITLV_SET_HDR(&cmd->tlv_header, 6178 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6179 WMITLV_GET_STRUCT_TLVLEN 6180 (wmi_request_stats_cmd_fixed_param)); 6181 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6182 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6183 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6184 WMI_REQUEST_STATS_CMDID)) { 6185 wmi_err("Failed to send host stats request to fw"); 6186 wmi_buf_free(buf); 6187 return QDF_STATUS_E_FAILURE; 6188 } 6189 6190 return QDF_STATUS_SUCCESS; 6191 } 6192 6193 /** 6194 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6195 * @wmi_handle: wmi handle 6196 * @link_status: get link params 6197 * 6198 * Return: CDF status 6199 */ 6200 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6201 struct link_status_params *link_status) 6202 { 6203 wmi_buf_t buf; 6204 wmi_request_stats_cmd_fixed_param *cmd; 6205 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6206 6207 buf = wmi_buf_alloc(wmi_handle, len); 6208 if (!buf) 6209 return QDF_STATUS_E_FAILURE; 6210 6211 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6212 WMITLV_SET_HDR(&cmd->tlv_header, 6213 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6214 WMITLV_GET_STRUCT_TLVLEN 6215 (wmi_request_stats_cmd_fixed_param)); 6216 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6217 cmd->vdev_id = link_status->vdev_id; 6218 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6219 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6220 WMI_REQUEST_STATS_CMDID)) { 6221 wmi_err("Failed to send WMI link status request to fw"); 6222 wmi_buf_free(buf); 6223 return QDF_STATUS_E_FAILURE; 6224 } 6225 6226 return QDF_STATUS_SUCCESS; 6227 } 6228 6229 #ifdef WLAN_SUPPORT_GREEN_AP 6230 /** 6231 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6232 * @wmi_handle: wmi handler 6233 * @egap_params: pointer to egap_params 6234 * 6235 * Return: 0 for success, otherwise appropriate error code 6236 */ 6237 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 6238 struct wlan_green_ap_egap_params *egap_params) 6239 { 6240 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 6241 wmi_buf_t buf; 6242 int32_t err; 6243 6244 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6245 if (!buf) 6246 return QDF_STATUS_E_NOMEM; 6247 6248 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 6249 WMITLV_SET_HDR(&cmd->tlv_header, 6250 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 6251 WMITLV_GET_STRUCT_TLVLEN( 6252 wmi_ap_ps_egap_param_cmd_fixed_param)); 6253 6254 cmd->enable = egap_params->host_enable_egap; 6255 cmd->inactivity_time = egap_params->egap_inactivity_time; 6256 cmd->wait_time = egap_params->egap_wait_time; 6257 cmd->flags = egap_params->egap_feature_flags; 6258 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 6259 err = wmi_unified_cmd_send(wmi_handle, buf, 6260 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 6261 if (err) { 6262 wmi_err("Failed to send ap_ps_egap cmd"); 6263 wmi_buf_free(buf); 6264 return QDF_STATUS_E_FAILURE; 6265 } 6266 6267 return QDF_STATUS_SUCCESS; 6268 } 6269 #endif 6270 6271 /** 6272 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 6273 * @wmi_handle: wmi handle 6274 * @vdev_id: vdev id 6275 * 6276 * Return: QDF_STATUS_SUCCESS for success or error code 6277 */ 6278 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 6279 uint8_t vdev_id) 6280 { 6281 wmi_csa_offload_enable_cmd_fixed_param *cmd; 6282 wmi_buf_t buf; 6283 int32_t len = sizeof(*cmd); 6284 6285 wmi_debug("vdev_id %d", vdev_id); 6286 buf = wmi_buf_alloc(wmi_handle, len); 6287 if (!buf) 6288 return QDF_STATUS_E_NOMEM; 6289 6290 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 6291 WMITLV_SET_HDR(&cmd->tlv_header, 6292 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 6293 WMITLV_GET_STRUCT_TLVLEN 6294 (wmi_csa_offload_enable_cmd_fixed_param)); 6295 cmd->vdev_id = vdev_id; 6296 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 6297 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 6298 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6299 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 6300 wmi_err("Failed to send CSA offload enable command"); 6301 wmi_buf_free(buf); 6302 return QDF_STATUS_E_FAILURE; 6303 } 6304 6305 return 0; 6306 } 6307 6308 #ifdef WLAN_FEATURE_CIF_CFR 6309 /** 6310 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 6311 * @wmi_handle: wmi handle 6312 * @data_len: len of dma cfg req 6313 * @data: dma cfg req 6314 * 6315 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 6316 */ 6317 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 6318 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 6319 { 6320 wmi_buf_t buf; 6321 uint8_t *cmd; 6322 QDF_STATUS ret; 6323 6324 WMITLV_SET_HDR(cfg, 6325 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 6326 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 6327 6328 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 6329 if (!buf) 6330 return QDF_STATUS_E_FAILURE; 6331 6332 cmd = (uint8_t *) wmi_buf_data(buf); 6333 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 6334 wmi_debug("Sending OEM Data Request to target, data len %lu", 6335 sizeof(*cfg)); 6336 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 6337 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 6338 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 6339 if (QDF_IS_STATUS_ERROR(ret)) { 6340 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 6341 wmi_buf_free(buf); 6342 } 6343 6344 return ret; 6345 } 6346 #endif 6347 6348 /** 6349 * send_start_11d_scan_cmd_tlv() - start 11d scan request 6350 * @wmi_handle: wmi handle 6351 * @start_11d_scan: 11d scan start request parameters 6352 * 6353 * This function request FW to start 11d scan. 6354 * 6355 * Return: QDF status 6356 */ 6357 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6358 struct reg_start_11d_scan_req *start_11d_scan) 6359 { 6360 wmi_11d_scan_start_cmd_fixed_param *cmd; 6361 int32_t len; 6362 wmi_buf_t buf; 6363 int ret; 6364 6365 len = sizeof(*cmd); 6366 buf = wmi_buf_alloc(wmi_handle, len); 6367 if (!buf) 6368 return QDF_STATUS_E_NOMEM; 6369 6370 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 6371 6372 WMITLV_SET_HDR(&cmd->tlv_header, 6373 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 6374 WMITLV_GET_STRUCT_TLVLEN 6375 (wmi_11d_scan_start_cmd_fixed_param)); 6376 6377 cmd->vdev_id = start_11d_scan->vdev_id; 6378 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 6379 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 6380 6381 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 6382 6383 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 6384 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6385 WMI_11D_SCAN_START_CMDID); 6386 if (ret) { 6387 wmi_err("Failed to send start 11d scan wmi cmd"); 6388 wmi_buf_free(buf); 6389 return QDF_STATUS_E_FAILURE; 6390 } 6391 6392 return QDF_STATUS_SUCCESS; 6393 } 6394 6395 /** 6396 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 6397 * @wmi_handle: wmi handle 6398 * @start_11d_scan: 11d scan stop request parameters 6399 * 6400 * This function request FW to stop 11d scan. 6401 * 6402 * Return: QDF status 6403 */ 6404 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6405 struct reg_stop_11d_scan_req *stop_11d_scan) 6406 { 6407 wmi_11d_scan_stop_cmd_fixed_param *cmd; 6408 int32_t len; 6409 wmi_buf_t buf; 6410 int ret; 6411 6412 len = sizeof(*cmd); 6413 buf = wmi_buf_alloc(wmi_handle, len); 6414 if (!buf) 6415 return QDF_STATUS_E_NOMEM; 6416 6417 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 6418 6419 WMITLV_SET_HDR(&cmd->tlv_header, 6420 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 6421 WMITLV_GET_STRUCT_TLVLEN 6422 (wmi_11d_scan_stop_cmd_fixed_param)); 6423 6424 cmd->vdev_id = stop_11d_scan->vdev_id; 6425 6426 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 6427 6428 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 6429 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6430 WMI_11D_SCAN_STOP_CMDID); 6431 if (ret) { 6432 wmi_err("Failed to send stop 11d scan wmi cmd"); 6433 wmi_buf_free(buf); 6434 return QDF_STATUS_E_FAILURE; 6435 } 6436 6437 return QDF_STATUS_SUCCESS; 6438 } 6439 6440 /** 6441 * send_start_oem_data_cmd_tlv() - start OEM data request to target 6442 * @wmi_handle: wmi handle 6443 * @data_len: the length of @data 6444 * @data: the pointer to data buf 6445 * 6446 * Return: CDF status 6447 */ 6448 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 6449 uint32_t data_len, 6450 uint8_t *data) 6451 { 6452 wmi_buf_t buf; 6453 uint8_t *cmd; 6454 QDF_STATUS ret; 6455 6456 buf = wmi_buf_alloc(wmi_handle, 6457 (data_len + WMI_TLV_HDR_SIZE)); 6458 if (!buf) 6459 return QDF_STATUS_E_FAILURE; 6460 6461 cmd = (uint8_t *) wmi_buf_data(buf); 6462 6463 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 6464 cmd += WMI_TLV_HDR_SIZE; 6465 qdf_mem_copy(cmd, data, 6466 data_len); 6467 6468 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 6469 6470 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 6471 ret = wmi_unified_cmd_send(wmi_handle, buf, 6472 (data_len + 6473 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 6474 6475 if (QDF_IS_STATUS_ERROR(ret)) { 6476 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 6477 wmi_buf_free(buf); 6478 } 6479 6480 return ret; 6481 } 6482 6483 #ifdef FEATURE_OEM_DATA 6484 /** 6485 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 6486 * @wmi_handle: wmi handle 6487 * @oem_data: the pointer to oem data 6488 * 6489 * Return: QDF status 6490 */ 6491 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 6492 struct oem_data *oem_data) 6493 { 6494 QDF_STATUS ret; 6495 wmi_oem_data_cmd_fixed_param *cmd; 6496 struct wmi_ops *ops; 6497 wmi_buf_t buf; 6498 uint16_t len = sizeof(*cmd); 6499 uint16_t oem_data_len_aligned; 6500 uint8_t *buf_ptr; 6501 uint32_t pdev_id; 6502 6503 if (!oem_data || !oem_data->data) { 6504 wmi_err_rl("oem data is not valid"); 6505 return QDF_STATUS_E_FAILURE; 6506 } 6507 6508 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 6509 if (oem_data_len_aligned < oem_data->data_len) { 6510 wmi_err_rl("integer overflow while rounding up data_len"); 6511 return QDF_STATUS_E_FAILURE; 6512 } 6513 6514 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 6515 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 6516 return QDF_STATUS_E_FAILURE; 6517 } 6518 6519 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 6520 buf = wmi_buf_alloc(wmi_handle, len); 6521 if (!buf) 6522 return QDF_STATUS_E_NOMEM; 6523 6524 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6525 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 6526 WMITLV_SET_HDR(&cmd->tlv_header, 6527 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 6528 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 6529 6530 pdev_id = oem_data->pdev_id; 6531 if (oem_data->pdev_vdev_flag) { 6532 ops = wmi_handle->ops; 6533 if (oem_data->is_host_pdev_id) 6534 pdev_id = 6535 ops->convert_host_pdev_id_to_target(wmi_handle, 6536 pdev_id); 6537 else 6538 pdev_id = 6539 ops->convert_pdev_id_host_to_target(wmi_handle, 6540 pdev_id); 6541 } 6542 6543 cmd->vdev_id = oem_data->vdev_id; 6544 cmd->data_len = oem_data->data_len; 6545 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 6546 cmd->pdev_id = pdev_id; 6547 6548 buf_ptr += sizeof(*cmd); 6549 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 6550 buf_ptr += WMI_TLV_HDR_SIZE; 6551 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 6552 6553 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 6554 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 6555 if (QDF_IS_STATUS_ERROR(ret)) { 6556 wmi_err_rl("Failed with ret = %d", ret); 6557 wmi_buf_free(buf); 6558 } 6559 6560 return ret; 6561 } 6562 #endif 6563 6564 /** 6565 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 6566 * @wmi_handle: wmi handle 6567 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 6568 * 6569 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 6570 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 6571 * to firmware based on phyerr filtering 6572 * offload status. 6573 * 6574 * Return: 1 success, 0 failure 6575 */ 6576 static QDF_STATUS 6577 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 6578 bool dfs_phyerr_filter_offload) 6579 { 6580 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 6581 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 6582 wmi_buf_t buf; 6583 uint16_t len; 6584 QDF_STATUS ret; 6585 6586 6587 if (false == dfs_phyerr_filter_offload) { 6588 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 6589 len = sizeof(*disable_phyerr_offload_cmd); 6590 buf = wmi_buf_alloc(wmi_handle, len); 6591 if (!buf) 6592 return 0; 6593 6594 disable_phyerr_offload_cmd = 6595 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 6596 wmi_buf_data(buf); 6597 6598 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 6599 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 6600 WMITLV_GET_STRUCT_TLVLEN 6601 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 6602 6603 /* 6604 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 6605 * to the firmware to disable the phyerror 6606 * filtering offload. 6607 */ 6608 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 6609 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6610 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 6611 if (QDF_IS_STATUS_ERROR(ret)) { 6612 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 6613 ret); 6614 wmi_buf_free(buf); 6615 return QDF_STATUS_E_FAILURE; 6616 } 6617 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 6618 } else { 6619 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 6620 6621 len = sizeof(*enable_phyerr_offload_cmd); 6622 buf = wmi_buf_alloc(wmi_handle, len); 6623 if (!buf) 6624 return QDF_STATUS_E_FAILURE; 6625 6626 enable_phyerr_offload_cmd = 6627 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 6628 wmi_buf_data(buf); 6629 6630 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 6631 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 6632 WMITLV_GET_STRUCT_TLVLEN 6633 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 6634 6635 /* 6636 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 6637 * to the firmware to enable the phyerror 6638 * filtering offload. 6639 */ 6640 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 6641 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6642 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 6643 6644 if (QDF_IS_STATUS_ERROR(ret)) { 6645 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 6646 wmi_buf_free(buf); 6647 return QDF_STATUS_E_FAILURE; 6648 } 6649 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 6650 } 6651 6652 return QDF_STATUS_SUCCESS; 6653 } 6654 6655 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 6656 /** 6657 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 6658 * @wmi_handle: wmi handle 6659 * @pktlog_event: pktlog event 6660 * @cmd_id: pktlog cmd id 6661 * @user_triggered: user triggered input for PKTLOG enable mode 6662 * 6663 * Return: CDF status 6664 */ 6665 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 6666 WMI_PKTLOG_EVENT pktlog_event, 6667 WMI_CMD_ID cmd_id, uint8_t user_triggered) 6668 { 6669 WMI_PKTLOG_EVENT PKTLOG_EVENT; 6670 WMI_CMD_ID CMD_ID; 6671 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 6672 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 6673 int len = 0; 6674 wmi_buf_t buf; 6675 int32_t idx, max_idx; 6676 6677 PKTLOG_EVENT = pktlog_event; 6678 CMD_ID = cmd_id; 6679 6680 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 6681 switch (CMD_ID) { 6682 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 6683 len = sizeof(*cmd); 6684 buf = wmi_buf_alloc(wmi_handle, len); 6685 if (!buf) 6686 return QDF_STATUS_E_NOMEM; 6687 6688 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 6689 wmi_buf_data(buf); 6690 WMITLV_SET_HDR(&cmd->tlv_header, 6691 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 6692 WMITLV_GET_STRUCT_TLVLEN 6693 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 6694 cmd->evlist = 0; 6695 for (idx = 0; idx < max_idx; idx++) { 6696 if (PKTLOG_EVENT & (1 << idx)) 6697 cmd->evlist |= pktlog_event_tlv[idx]; 6698 } 6699 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 6700 : WMI_PKTLOG_ENABLE_AUTO; 6701 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6702 wmi_handle, 6703 WMI_HOST_PDEV_ID_SOC); 6704 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 6705 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6706 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 6707 wmi_err("Failed to send pktlog enable cmdid"); 6708 goto wmi_send_failed; 6709 } 6710 break; 6711 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 6712 len = sizeof(*disable_cmd); 6713 buf = wmi_buf_alloc(wmi_handle, len); 6714 if (!buf) 6715 return QDF_STATUS_E_NOMEM; 6716 6717 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 6718 wmi_buf_data(buf); 6719 WMITLV_SET_HDR(&disable_cmd->tlv_header, 6720 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 6721 WMITLV_GET_STRUCT_TLVLEN 6722 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 6723 disable_cmd->pdev_id = 6724 wmi_handle->ops->convert_pdev_id_host_to_target( 6725 wmi_handle, 6726 WMI_HOST_PDEV_ID_SOC); 6727 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 6728 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6729 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 6730 wmi_err("failed to send pktlog disable cmdid"); 6731 goto wmi_send_failed; 6732 } 6733 break; 6734 default: 6735 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 6736 break; 6737 } 6738 6739 return QDF_STATUS_SUCCESS; 6740 6741 wmi_send_failed: 6742 wmi_buf_free(buf); 6743 return QDF_STATUS_E_FAILURE; 6744 } 6745 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 6746 6747 /** 6748 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 6749 * @wmi_handle: wmi handle 6750 * @preq: stats ext params 6751 * 6752 * Return: CDF status 6753 */ 6754 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 6755 struct stats_ext_params *preq) 6756 { 6757 QDF_STATUS ret; 6758 wmi_req_stats_ext_cmd_fixed_param *cmd; 6759 wmi_buf_t buf; 6760 size_t len; 6761 uint8_t *buf_ptr; 6762 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 6763 uint32_t *vdev_bitmap; 6764 6765 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 6766 sizeof(*cmd))) { 6767 wmi_err("Data length=%d is greater than max wmi msg size", 6768 preq->request_data_len); 6769 return QDF_STATUS_E_FAILURE; 6770 } 6771 6772 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 6773 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 6774 6775 buf = wmi_buf_alloc(wmi_handle, len); 6776 if (!buf) 6777 return QDF_STATUS_E_NOMEM; 6778 6779 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6780 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 6781 6782 WMITLV_SET_HDR(&cmd->tlv_header, 6783 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 6784 WMITLV_GET_STRUCT_TLVLEN 6785 (wmi_req_stats_ext_cmd_fixed_param)); 6786 cmd->vdev_id = preq->vdev_id; 6787 cmd->data_len = preq->request_data_len; 6788 6789 wmi_debug("The data len value is %u and vdev id set is %u", 6790 preq->request_data_len, preq->vdev_id); 6791 6792 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 6793 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 6794 6795 buf_ptr += WMI_TLV_HDR_SIZE; 6796 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 6797 6798 buf_ptr += cmd->data_len; 6799 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 6800 6801 buf_ptr += WMI_TLV_HDR_SIZE; 6802 6803 vdev_bitmap = (A_UINT32 *)buf_ptr; 6804 6805 vdev_bitmap[0] = preq->vdev_id_bitmap; 6806 6807 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 6808 6809 buf_ptr += sizeof(uint32_t); 6810 6811 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 6812 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6813 WMI_REQUEST_STATS_EXT_CMDID); 6814 if (QDF_IS_STATUS_ERROR(ret)) { 6815 wmi_err("Failed to send notify cmd ret = %d", ret); 6816 wmi_buf_free(buf); 6817 } 6818 6819 return ret; 6820 } 6821 6822 /** 6823 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 6824 * @wmi_handle: wmi handle 6825 * @params: DHCP server offload info 6826 * 6827 * Return: QDF_STATUS_SUCCESS for success or error code 6828 */ 6829 static QDF_STATUS 6830 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 6831 struct dhcp_offload_info_params *params) 6832 { 6833 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 6834 wmi_buf_t buf; 6835 QDF_STATUS status; 6836 6837 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6838 if (!buf) 6839 return QDF_STATUS_E_NOMEM; 6840 6841 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 6842 6843 WMITLV_SET_HDR(&cmd->tlv_header, 6844 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 6845 WMITLV_GET_STRUCT_TLVLEN 6846 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 6847 cmd->vdev_id = params->vdev_id; 6848 cmd->enable = params->dhcp_offload_enabled; 6849 cmd->num_client = params->dhcp_client_num; 6850 cmd->srv_ipv4 = params->dhcp_srv_addr; 6851 cmd->start_lsb = 0; 6852 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 6853 status = wmi_unified_cmd_send(wmi_handle, buf, 6854 sizeof(*cmd), 6855 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 6856 if (QDF_IS_STATUS_ERROR(status)) { 6857 wmi_err("Failed to send set_dhcp_server_offload cmd"); 6858 wmi_buf_free(buf); 6859 return QDF_STATUS_E_FAILURE; 6860 } 6861 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 6862 6863 return status; 6864 } 6865 6866 /** 6867 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 6868 * @wmi_handle: wmi handle 6869 * @param: pointer to pdev regdomain params 6870 * 6871 * Return: 0 for success or error code 6872 */ 6873 static QDF_STATUS 6874 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 6875 struct pdev_set_regdomain_params *param) 6876 { 6877 wmi_buf_t buf; 6878 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6879 int32_t len = sizeof(*cmd); 6880 6881 buf = wmi_buf_alloc(wmi_handle, len); 6882 if (!buf) 6883 return QDF_STATUS_E_NOMEM; 6884 6885 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6886 WMITLV_SET_HDR(&cmd->tlv_header, 6887 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6888 WMITLV_GET_STRUCT_TLVLEN 6889 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6890 6891 cmd->reg_domain = param->currentRDinuse; 6892 cmd->reg_domain_2G = param->currentRD2G; 6893 cmd->reg_domain_5G = param->currentRD5G; 6894 cmd->conformance_test_limit_2G = param->ctl_2G; 6895 cmd->conformance_test_limit_5G = param->ctl_5G; 6896 cmd->dfs_domain = param->dfsDomain; 6897 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6898 wmi_handle, 6899 param->pdev_id); 6900 6901 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6902 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6903 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6904 wmi_err("Failed to send pdev set regdomain command"); 6905 wmi_buf_free(buf); 6906 return QDF_STATUS_E_FAILURE; 6907 } 6908 6909 return QDF_STATUS_SUCCESS; 6910 } 6911 6912 /** 6913 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 6914 * @wmi_handle: wmi handle 6915 * @reg_dmn: reg domain 6916 * @regdmn2G: 2G reg domain 6917 * @regdmn5G: 5G reg domain 6918 * @ctl2G: 2G test limit 6919 * @ctl5G: 5G test limit 6920 * 6921 * Return: none 6922 */ 6923 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 6924 uint32_t reg_dmn, uint16_t regdmn2G, 6925 uint16_t regdmn5G, uint8_t ctl2G, 6926 uint8_t ctl5G) 6927 { 6928 wmi_buf_t buf; 6929 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6930 int32_t len = sizeof(*cmd); 6931 6932 6933 buf = wmi_buf_alloc(wmi_handle, len); 6934 if (!buf) 6935 return QDF_STATUS_E_NOMEM; 6936 6937 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6938 WMITLV_SET_HDR(&cmd->tlv_header, 6939 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6940 WMITLV_GET_STRUCT_TLVLEN 6941 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6942 cmd->reg_domain = reg_dmn; 6943 cmd->reg_domain_2G = regdmn2G; 6944 cmd->reg_domain_5G = regdmn5G; 6945 cmd->conformance_test_limit_2G = ctl2G; 6946 cmd->conformance_test_limit_5G = ctl5G; 6947 6948 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 6949 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 6950 cmd->conformance_test_limit_2G, 6951 cmd->conformance_test_limit_5G); 6952 6953 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6954 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6955 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6956 wmi_err("Failed to send pdev set regdomain command"); 6957 wmi_buf_free(buf); 6958 return QDF_STATUS_E_FAILURE; 6959 } 6960 6961 return QDF_STATUS_SUCCESS; 6962 } 6963 6964 /** 6965 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 6966 * @param: param sent from the host side 6967 * @cmd: param to be sent to the fw side 6968 */ 6969 static inline void copy_custom_aggr_bitmap( 6970 struct set_custom_aggr_size_params *param, 6971 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 6972 { 6973 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 6974 param->ac); 6975 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 6976 param->aggr_type); 6977 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6978 param->tx_aggr_size_disable); 6979 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6980 param->rx_aggr_size_disable); 6981 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 6982 param->tx_ac_enable); 6983 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 6984 param->aggr_ba_enable); 6985 } 6986 6987 /** 6988 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 6989 * @wmi_handle: wmi handle 6990 * @param: pointer to hold custom aggr size params 6991 * 6992 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6993 */ 6994 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 6995 wmi_unified_t wmi_handle, 6996 struct set_custom_aggr_size_params *param) 6997 { 6998 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 6999 wmi_buf_t buf; 7000 int32_t len = sizeof(*cmd); 7001 7002 buf = wmi_buf_alloc(wmi_handle, len); 7003 if (!buf) 7004 return QDF_STATUS_E_FAILURE; 7005 7006 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7007 wmi_buf_data(buf); 7008 WMITLV_SET_HDR(&cmd->tlv_header, 7009 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7010 WMITLV_GET_STRUCT_TLVLEN( 7011 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7012 cmd->vdev_id = param->vdev_id; 7013 cmd->tx_aggr_size = param->tx_aggr_size; 7014 cmd->rx_aggr_size = param->rx_aggr_size; 7015 copy_custom_aggr_bitmap(param, cmd); 7016 7017 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7018 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7019 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7020 "tx_ac_enable=0x%X", 7021 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7022 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7023 param->rx_aggr_size_disable, param->tx_ac_enable); 7024 7025 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7026 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7027 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7028 wmi_err("Setting custom aggregation size failed"); 7029 wmi_buf_free(buf); 7030 return QDF_STATUS_E_FAILURE; 7031 } 7032 7033 return QDF_STATUS_SUCCESS; 7034 } 7035 7036 /** 7037 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7038 * @param wmi_handle : handle to WMI. 7039 * @param param : pointer to tx antenna param 7040 * 7041 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7042 */ 7043 7044 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7045 struct set_qdepth_thresh_params *param) 7046 { 7047 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7048 wmi_msduq_qdepth_thresh_update *cmd_update; 7049 wmi_buf_t buf; 7050 int32_t len = 0; 7051 int i; 7052 uint8_t *buf_ptr; 7053 QDF_STATUS ret; 7054 7055 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7056 wmi_err("Invalid Update Count!"); 7057 return QDF_STATUS_E_INVAL; 7058 } 7059 7060 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7061 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7062 param->num_of_msduq_updates); 7063 buf = wmi_buf_alloc(wmi_handle, len); 7064 7065 if (!buf) 7066 return QDF_STATUS_E_NOMEM; 7067 7068 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7069 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7070 buf_ptr; 7071 7072 WMITLV_SET_HDR(&cmd->tlv_header, 7073 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7074 , WMITLV_GET_STRUCT_TLVLEN( 7075 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7076 7077 cmd->pdev_id = 7078 wmi_handle->ops->convert_pdev_id_host_to_target( 7079 wmi_handle, 7080 param->pdev_id); 7081 cmd->vdev_id = param->vdev_id; 7082 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7083 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7084 7085 buf_ptr += sizeof( 7086 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7087 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7088 param->num_of_msduq_updates * 7089 sizeof(wmi_msduq_qdepth_thresh_update)); 7090 buf_ptr += WMI_TLV_HDR_SIZE; 7091 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7092 7093 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7094 WMITLV_SET_HDR(&cmd_update->tlv_header, 7095 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7096 WMITLV_GET_STRUCT_TLVLEN( 7097 wmi_msduq_qdepth_thresh_update)); 7098 cmd_update->tid_num = param->update_params[i].tid_num; 7099 cmd_update->msduq_update_mask = 7100 param->update_params[i].msduq_update_mask; 7101 cmd_update->qdepth_thresh_value = 7102 param->update_params[i].qdepth_thresh_value; 7103 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7104 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7105 " update mask=0x%X thresh val=0x%X", 7106 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7107 cmd->peer_mac_address.mac_addr31to0, 7108 cmd->peer_mac_address.mac_addr47to32, 7109 cmd_update->msduq_update_mask, 7110 cmd_update->qdepth_thresh_value); 7111 cmd_update++; 7112 } 7113 7114 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7115 cmd->vdev_id, 0); 7116 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7117 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7118 7119 if (ret != 0) { 7120 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7121 wmi_buf_free(buf); 7122 } 7123 7124 return ret; 7125 } 7126 7127 /** 7128 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7129 * @wmi_handle: wmi handle 7130 * @param: pointer to hold vap dscp tid map param 7131 * 7132 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7133 */ 7134 static QDF_STATUS 7135 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7136 struct vap_dscp_tid_map_params *param) 7137 { 7138 wmi_buf_t buf; 7139 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7140 int32_t len = sizeof(*cmd); 7141 7142 buf = wmi_buf_alloc(wmi_handle, len); 7143 if (!buf) 7144 return QDF_STATUS_E_FAILURE; 7145 7146 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7147 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7148 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7149 7150 cmd->vdev_id = param->vdev_id; 7151 cmd->enable_override = 0; 7152 7153 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7154 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7155 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7156 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7157 wmi_err("Failed to set dscp cmd"); 7158 wmi_buf_free(buf); 7159 return QDF_STATUS_E_FAILURE; 7160 } 7161 7162 return QDF_STATUS_SUCCESS; 7163 } 7164 7165 /** 7166 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7167 * @wmi_handle: wmi handle 7168 * @param: pointer to hold fwtest param 7169 * 7170 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7171 */ 7172 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7173 struct set_fwtest_params *param) 7174 { 7175 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7176 wmi_buf_t buf; 7177 int32_t len = sizeof(*cmd); 7178 7179 buf = wmi_buf_alloc(wmi_handle, len); 7180 7181 if (!buf) 7182 return QDF_STATUS_E_FAILURE; 7183 7184 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7185 WMITLV_SET_HDR(&cmd->tlv_header, 7186 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7187 WMITLV_GET_STRUCT_TLVLEN( 7188 wmi_fwtest_set_param_cmd_fixed_param)); 7189 cmd->param_id = param->arg; 7190 cmd->param_value = param->value; 7191 7192 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7193 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7194 wmi_err("Setting FW test param failed"); 7195 wmi_buf_free(buf); 7196 return QDF_STATUS_E_FAILURE; 7197 } 7198 7199 return QDF_STATUS_SUCCESS; 7200 } 7201 7202 /** 7203 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7204 * 7205 * @param wmi_handle : handle to WMI. 7206 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7207 */ 7208 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7209 { 7210 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7211 wmi_buf_t buf; 7212 QDF_STATUS ret; 7213 int32_t len; 7214 7215 len = sizeof(*cmd); 7216 7217 buf = wmi_buf_alloc(wmi_handle, len); 7218 if (!buf) 7219 return QDF_STATUS_E_FAILURE; 7220 7221 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7222 WMITLV_SET_HDR(&cmd->tlv_header, 7223 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7224 WMITLV_GET_STRUCT_TLVLEN( 7225 wmi_pdev_dfs_disable_cmd_fixed_param)); 7226 /* Filling it with WMI_PDEV_ID_SOC for now */ 7227 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7228 wmi_handle, 7229 WMI_HOST_PDEV_ID_SOC); 7230 7231 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7232 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7233 WMI_PDEV_DFS_DISABLE_CMDID); 7234 7235 if (ret != 0) { 7236 wmi_err("Sending PDEV DFS disable cmd failed"); 7237 wmi_buf_free(buf); 7238 } 7239 7240 return ret; 7241 } 7242 7243 /** 7244 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 7245 * 7246 * @param wmi_handle : handle to WMI. 7247 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7248 */ 7249 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 7250 { 7251 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 7252 wmi_buf_t buf; 7253 QDF_STATUS ret; 7254 int32_t len; 7255 7256 len = sizeof(*cmd); 7257 7258 buf = wmi_buf_alloc(wmi_handle, len); 7259 if (!buf) 7260 return QDF_STATUS_E_FAILURE; 7261 7262 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 7263 WMITLV_SET_HDR(&cmd->tlv_header, 7264 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 7265 WMITLV_GET_STRUCT_TLVLEN( 7266 wmi_pdev_dfs_enable_cmd_fixed_param)); 7267 /* Reserved for future use */ 7268 cmd->reserved0 = 0; 7269 7270 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 7271 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7272 WMI_PDEV_DFS_ENABLE_CMDID); 7273 7274 if (ret != 0) { 7275 wmi_err("Sending PDEV DFS enable cmd failed"); 7276 wmi_buf_free(buf); 7277 } 7278 7279 return ret; 7280 } 7281 7282 /** 7283 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 7284 * to fw 7285 * @wmi_handle: wmi handle 7286 * @param: pointer to hold periodic chan stats param 7287 * 7288 * Return: 0 for success or error code 7289 */ 7290 static QDF_STATUS 7291 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 7292 struct periodic_chan_stats_params *param) 7293 { 7294 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 7295 wmi_buf_t buf; 7296 QDF_STATUS ret; 7297 int32_t len; 7298 7299 len = sizeof(*cmd); 7300 7301 buf = wmi_buf_alloc(wmi_handle, len); 7302 if (!buf) 7303 return QDF_STATUS_E_FAILURE; 7304 7305 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 7306 wmi_buf_data(buf); 7307 WMITLV_SET_HDR(&cmd->tlv_header, 7308 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 7309 WMITLV_GET_STRUCT_TLVLEN( 7310 wmi_set_periodic_channel_stats_config_fixed_param)); 7311 cmd->enable = param->enable; 7312 cmd->stats_period = param->stats_period; 7313 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7314 wmi_handle, 7315 param->pdev_id); 7316 7317 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 7318 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7319 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 7320 7321 if (ret != 0) { 7322 wmi_err("Sending periodic chan stats config failed"); 7323 wmi_buf_free(buf); 7324 } 7325 7326 return ret; 7327 } 7328 7329 #ifdef WLAN_IOT_SIM_SUPPORT 7330 /** 7331 * send_simulation_test_cmd_tlv() - send simulation test command to fw 7332 * 7333 * @wmi_handle: wmi handle 7334 * @param: pointer to hold simulation test parameter 7335 * 7336 * Return: 0 for success or error code 7337 */ 7338 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 7339 struct simulation_test_params 7340 *param) 7341 { 7342 wmi_simulation_test_cmd_fixed_param *cmd; 7343 u32 wmi_buf_len; 7344 wmi_buf_t buf; 7345 u8 *buf_ptr; 7346 u32 aligned_len = 0; 7347 7348 wmi_buf_len = sizeof(*cmd); 7349 if (param->buf_len) { 7350 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 7351 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 7352 } 7353 7354 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 7355 if (!buf) { 7356 wmi_err("wmi_buf_alloc failed"); 7357 return QDF_STATUS_E_NOMEM; 7358 } 7359 7360 buf_ptr = wmi_buf_data(buf); 7361 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 7362 WMITLV_SET_HDR(&cmd->tlv_header, 7363 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 7364 WMITLV_GET_STRUCT_TLVLEN( 7365 wmi_simulation_test_cmd_fixed_param)); 7366 cmd->pdev_id = param->pdev_id; 7367 cmd->vdev_id = param->vdev_id; 7368 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 7369 cmd->test_cmd_type = param->test_cmd_type; 7370 cmd->test_subcmd_type = param->test_subcmd_type; 7371 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 7372 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 7373 param->frame_subtype); 7374 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 7375 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 7376 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 7377 cmd->buf_len = param->buf_len; 7378 7379 if (param->buf_len) { 7380 buf_ptr += sizeof(*cmd); 7381 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 7382 buf_ptr += WMI_TLV_HDR_SIZE; 7383 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 7384 } 7385 7386 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 7387 WMI_SIMULATION_TEST_CMDID)) { 7388 wmi_err("Failed to send test simulation cmd"); 7389 wmi_buf_free(buf); 7390 return QDF_STATUS_E_FAILURE; 7391 } 7392 7393 return QDF_STATUS_SUCCESS; 7394 } 7395 #endif 7396 7397 #ifdef WLAN_FEATURE_11BE 7398 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 7399 #else 7400 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 7401 #endif 7402 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 7403 { 7404 switch (wmi_width) { 7405 case WMI_CHAN_WIDTH_20: 7406 return CH_WIDTH_20MHZ; 7407 case WMI_CHAN_WIDTH_40: 7408 return CH_WIDTH_40MHZ; 7409 case WMI_CHAN_WIDTH_80: 7410 return CH_WIDTH_80MHZ; 7411 case WMI_CHAN_WIDTH_160: 7412 return CH_WIDTH_160MHZ; 7413 case WMI_CHAN_WIDTH_80P80: 7414 return CH_WIDTH_80P80MHZ; 7415 case WMI_CHAN_WIDTH_5: 7416 return CH_WIDTH_5MHZ; 7417 case WMI_CHAN_WIDTH_10: 7418 return CH_WIDTH_10MHZ; 7419 case WMI_CHAN_WIDTH_320: 7420 return WLAN_PHY_CH_WIDTH_320MHZ; 7421 default: 7422 return CH_WIDTH_INVALID; 7423 } 7424 } 7425 7426 /** 7427 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 7428 * command to fw 7429 * @wmi_handle: wmi handle 7430 * @param: pointer to hold spectral config parameter 7431 * 7432 * Return: 0 for success or error code 7433 */ 7434 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 7435 struct vdev_spectral_configure_params *param) 7436 { 7437 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 7438 wmi_buf_t buf; 7439 QDF_STATUS ret; 7440 int32_t len; 7441 7442 len = sizeof(*cmd); 7443 buf = wmi_buf_alloc(wmi_handle, len); 7444 if (!buf) 7445 return QDF_STATUS_E_FAILURE; 7446 7447 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 7448 WMITLV_SET_HDR(&cmd->tlv_header, 7449 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 7450 WMITLV_GET_STRUCT_TLVLEN( 7451 wmi_vdev_spectral_configure_cmd_fixed_param)); 7452 7453 cmd->vdev_id = param->vdev_id; 7454 cmd->spectral_scan_count = param->count; 7455 cmd->spectral_scan_period = param->period; 7456 cmd->spectral_scan_priority = param->spectral_pri; 7457 cmd->spectral_scan_fft_size = param->fft_size; 7458 cmd->spectral_scan_gc_ena = param->gc_enable; 7459 cmd->spectral_scan_restart_ena = param->restart_enable; 7460 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 7461 cmd->spectral_scan_init_delay = param->init_delay; 7462 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 7463 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 7464 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 7465 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 7466 cmd->spectral_scan_rssi_thr = param->rssi_thr; 7467 cmd->spectral_scan_pwr_format = param->pwr_format; 7468 cmd->spectral_scan_rpt_mode = param->rpt_mode; 7469 cmd->spectral_scan_bin_scale = param->bin_scale; 7470 cmd->spectral_scan_dBm_adj = param->dbm_adj; 7471 cmd->spectral_scan_chn_mask = param->chn_mask; 7472 cmd->spectral_scan_mode = param->mode; 7473 cmd->spectral_scan_center_freq1 = param->center_freq1; 7474 cmd->spectral_scan_center_freq2 = param->center_freq2; 7475 cmd->spectral_scan_chan_width = param->chan_width; 7476 cmd->recapture_sample_on_gain_change = param->fft_recap; 7477 /* Not used, fill with zeros */ 7478 cmd->spectral_scan_chan_freq = 0; 7479 7480 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 7481 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7482 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 7483 7484 if (ret != 0) { 7485 wmi_err("Sending set quiet cmd failed"); 7486 wmi_buf_free(buf); 7487 } 7488 7489 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 7490 wmi_debug("vdev_id: %u spectral_scan_count: %u", 7491 param->vdev_id, param->count); 7492 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 7493 param->period, param->spectral_pri); 7494 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 7495 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 7496 param->fft_size, param->gc_enable); 7497 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 7498 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 7499 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 7500 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 7501 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 7502 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 7503 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 7504 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 7505 param->rssi_thr, param->pwr_format); 7506 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 7507 param->rpt_mode, param->bin_scale); 7508 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 7509 param->dbm_adj, param->chn_mask); 7510 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 7511 param->mode, param->center_freq1); 7512 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 7513 param->center_freq2, param->chan_freq); 7514 wmi_debug("spectral_scan_chan_width: %u Status: %d", 7515 param->chan_width, ret); 7516 7517 return ret; 7518 } 7519 7520 /** 7521 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 7522 * command to fw 7523 * @wmi_handle: wmi handle 7524 * @param: pointer to hold spectral enable parameter 7525 * 7526 * Return: 0 for success or error code 7527 */ 7528 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 7529 struct vdev_spectral_enable_params *param) 7530 { 7531 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 7532 wmi_buf_t buf; 7533 QDF_STATUS ret; 7534 int32_t len; 7535 7536 len = sizeof(*cmd); 7537 buf = wmi_buf_alloc(wmi_handle, len); 7538 if (!buf) 7539 return QDF_STATUS_E_FAILURE; 7540 7541 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 7542 WMITLV_SET_HDR(&cmd->tlv_header, 7543 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 7544 WMITLV_GET_STRUCT_TLVLEN( 7545 wmi_vdev_spectral_enable_cmd_fixed_param)); 7546 7547 cmd->vdev_id = param->vdev_id; 7548 7549 if (param->active_valid) { 7550 cmd->trigger_cmd = param->active ? 1 : 2; 7551 /* 1: Trigger, 2: Clear Trigger */ 7552 } else { 7553 cmd->trigger_cmd = 0; /* 0: Ignore */ 7554 } 7555 7556 if (param->enabled_valid) { 7557 cmd->enable_cmd = param->enabled ? 1 : 2; 7558 /* 1: Enable 2: Disable */ 7559 } else { 7560 cmd->enable_cmd = 0; /* 0: Ignore */ 7561 } 7562 cmd->spectral_scan_mode = param->mode; 7563 7564 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 7565 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 7566 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 7567 7568 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 7569 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7570 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 7571 7572 if (ret != 0) { 7573 wmi_err("Sending scan enable CMD failed"); 7574 wmi_buf_free(buf); 7575 } 7576 7577 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 7578 ret); 7579 7580 return ret; 7581 } 7582 7583 #ifdef WLAN_CONV_SPECTRAL_ENABLE 7584 static QDF_STATUS 7585 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 7586 wmi_unified_t wmi_handle, 7587 uint8_t *event, struct spectral_startscan_resp_params *param) 7588 { 7589 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7590 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 7591 7592 if (!wmi_handle) { 7593 wmi_err("WMI handle is null"); 7594 return QDF_STATUS_E_INVAL; 7595 } 7596 7597 if (!event) { 7598 wmi_err("WMI event is null"); 7599 return QDF_STATUS_E_INVAL; 7600 } 7601 7602 if (!param) { 7603 wmi_err("Spectral startscan response params is null"); 7604 return QDF_STATUS_E_INVAL; 7605 } 7606 7607 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7608 if (!param_buf) 7609 return QDF_STATUS_E_INVAL; 7610 7611 ev = param_buf->fixed_param; 7612 if (!ev) 7613 return QDF_STATUS_E_INVAL; 7614 7615 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 7616 wmi_handle, 7617 ev->pdev_id); 7618 param->smode = ev->spectral_scan_mode; 7619 param->num_fft_bin_index = param_buf->num_fft_bin_index; 7620 param->num_det_info = param_buf->num_det_info; 7621 7622 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 7623 ev->pdev_id, ev->spectral_scan_mode, 7624 param_buf->num_fft_bin_index, param_buf->num_det_info); 7625 7626 return QDF_STATUS_SUCCESS; 7627 } 7628 7629 static QDF_STATUS 7630 extract_pdev_sscan_fft_bin_index_tlv( 7631 wmi_unified_t wmi_handle, uint8_t *event, 7632 struct spectral_fft_bin_markers_160_165mhz *param) 7633 { 7634 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7635 wmi_pdev_sscan_fft_bin_index *ev; 7636 7637 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7638 if (!param_buf) 7639 return QDF_STATUS_E_INVAL; 7640 7641 ev = param_buf->fft_bin_index; 7642 if (!ev) 7643 return QDF_STATUS_E_INVAL; 7644 7645 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 7646 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 7647 param->start_pri80 + 1; 7648 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 7649 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 7650 param->start_sec80 + 1; 7651 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 7652 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 7653 param->start_5mhz + 1; 7654 param->is_valid = true; 7655 7656 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 7657 param->start_pri80, param->num_pri80, 7658 param->start_sec80, param->num_sec80, 7659 param->start_5mhz, param->num_5mhz); 7660 7661 return QDF_STATUS_SUCCESS; 7662 } 7663 7664 /** 7665 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 7666 * for a spectral scan session 7667 * @wmi_handle: handle to WMI. 7668 * @event: Event buffer 7669 * @chan_info: Spectral session channel information data structure to be filled 7670 * by this API 7671 * 7672 * Return: QDF_STATUS of operation 7673 */ 7674 static QDF_STATUS 7675 extract_pdev_spectral_session_chan_info_tlv( 7676 wmi_unified_t wmi_handle, void *event, 7677 struct spectral_session_chan_info *chan_info) 7678 { 7679 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 7680 wmi_pdev_sscan_chan_info *chan_info_tlv; 7681 7682 if (!param_buf) { 7683 wmi_err("param_buf is NULL"); 7684 return QDF_STATUS_E_NULL_VALUE; 7685 } 7686 7687 if (!chan_info) { 7688 wmi_err("chan_info is NULL"); 7689 return QDF_STATUS_E_NULL_VALUE; 7690 } 7691 7692 chan_info_tlv = param_buf->chan_info; 7693 if (!chan_info_tlv) { 7694 wmi_err("chan_info tlv is not present in the event"); 7695 return QDF_STATUS_E_NULL_VALUE; 7696 } 7697 7698 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 7699 "operating_cfreq2:%u operating_bw:%u" 7700 "operating_puncture_20mhz_bitmap:%u" 7701 "sscan_cfreq1:%u sscan_cfreq2:%u" 7702 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 7703 chan_info_tlv->operating_pri20_freq, 7704 chan_info_tlv->operating_cfreq1, 7705 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 7706 chan_info_tlv->operating_puncture_20mhz_bitmap, 7707 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 7708 chan_info_tlv->sscan_bw, 7709 chan_info_tlv->sscan_puncture_20mhz_bitmap); 7710 7711 chan_info->operating_pri20_freq = 7712 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 7713 chan_info->operating_cfreq1 = 7714 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 7715 chan_info->operating_cfreq2 = 7716 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 7717 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 7718 chan_info->operating_puncture_20mhz_bitmap = 7719 chan_info_tlv->operating_puncture_20mhz_bitmap; 7720 7721 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 7722 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 7723 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 7724 chan_info->sscan_puncture_20mhz_bitmap = 7725 chan_info_tlv->sscan_puncture_20mhz_bitmap; 7726 7727 return QDF_STATUS_SUCCESS; 7728 } 7729 7730 static QDF_STATUS 7731 extract_pdev_spectral_session_detector_info_tlv( 7732 wmi_unified_t wmi_handle, void *event, 7733 struct spectral_session_det_info *det_info, uint8_t idx) 7734 { 7735 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 7736 wmi_pdev_sscan_per_detector_info *det_info_tlv; 7737 7738 if (!param_buf) { 7739 wmi_err("param_buf is NULL"); 7740 return QDF_STATUS_E_NULL_VALUE; 7741 } 7742 7743 if (!det_info) { 7744 wmi_err("chan_info is NULL"); 7745 return QDF_STATUS_E_NULL_VALUE; 7746 } 7747 7748 if (!param_buf->det_info) { 7749 wmi_err("det_info tlv is not present in the event"); 7750 return QDF_STATUS_E_NULL_VALUE; 7751 } 7752 7753 if (idx >= param_buf->num_det_info) { 7754 wmi_err("det_info index(%u) is greater than or equal to %u", 7755 idx, param_buf->num_det_info); 7756 return QDF_STATUS_E_FAILURE; 7757 } 7758 7759 det_info_tlv = ¶m_buf->det_info[idx]; 7760 7761 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 7762 idx, det_info_tlv->detector_id, 7763 det_info_tlv->start_freq, det_info_tlv->end_freq); 7764 7765 det_info->det_id = det_info_tlv->detector_id; 7766 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 7767 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 7768 7769 return QDF_STATUS_SUCCESS; 7770 } 7771 7772 /** 7773 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 7774 * capabilities WMI event 7775 * @wmi_handle: handle to WMI. 7776 * @event: Event buffer 7777 * @param: Spectral capabilities event parameters data structure to be filled 7778 * by this API 7779 * 7780 * Return: QDF_STATUS of operation 7781 */ 7782 static QDF_STATUS 7783 extract_spectral_caps_fixed_param_tlv( 7784 wmi_unified_t wmi_handle, void *event, 7785 struct spectral_capabilities_event_params *params) 7786 { 7787 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 7788 7789 if (!param_buf) { 7790 wmi_err("param_buf is NULL"); 7791 return QDF_STATUS_E_NULL_VALUE; 7792 } 7793 7794 if (!params) { 7795 wmi_err("event parameters is NULL"); 7796 return QDF_STATUS_E_NULL_VALUE; 7797 } 7798 7799 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 7800 params->num_fft_size_caps = param_buf->num_fft_size_caps; 7801 7802 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 7803 params->num_sscan_bw_caps, params->num_fft_size_caps); 7804 7805 return QDF_STATUS_SUCCESS; 7806 } 7807 7808 /** 7809 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 7810 * Spectral capabilities WMI event 7811 * @wmi_handle: handle to WMI. 7812 * @event: Event buffer 7813 * @bw_caps: Data structure to be populated by this API after extraction 7814 * 7815 * Return: QDF_STATUS of operation 7816 */ 7817 static QDF_STATUS 7818 extract_spectral_scan_bw_caps_tlv( 7819 wmi_unified_t wmi_handle, void *event, 7820 struct spectral_scan_bw_capabilities *bw_caps) 7821 { 7822 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 7823 int idx; 7824 7825 if (!param_buf) { 7826 wmi_err("param_buf is NULL"); 7827 return QDF_STATUS_E_NULL_VALUE; 7828 } 7829 7830 if (!bw_caps) { 7831 wmi_err("bw_caps is null"); 7832 return QDF_STATUS_E_NULL_VALUE; 7833 } 7834 7835 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 7836 bw_caps[idx].pdev_id = 7837 wmi_handle->ops->convert_pdev_id_target_to_host( 7838 wmi_handle, 7839 param_buf->sscan_bw_caps[idx].pdev_id); 7840 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 7841 bw_caps[idx].operating_bw = wmi_map_ch_width( 7842 param_buf->sscan_bw_caps[idx].operating_bw); 7843 bw_caps[idx].supported_bws = 7844 param_buf->sscan_bw_caps[idx].supported_flags; 7845 7846 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 7847 "operating_bw:%u supported_flags:0x%x", 7848 idx, param_buf->sscan_bw_caps[idx].pdev_id, 7849 param_buf->sscan_bw_caps[idx].sscan_mode, 7850 param_buf->sscan_bw_caps[idx].operating_bw, 7851 param_buf->sscan_bw_caps[idx].supported_flags); 7852 } 7853 7854 return QDF_STATUS_SUCCESS; 7855 } 7856 7857 /** 7858 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 7859 * Spectral capabilities WMI event 7860 * @wmi_handle: handle to WMI. 7861 * @event: Event buffer 7862 * @fft_size_caps: Data structure to be populated by this API after extraction 7863 * 7864 * Return: QDF_STATUS of operation 7865 */ 7866 static QDF_STATUS 7867 extract_spectral_fft_size_caps_tlv( 7868 wmi_unified_t wmi_handle, void *event, 7869 struct spectral_fft_size_capabilities *fft_size_caps) 7870 { 7871 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 7872 int idx; 7873 7874 if (!param_buf) { 7875 wmi_err("param_buf is NULL"); 7876 return QDF_STATUS_E_NULL_VALUE; 7877 } 7878 7879 if (!fft_size_caps) { 7880 wmi_err("fft size caps is NULL"); 7881 return QDF_STATUS_E_NULL_VALUE; 7882 } 7883 7884 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 7885 fft_size_caps[idx].pdev_id = 7886 wmi_handle->ops->convert_pdev_id_target_to_host( 7887 wmi_handle, 7888 param_buf->fft_size_caps[idx].pdev_id); 7889 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 7890 param_buf->fft_size_caps[idx].sscan_bw); 7891 fft_size_caps[idx].supports_fft_sizes = 7892 param_buf->sscan_bw_caps[idx].supported_flags; 7893 7894 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 7895 "supported_flags:0x%x", 7896 idx, param_buf->sscan_bw_caps[idx].pdev_id, 7897 param_buf->fft_size_caps[idx].sscan_bw, 7898 param_buf->sscan_bw_caps[idx].supported_flags); 7899 } 7900 7901 return QDF_STATUS_SUCCESS; 7902 } 7903 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 7904 7905 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 7906 static inline void 7907 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 7908 struct thermal_mitigation_params *param) 7909 { 7910 tt_conf->client_id = param->client_id; 7911 tt_conf->priority = param->priority; 7912 } 7913 #else 7914 static inline void 7915 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 7916 struct thermal_mitigation_params *param) 7917 { 7918 } 7919 #endif 7920 7921 /** 7922 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 7923 * @param wmi_handle : handle to WMI. 7924 * @param param : pointer to hold thermal mitigation param 7925 * 7926 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7927 */ 7928 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 7929 wmi_unified_t wmi_handle, 7930 struct thermal_mitigation_params *param) 7931 { 7932 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 7933 wmi_therm_throt_level_config_info *lvl_conf = NULL; 7934 wmi_buf_t buf = NULL; 7935 uint8_t *buf_ptr = NULL; 7936 int error; 7937 int32_t len; 7938 int i; 7939 7940 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 7941 param->num_thermal_conf * 7942 sizeof(wmi_therm_throt_level_config_info); 7943 7944 buf = wmi_buf_alloc(wmi_handle, len); 7945 if (!buf) 7946 return QDF_STATUS_E_NOMEM; 7947 7948 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 7949 7950 /* init fixed params */ 7951 WMITLV_SET_HDR(tt_conf, 7952 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 7953 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 7954 7955 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7956 wmi_handle, 7957 param->pdev_id); 7958 tt_conf->enable = param->enable; 7959 tt_conf->dc = param->dc; 7960 tt_conf->dc_per_event = param->dc_per_event; 7961 tt_conf->therm_throt_levels = param->num_thermal_conf; 7962 wmi_fill_client_id_priority(tt_conf, param); 7963 buf_ptr = (uint8_t *) ++tt_conf; 7964 /* init TLV params */ 7965 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7966 (param->num_thermal_conf * 7967 sizeof(wmi_therm_throt_level_config_info))); 7968 7969 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 7970 for (i = 0; i < param->num_thermal_conf; i++) { 7971 WMITLV_SET_HDR(&lvl_conf->tlv_header, 7972 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 7973 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 7974 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 7975 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 7976 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 7977 lvl_conf->prio = param->levelconf[i].priority; 7978 lvl_conf++; 7979 } 7980 7981 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 7982 error = wmi_unified_cmd_send(wmi_handle, buf, len, 7983 WMI_THERM_THROT_SET_CONF_CMDID); 7984 if (QDF_IS_STATUS_ERROR(error)) { 7985 wmi_buf_free(buf); 7986 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 7987 } 7988 7989 return error; 7990 } 7991 7992 /** 7993 * send_coex_config_cmd_tlv() - send coex config command to fw 7994 * @wmi_handle: wmi handle 7995 * @param: pointer to coex config param 7996 * 7997 * Return: 0 for success or error code 7998 */ 7999 static QDF_STATUS 8000 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8001 struct coex_config_params *param) 8002 { 8003 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8004 wmi_buf_t buf; 8005 QDF_STATUS ret; 8006 int32_t len; 8007 8008 len = sizeof(*cmd); 8009 buf = wmi_buf_alloc(wmi_handle, len); 8010 if (!buf) 8011 return QDF_STATUS_E_FAILURE; 8012 8013 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8014 WMITLV_SET_HDR(&cmd->tlv_header, 8015 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8016 WMITLV_GET_STRUCT_TLVLEN( 8017 WMI_COEX_CONFIG_CMD_fixed_param)); 8018 8019 cmd->vdev_id = param->vdev_id; 8020 cmd->config_type = param->config_type; 8021 cmd->config_arg1 = param->config_arg1; 8022 cmd->config_arg2 = param->config_arg2; 8023 cmd->config_arg3 = param->config_arg3; 8024 cmd->config_arg4 = param->config_arg4; 8025 cmd->config_arg5 = param->config_arg5; 8026 cmd->config_arg6 = param->config_arg6; 8027 8028 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8029 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8030 WMI_COEX_CONFIG_CMDID); 8031 8032 if (ret != 0) { 8033 wmi_err("Sending COEX CONFIG CMD failed"); 8034 wmi_buf_free(buf); 8035 } 8036 8037 return ret; 8038 } 8039 8040 #ifdef WLAN_SUPPORT_TWT 8041 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8042 target_resource_config *tgt_res_cfg) 8043 { 8044 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8045 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8046 } 8047 #else 8048 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8049 target_resource_config *tgt_res_cfg) 8050 { 8051 resource_cfg->twt_ap_pdev_count = 0; 8052 resource_cfg->twt_ap_sta_count = 0; 8053 } 8054 #endif 8055 8056 #ifdef WLAN_FEATURE_NAN 8057 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8058 { 8059 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8060 resource_cfg->host_service_flags, 1); 8061 } 8062 #else 8063 static inline 8064 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8065 { 8066 } 8067 #endif 8068 8069 #if defined(CONFIG_AFC_SUPPORT) 8070 static 8071 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8072 target_resource_config *tgt_res_cfg) 8073 { 8074 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8075 resource_cfg->host_service_flags, 8076 tgt_res_cfg->afc_indoor_support); 8077 8078 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8079 resource_cfg->host_service_flags, 8080 tgt_res_cfg->afc_outdoor_support); 8081 } 8082 #else 8083 static 8084 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8085 target_resource_config *tgt_res_cfg) 8086 { 8087 } 8088 #endif 8089 8090 static 8091 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8092 target_resource_config *tgt_res_cfg) 8093 { 8094 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 8095 resource_cfg->num_peers = tgt_res_cfg->num_peers; 8096 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 8097 resource_cfg->num_offload_reorder_buffs = 8098 tgt_res_cfg->num_offload_reorder_buffs; 8099 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 8100 resource_cfg->num_tids = tgt_res_cfg->num_tids; 8101 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 8102 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 8103 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 8104 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 8105 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 8106 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 8107 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 8108 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 8109 resource_cfg->scan_max_pending_req = 8110 tgt_res_cfg->scan_max_pending_req; 8111 resource_cfg->bmiss_offload_max_vdev = 8112 tgt_res_cfg->bmiss_offload_max_vdev; 8113 resource_cfg->roam_offload_max_vdev = 8114 tgt_res_cfg->roam_offload_max_vdev; 8115 resource_cfg->roam_offload_max_ap_profiles = 8116 tgt_res_cfg->roam_offload_max_ap_profiles; 8117 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 8118 resource_cfg->num_mcast_table_elems = 8119 tgt_res_cfg->num_mcast_table_elems; 8120 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 8121 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 8122 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 8123 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 8124 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 8125 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 8126 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 8127 resource_cfg->vow_config = tgt_res_cfg->vow_config; 8128 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 8129 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 8130 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 8131 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 8132 resource_cfg->num_tdls_conn_table_entries = 8133 tgt_res_cfg->num_tdls_conn_table_entries; 8134 resource_cfg->beacon_tx_offload_max_vdev = 8135 tgt_res_cfg->beacon_tx_offload_max_vdev; 8136 resource_cfg->num_multicast_filter_entries = 8137 tgt_res_cfg->num_multicast_filter_entries; 8138 resource_cfg->num_wow_filters = 8139 tgt_res_cfg->num_wow_filters; 8140 resource_cfg->num_keep_alive_pattern = 8141 tgt_res_cfg->num_keep_alive_pattern; 8142 resource_cfg->keep_alive_pattern_size = 8143 tgt_res_cfg->keep_alive_pattern_size; 8144 resource_cfg->max_tdls_concurrent_sleep_sta = 8145 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 8146 resource_cfg->max_tdls_concurrent_buffer_sta = 8147 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 8148 resource_cfg->wmi_send_separate = 8149 tgt_res_cfg->wmi_send_separate; 8150 resource_cfg->num_ocb_vdevs = 8151 tgt_res_cfg->num_ocb_vdevs; 8152 resource_cfg->num_ocb_channels = 8153 tgt_res_cfg->num_ocb_channels; 8154 resource_cfg->num_ocb_schedules = 8155 tgt_res_cfg->num_ocb_schedules; 8156 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 8157 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 8158 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 8159 resource_cfg->max_num_dbs_scan_duty_cycle = 8160 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 8161 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 8162 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 8163 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 8164 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 8165 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 8166 /* Deferred AI: Max rnr neighbors supported in multisoc case 8167 * where in SoC can support 6ghz. During WMI init of a SoC 8168 * currently there is no way to figure if another SOC is plugged in 8169 * and it can support 6Ghz. 8170 */ 8171 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 8172 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 8173 resource_cfg->ema_max_profile_period = 8174 tgt_res_cfg->ema_max_profile_period; 8175 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 8176 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 8177 8178 if (tgt_res_cfg->max_ndp_sessions) 8179 resource_cfg->max_ndp_sessions = 8180 tgt_res_cfg->max_ndp_sessions; 8181 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 8182 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 8183 8184 if (tgt_res_cfg->atf_config) 8185 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 8186 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 8187 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 8188 resource_cfg->flag1, 1); 8189 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 8190 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 8191 resource_cfg->flag1, 1); 8192 if (tgt_res_cfg->cce_disable) 8193 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 8194 if (tgt_res_cfg->enable_pci_gen) 8195 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 8196 resource_cfg->flag1, 1); 8197 if (tgt_res_cfg->eapol_minrate_set) { 8198 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 8199 resource_cfg->flag1, 1); 8200 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 8201 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 8202 resource_cfg->flag1, 1); 8203 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 8204 resource_cfg->flag1, 8205 tgt_res_cfg->eapol_minrate_ac_set); 8206 } 8207 } 8208 if (tgt_res_cfg->new_htt_msg_format) { 8209 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 8210 resource_cfg->flag1, 1); 8211 } 8212 8213 if (tgt_res_cfg->peer_unmap_conf_support) 8214 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 8215 resource_cfg->flag1, 1); 8216 8217 if (tgt_res_cfg->tstamp64_en) 8218 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 8219 resource_cfg->flag1, 1); 8220 8221 if (tgt_res_cfg->three_way_coex_config_legacy_en) 8222 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 8223 resource_cfg->flag1, 1); 8224 if (tgt_res_cfg->pktcapture_support) 8225 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 8226 resource_cfg->flag1, 1); 8227 8228 /* 8229 * Control padding using config param/ini of iphdr_pad_config 8230 */ 8231 if (tgt_res_cfg->iphdr_pad_config) 8232 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 8233 resource_cfg->flag1, 1); 8234 8235 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 8236 tgt_res_cfg->ipa_disable); 8237 8238 if (tgt_res_cfg->time_sync_ftm) 8239 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 8240 1); 8241 8242 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 8243 resource_cfg->peer_map_unmap_versions = 8244 tgt_res_cfg->peer_map_unmap_version; 8245 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 8246 if (tgt_res_cfg->re_ul_resp) 8247 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 8248 tgt_res_cfg->re_ul_resp); 8249 8250 /* 8251 * Enable Service Aware Wifi 8252 */ 8253 if (tgt_res_cfg->sawf) 8254 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 8255 tgt_res_cfg->sawf); 8256 8257 /* 8258 * Enable ast flow override per peer 8259 */ 8260 resource_cfg->msdu_flow_override_config0 = 0; 8261 WMI_MSDU_FLOW_AST_ENABLE_SET( 8262 resource_cfg->msdu_flow_override_config0, 8263 WMI_CONFIG_MSDU_AST_INDEX_1, 8264 tgt_res_cfg->ast_1_valid_mask_enable); 8265 8266 WMI_MSDU_FLOW_AST_ENABLE_SET( 8267 resource_cfg->msdu_flow_override_config0, 8268 WMI_CONFIG_MSDU_AST_INDEX_2, 8269 tgt_res_cfg->ast_2_valid_mask_enable); 8270 8271 WMI_MSDU_FLOW_AST_ENABLE_SET( 8272 resource_cfg->msdu_flow_override_config0, 8273 WMI_CONFIG_MSDU_AST_INDEX_3, 8274 tgt_res_cfg->ast_3_valid_mask_enable); 8275 8276 /* 8277 * Enable ast flow mask and TID valid mask configurations 8278 */ 8279 resource_cfg->msdu_flow_override_config1 = 0; 8280 8281 /*Enable UDP flow for Ast index 0*/ 8282 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8283 resource_cfg->msdu_flow_override_config1, 8284 WMI_CONFIG_MSDU_AST_INDEX_0, 8285 tgt_res_cfg->ast_0_flow_mask_enable); 8286 8287 /*Enable Non UDP flow for Ast index 1*/ 8288 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8289 resource_cfg->msdu_flow_override_config1, 8290 WMI_CONFIG_MSDU_AST_INDEX_1, 8291 tgt_res_cfg->ast_1_flow_mask_enable); 8292 8293 /*Enable Hi-Priority flow for Ast index 2*/ 8294 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8295 resource_cfg->msdu_flow_override_config1, 8296 WMI_CONFIG_MSDU_AST_INDEX_2, 8297 tgt_res_cfg->ast_2_flow_mask_enable); 8298 8299 /*Enable Low-Priority flow for Ast index 3*/ 8300 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 8301 resource_cfg->msdu_flow_override_config1, 8302 WMI_CONFIG_MSDU_AST_INDEX_3, 8303 tgt_res_cfg->ast_3_flow_mask_enable); 8304 8305 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 8306 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 8307 resource_cfg->msdu_flow_override_config1, 8308 tgt_res_cfg->ast_tid_high_mask_enable); 8309 8310 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 8311 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 8312 resource_cfg->msdu_flow_override_config1, 8313 tgt_res_cfg->ast_tid_low_mask_enable); 8314 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 8315 resource_cfg->host_service_flags, 8316 tgt_res_cfg->nan_separate_iface_support); 8317 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 8318 resource_cfg->host_service_flags, 1); 8319 8320 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 8321 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 8322 8323 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 8324 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 8325 resource_cfg->flags2, 1); 8326 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 8327 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 8328 resource_cfg->flags2, 1); 8329 8330 if (tgt_res_cfg->sae_eapol_offload) 8331 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 8332 resource_cfg->host_service_flags, 1); 8333 8334 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 8335 resource_cfg->host_service_flags, 8336 tgt_res_cfg->is_reg_cc_ext_event_supported); 8337 8338 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 8339 resource_cfg->host_service_flags, 8340 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 8341 8342 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 8343 resource_cfg->host_service_flags, 8344 tgt_res_cfg->afc_timer_check_disable); 8345 8346 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 8347 resource_cfg->host_service_flags, 8348 tgt_res_cfg->afc_req_id_check_disable); 8349 8350 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 8351 8352 wmi_set_nan_channel_support(resource_cfg); 8353 8354 if (tgt_res_cfg->twt_ack_support_cap) 8355 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 8356 resource_cfg->host_service_flags, 1); 8357 8358 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 8359 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 8360 resource_cfg->host_service_flags, 1); 8361 8362 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 8363 tgt_res_cfg->target_cap_flags); 8364 if (tgt_res_cfg->notify_frame_support) 8365 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 8366 resource_cfg->flags2, 1); 8367 8368 } 8369 8370 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 8371 * @wmi_handle: pointer to wmi handle 8372 * @buf_ptr: pointer to current position in init command buffer 8373 * @len: pointer to length. This will be updated with current length of cmd 8374 * @param: point host parameters for init command 8375 * 8376 * Return: Updated pointer of buf_ptr. 8377 */ 8378 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 8379 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 8380 { 8381 uint16_t idx; 8382 8383 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 8384 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 8385 wmi_pdev_band_to_mac *band_to_mac; 8386 8387 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 8388 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 8389 sizeof(wmi_resource_config) + 8390 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 8391 sizeof(wlan_host_memory_chunk))); 8392 8393 WMITLV_SET_HDR(&hw_mode->tlv_header, 8394 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 8395 (WMITLV_GET_STRUCT_TLVLEN 8396 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 8397 8398 hw_mode->hw_mode_index = param->hw_mode_id; 8399 hw_mode->num_band_to_mac = param->num_band_to_mac; 8400 8401 buf_ptr = (uint8_t *) (hw_mode + 1); 8402 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 8403 WMI_TLV_HDR_SIZE); 8404 for (idx = 0; idx < param->num_band_to_mac; idx++) { 8405 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 8406 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 8407 WMITLV_GET_STRUCT_TLVLEN 8408 (wmi_pdev_band_to_mac)); 8409 band_to_mac[idx].pdev_id = 8410 wmi_handle->ops->convert_pdev_id_host_to_target( 8411 wmi_handle, 8412 param->band_to_mac[idx].pdev_id); 8413 band_to_mac[idx].start_freq = 8414 param->band_to_mac[idx].start_freq; 8415 band_to_mac[idx].end_freq = 8416 param->band_to_mac[idx].end_freq; 8417 } 8418 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 8419 (param->num_band_to_mac * 8420 sizeof(wmi_pdev_band_to_mac)) + 8421 WMI_TLV_HDR_SIZE; 8422 8423 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8424 (param->num_band_to_mac * 8425 sizeof(wmi_pdev_band_to_mac))); 8426 } 8427 8428 return buf_ptr; 8429 } 8430 8431 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 8432 wmi_init_cmd_fixed_param *cmd) 8433 { 8434 int num_allowlist; 8435 wmi_abi_version my_vers; 8436 8437 num_allowlist = sizeof(version_whitelist) / 8438 sizeof(wmi_whitelist_version_info); 8439 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 8440 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 8441 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 8442 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 8443 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 8444 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 8445 8446 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 8447 &my_vers, 8448 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 8449 &cmd->host_abi_vers); 8450 8451 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 8452 __func__, 8453 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 8454 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 8455 cmd->host_abi_vers.abi_version_ns_0, 8456 cmd->host_abi_vers.abi_version_ns_1, 8457 cmd->host_abi_vers.abi_version_ns_2, 8458 cmd->host_abi_vers.abi_version_ns_3); 8459 8460 /* Save version sent from host - 8461 * Will be used to check ready event 8462 */ 8463 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 8464 sizeof(wmi_abi_version)); 8465 } 8466 8467 /* 8468 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 8469 * @wmi_handle: Pointer to WMi handle 8470 * @ie_data: Pointer for ie data 8471 * 8472 * This function sends action frame tb ppdu cfg to FW 8473 * 8474 * Return: QDF_STATUS_SUCCESS for success otherwise failure 8475 * 8476 */ 8477 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 8478 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 8479 { 8480 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 8481 wmi_buf_t buf; 8482 uint8_t *buf_ptr; 8483 uint32_t len, frm_len_aligned; 8484 QDF_STATUS ret; 8485 8486 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 8487 /* Allocate memory for the WMI command */ 8488 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 8489 8490 buf = wmi_buf_alloc(wmi_handle, len); 8491 if (!buf) 8492 return QDF_STATUS_E_NOMEM; 8493 8494 buf_ptr = wmi_buf_data(buf); 8495 qdf_mem_zero(buf_ptr, len); 8496 8497 /* Populate the WMI command */ 8498 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 8499 8500 WMITLV_SET_HDR(&cmd->tlv_header, 8501 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 8502 WMITLV_GET_STRUCT_TLVLEN( 8503 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 8504 cmd->enable = cfg_msg->cfg; 8505 cmd->data_len = cfg_msg->frm_len; 8506 8507 buf_ptr += sizeof(*cmd); 8508 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 8509 buf_ptr += WMI_TLV_HDR_SIZE; 8510 8511 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 8512 8513 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8514 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 8515 if (QDF_IS_STATUS_ERROR(ret)) { 8516 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 8517 wmi_buf_free(buf); 8518 } 8519 8520 return ret; 8521 } 8522 8523 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 8524 { 8525 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 8526 wmi_service_ready_event_fixed_param *ev; 8527 8528 8529 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 8530 8531 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 8532 if (!ev) 8533 return QDF_STATUS_E_FAILURE; 8534 8535 /*Save fw version from service ready message */ 8536 /*This will be used while sending INIT message */ 8537 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 8538 sizeof(wmi_handle->fw_abi_version)); 8539 8540 return QDF_STATUS_SUCCESS; 8541 } 8542 8543 /** 8544 * wmi_unified_save_fw_version_cmd() - save fw version 8545 * @wmi_handle: pointer to wmi handle 8546 * @res_cfg: resource config 8547 * @num_mem_chunks: no of mem chunck 8548 * @mem_chunk: pointer to mem chunck structure 8549 * 8550 * This function sends IE information to firmware 8551 * 8552 * Return: QDF_STATUS_SUCCESS for success otherwise failure 8553 * 8554 */ 8555 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 8556 void *evt_buf) 8557 { 8558 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 8559 wmi_ready_event_fixed_param *ev = NULL; 8560 8561 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 8562 ev = param_buf->fixed_param; 8563 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 8564 &wmi_handle->final_abi_vers, 8565 &ev->fw_abi_vers)) { 8566 /* 8567 * Error: Our host version and the given firmware version 8568 * are incompatible. 8569 **/ 8570 wmi_debug("Error: Incompatible WMI version." 8571 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 8572 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 8573 abi_version_0), 8574 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 8575 abi_version_0), 8576 wmi_handle->final_abi_vers.abi_version_ns_0, 8577 wmi_handle->final_abi_vers.abi_version_ns_1, 8578 wmi_handle->final_abi_vers.abi_version_ns_2, 8579 wmi_handle->final_abi_vers.abi_version_ns_3, 8580 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 8581 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 8582 ev->fw_abi_vers.abi_version_ns_0, 8583 ev->fw_abi_vers.abi_version_ns_1, 8584 ev->fw_abi_vers.abi_version_ns_2, 8585 ev->fw_abi_vers.abi_version_ns_3); 8586 8587 return QDF_STATUS_E_FAILURE; 8588 } 8589 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 8590 sizeof(wmi_abi_version)); 8591 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 8592 sizeof(wmi_abi_version)); 8593 8594 return QDF_STATUS_SUCCESS; 8595 } 8596 8597 /** 8598 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 8599 * @handle: wmi handle 8600 * @event: Event received from FW 8601 * @len: Length of the event 8602 * 8603 * Enables the low frequency events and disables the high frequency 8604 * events. Bit 17 indicates if the event if low/high frequency. 8605 * 1 - high frequency, 0 - low frequency 8606 * 8607 * Return: 0 on successfully enabling/disabling the events 8608 */ 8609 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 8610 uint8_t *event, 8611 uint32_t len) 8612 { 8613 uint32_t num_of_diag_events_logs; 8614 wmi_diag_event_log_config_fixed_param *cmd; 8615 wmi_buf_t buf; 8616 uint8_t *buf_ptr; 8617 uint32_t *cmd_args, *evt_args; 8618 uint32_t buf_len, i; 8619 8620 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 8621 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 8622 8623 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 8624 8625 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 8626 if (!param_buf) { 8627 wmi_err("Invalid log supported event buffer"); 8628 return QDF_STATUS_E_INVAL; 8629 } 8630 wmi_event = param_buf->fixed_param; 8631 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 8632 8633 if (num_of_diag_events_logs > 8634 param_buf->num_diag_events_logs_list) { 8635 wmi_err("message number of events %d is more than tlv hdr content %d", 8636 num_of_diag_events_logs, 8637 param_buf->num_diag_events_logs_list); 8638 return QDF_STATUS_E_INVAL; 8639 } 8640 8641 evt_args = param_buf->diag_events_logs_list; 8642 if (!evt_args) { 8643 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 8644 num_of_diag_events_logs); 8645 return QDF_STATUS_E_INVAL; 8646 } 8647 8648 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 8649 8650 /* Free any previous allocation */ 8651 if (wmi_handle->events_logs_list) { 8652 qdf_mem_free(wmi_handle->events_logs_list); 8653 wmi_handle->events_logs_list = NULL; 8654 } 8655 8656 if (num_of_diag_events_logs > 8657 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 8658 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 8659 QDF_ASSERT(0); 8660 return QDF_STATUS_E_INVAL; 8661 } 8662 /* Store the event list for run time enable/disable */ 8663 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 8664 sizeof(uint32_t)); 8665 if (!wmi_handle->events_logs_list) 8666 return QDF_STATUS_E_NOMEM; 8667 8668 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 8669 8670 /* Prepare the send buffer */ 8671 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8672 (num_of_diag_events_logs * sizeof(uint32_t)); 8673 8674 buf = wmi_buf_alloc(wmi_handle, buf_len); 8675 if (!buf) { 8676 qdf_mem_free(wmi_handle->events_logs_list); 8677 wmi_handle->events_logs_list = NULL; 8678 return QDF_STATUS_E_NOMEM; 8679 } 8680 8681 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8682 buf_ptr = (uint8_t *) cmd; 8683 8684 WMITLV_SET_HDR(&cmd->tlv_header, 8685 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8686 WMITLV_GET_STRUCT_TLVLEN( 8687 wmi_diag_event_log_config_fixed_param)); 8688 8689 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 8690 8691 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8692 8693 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8694 (num_of_diag_events_logs * sizeof(uint32_t))); 8695 8696 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8697 8698 /* Populate the events */ 8699 for (i = 0; i < num_of_diag_events_logs; i++) { 8700 /* Low freq (0) - Enable (1) the event 8701 * High freq (1) - Disable (0) the event 8702 */ 8703 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 8704 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 8705 /* Set the event ID */ 8706 WMI_DIAG_ID_SET(cmd_args[i], 8707 WMI_DIAG_ID_GET(evt_args[i])); 8708 /* Set the type */ 8709 WMI_DIAG_TYPE_SET(cmd_args[i], 8710 WMI_DIAG_TYPE_GET(evt_args[i])); 8711 /* Storing the event/log list in WMI */ 8712 wmi_handle->events_logs_list[i] = evt_args[i]; 8713 } 8714 8715 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 8716 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 8717 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 8718 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 8719 wmi_buf_free(buf); 8720 /* Not clearing events_logs_list, though wmi cmd failed. 8721 * Host can still have this list 8722 */ 8723 return QDF_STATUS_E_INVAL; 8724 } 8725 8726 return 0; 8727 } 8728 8729 /** 8730 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 8731 * @wmi_handle: wmi handle 8732 * @start_log: Start logging related parameters 8733 * 8734 * Send the command to the FW based on which specific logging of diag 8735 * event/log id can be started/stopped 8736 * 8737 * Return: None 8738 */ 8739 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 8740 struct wmi_wifi_start_log *start_log) 8741 { 8742 wmi_diag_event_log_config_fixed_param *cmd; 8743 wmi_buf_t buf; 8744 uint8_t *buf_ptr; 8745 uint32_t len, count, log_level, i; 8746 uint32_t *cmd_args; 8747 uint32_t total_len; 8748 count = 0; 8749 8750 if (!wmi_handle->events_logs_list) { 8751 wmi_debug("Not received event/log list from FW, yet"); 8752 return QDF_STATUS_E_NOMEM; 8753 } 8754 /* total_len stores the number of events where BITS 17 and 18 are set. 8755 * i.e., events of high frequency (17) and for extended debugging (18) 8756 */ 8757 total_len = 0; 8758 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8759 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 8760 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 8761 total_len++; 8762 } 8763 8764 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8765 (total_len * sizeof(uint32_t)); 8766 8767 buf = wmi_buf_alloc(wmi_handle, len); 8768 if (!buf) 8769 return QDF_STATUS_E_NOMEM; 8770 8771 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8772 buf_ptr = (uint8_t *) cmd; 8773 8774 WMITLV_SET_HDR(&cmd->tlv_header, 8775 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8776 WMITLV_GET_STRUCT_TLVLEN( 8777 wmi_diag_event_log_config_fixed_param)); 8778 8779 cmd->num_of_diag_events_logs = total_len; 8780 8781 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8782 8783 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8784 (total_len * sizeof(uint32_t))); 8785 8786 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8787 8788 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 8789 log_level = 1; 8790 else 8791 log_level = 0; 8792 8793 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 8794 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8795 uint32_t val = wmi_handle->events_logs_list[i]; 8796 if ((WMI_DIAG_FREQUENCY_GET(val)) && 8797 (WMI_DIAG_EXT_FEATURE_GET(val))) { 8798 8799 WMI_DIAG_ID_SET(cmd_args[count], 8800 WMI_DIAG_ID_GET(val)); 8801 WMI_DIAG_TYPE_SET(cmd_args[count], 8802 WMI_DIAG_TYPE_GET(val)); 8803 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 8804 log_level); 8805 wmi_debug("Idx:%d, val:%x", i, val); 8806 count++; 8807 } 8808 } 8809 8810 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 8811 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8812 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 8813 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 8814 wmi_buf_free(buf); 8815 return QDF_STATUS_E_INVAL; 8816 } 8817 8818 return QDF_STATUS_SUCCESS; 8819 } 8820 8821 /** 8822 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 8823 * @wmi_handle: WMI handle 8824 * 8825 * This function is used to send the flush command to the FW, 8826 * that will flush the fw logs that are residue in the FW 8827 * 8828 * Return: None 8829 */ 8830 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 8831 { 8832 wmi_debug_mesg_flush_fixed_param *cmd; 8833 wmi_buf_t buf; 8834 int len = sizeof(*cmd); 8835 QDF_STATUS ret; 8836 8837 buf = wmi_buf_alloc(wmi_handle, len); 8838 if (!buf) 8839 return QDF_STATUS_E_NOMEM; 8840 8841 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 8842 WMITLV_SET_HDR(&cmd->tlv_header, 8843 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 8844 WMITLV_GET_STRUCT_TLVLEN( 8845 wmi_debug_mesg_flush_fixed_param)); 8846 cmd->reserved0 = 0; 8847 8848 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 8849 ret = wmi_unified_cmd_send(wmi_handle, 8850 buf, 8851 len, 8852 WMI_DEBUG_MESG_FLUSH_CMDID); 8853 if (QDF_IS_STATUS_ERROR(ret)) { 8854 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 8855 wmi_buf_free(buf); 8856 return QDF_STATUS_E_INVAL; 8857 } 8858 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 8859 8860 return ret; 8861 } 8862 8863 #ifdef BIG_ENDIAN_HOST 8864 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 8865 /** 8866 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 8867 * @param - fips extend param related parameters 8868 * 8869 * Return: QDF_STATUS - success or error status 8870 */ 8871 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 8872 struct fips_extend_params *param) 8873 { 8874 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 8875 int c; 8876 u_int8_t *key_aligned = NULL; 8877 u_int8_t *nonce_iv_aligned = NULL; 8878 u_int8_t *data_aligned = NULL; 8879 int ret = QDF_STATUS_SUCCESS; 8880 8881 /* Assigning unaligned space to copy the key */ 8882 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 8883 param->cmd_params.key_len + FIPS_ALIGN); 8884 /* Checking if kmalloc is successful to allocate space */ 8885 if (!key_unaligned) 8886 return QDF_STATUS_E_INVAL; 8887 8888 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 8889 FIPS_ALIGN); 8890 /* Checking if kmalloc is successful to allocate space */ 8891 if (!data_unaligned) { 8892 ret = QDF_STATUS_E_INVAL; 8893 goto fips_align_fail_data; 8894 } 8895 8896 /* Checking if space is aligned */ 8897 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 8898 /* align to 4 */ 8899 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 8900 FIPS_ALIGN); 8901 } else { 8902 key_aligned = (u_int8_t *)key_unaligned; 8903 } 8904 8905 /* memset and copy content from key to key aligned */ 8906 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 8907 OS_MEMCPY(key_aligned, param->cmd_params.key, 8908 param->cmd_params.key_len); 8909 8910 /* print a hexdump for host debug */ 8911 wmi_debug("Aligned and Copied Key: "); 8912 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8913 key_aligned, param->cmd_params.key_len); 8914 8915 /* Checking of space is aligned */ 8916 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 8917 /* align to 4 */ 8918 data_aligned = 8919 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 8920 } else { 8921 data_aligned = (u_int8_t *)data_unaligned; 8922 } 8923 8924 /* memset and copy content from data to data aligned */ 8925 OS_MEMSET(data_aligned, 0, param->data_len); 8926 OS_MEMCPY(data_aligned, param->data, param->data_len); 8927 8928 /* print a hexdump for host debug */ 8929 wmi_debug("\t Properly Aligned and Copied Data: "); 8930 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8931 data_aligned, param->data_len); 8932 8933 /* converting to little Endian */ 8934 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 8935 *((u_int32_t *)key_aligned + c) = 8936 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 8937 } 8938 for (c = 0; c < param->data_len / 4; c++) { 8939 *((u_int32_t *)data_aligned + c) = 8940 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 8941 } 8942 8943 /* update endian data */ 8944 OS_MEMCPY(param->cmd_params.key, key_aligned, 8945 param->cmd_params.key_len); 8946 OS_MEMCPY(param->data, data_aligned, param->data_len); 8947 8948 if (param->cmd_params.nonce_iv_len) { 8949 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 8950 param->cmd_params.nonce_iv_len + 8951 FIPS_ALIGN); 8952 8953 /* Checking if kmalloc is successful to allocate space */ 8954 if (!nonce_iv_unaligned) { 8955 ret = QDF_STATUS_E_INVAL; 8956 goto fips_align_fail_nonce_iv; 8957 } 8958 /* Checking if space is aligned */ 8959 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 8960 /* align to 4 */ 8961 nonce_iv_aligned = 8962 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 8963 FIPS_ALIGN); 8964 } else { 8965 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 8966 } 8967 8968 /* memset and copy content from iv to iv aligned */ 8969 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 8970 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 8971 param->cmd_params.nonce_iv_len); 8972 8973 /* print a hexdump for host debug */ 8974 wmi_debug("\t Aligned and Copied Nonce_IV: "); 8975 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 8976 nonce_iv_aligned, 8977 param->cmd_params.nonce_iv_len); 8978 8979 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 8980 *((u_int32_t *)nonce_iv_aligned + c) = 8981 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 8982 } 8983 } 8984 8985 /* clean up allocated spaces */ 8986 qdf_mem_free(nonce_iv_unaligned); 8987 nonce_iv_unaligned = NULL; 8988 nonce_iv_aligned = NULL; 8989 8990 fips_align_fail_nonce_iv: 8991 qdf_mem_free(data_unaligned); 8992 data_unaligned = NULL; 8993 data_aligned = NULL; 8994 8995 fips_align_fail_data: 8996 qdf_mem_free(key_unaligned); 8997 key_unaligned = NULL; 8998 key_aligned = NULL; 8999 9000 return ret; 9001 } 9002 #endif 9003 9004 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 9005 struct fips_params *param) 9006 { 9007 unsigned char *key_unaligned, *data_unaligned; 9008 int c; 9009 u_int8_t *key_aligned = NULL; 9010 u_int8_t *data_aligned = NULL; 9011 9012 /* Assigning unaligned space to copy the key */ 9013 key_unaligned = qdf_mem_malloc( 9014 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 9015 data_unaligned = qdf_mem_malloc( 9016 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 9017 9018 /* Checking if kmalloc is successful to allocate space */ 9019 if (!key_unaligned) 9020 return QDF_STATUS_SUCCESS; 9021 /* Checking if space is aligned */ 9022 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9023 /* align to 4 */ 9024 key_aligned = 9025 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 9026 FIPS_ALIGN); 9027 } else { 9028 key_aligned = (u_int8_t *)key_unaligned; 9029 } 9030 9031 /* memset and copy content from key to key aligned */ 9032 OS_MEMSET(key_aligned, 0, param->key_len); 9033 OS_MEMCPY(key_aligned, param->key, param->key_len); 9034 9035 /* print a hexdump for host debug */ 9036 print_hex_dump(KERN_DEBUG, 9037 "\t Aligned and Copied Key:@@@@ ", 9038 DUMP_PREFIX_NONE, 9039 16, 1, key_aligned, param->key_len, true); 9040 9041 /* Checking if kmalloc is successful to allocate space */ 9042 if (!data_unaligned) 9043 return QDF_STATUS_SUCCESS; 9044 /* Checking of space is aligned */ 9045 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 9046 /* align to 4 */ 9047 data_aligned = 9048 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 9049 FIPS_ALIGN); 9050 } else { 9051 data_aligned = (u_int8_t *)data_unaligned; 9052 } 9053 9054 /* memset and copy content from data to data aligned */ 9055 OS_MEMSET(data_aligned, 0, param->data_len); 9056 OS_MEMCPY(data_aligned, param->data, param->data_len); 9057 9058 /* print a hexdump for host debug */ 9059 print_hex_dump(KERN_DEBUG, 9060 "\t Properly Aligned and Copied Data:@@@@ ", 9061 DUMP_PREFIX_NONE, 9062 16, 1, data_aligned, param->data_len, true); 9063 9064 /* converting to little Endian both key_aligned and 9065 * data_aligned*/ 9066 for (c = 0; c < param->key_len/4; c++) { 9067 *((u_int32_t *)key_aligned+c) = 9068 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 9069 } 9070 for (c = 0; c < param->data_len/4; c++) { 9071 *((u_int32_t *)data_aligned+c) = 9072 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 9073 } 9074 9075 /* update endian data to key and data vectors */ 9076 OS_MEMCPY(param->key, key_aligned, param->key_len); 9077 OS_MEMCPY(param->data, data_aligned, param->data_len); 9078 9079 /* clean up allocated spaces */ 9080 qdf_mem_free(key_unaligned); 9081 key_unaligned = NULL; 9082 key_aligned = NULL; 9083 9084 qdf_mem_free(data_unaligned); 9085 data_unaligned = NULL; 9086 data_aligned = NULL; 9087 9088 return QDF_STATUS_SUCCESS; 9089 } 9090 #else 9091 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9092 /** 9093 * fips_extend_align_data_be() - DUMMY for LE platform 9094 * 9095 * Return: QDF_STATUS - success 9096 */ 9097 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 9098 struct fips_extend_params *param) 9099 { 9100 return QDF_STATUS_SUCCESS; 9101 } 9102 #endif 9103 9104 /** 9105 * fips_align_data_be() - DUMMY for LE platform 9106 * 9107 * Return: QDF_STATUS - success 9108 */ 9109 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 9110 struct fips_params *param) 9111 { 9112 return QDF_STATUS_SUCCESS; 9113 } 9114 #endif 9115 9116 #ifdef WLAN_FEATURE_DISA 9117 /** 9118 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 9119 * @wmi_handle: wmi handle 9120 * @params: encrypt/decrypt params 9121 * 9122 * Return: QDF_STATUS_SUCCESS for success or error code 9123 */ 9124 static QDF_STATUS 9125 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 9126 struct disa_encrypt_decrypt_req_params 9127 *encrypt_decrypt_params) 9128 { 9129 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 9130 wmi_buf_t wmi_buf; 9131 uint8_t *buf_ptr; 9132 QDF_STATUS ret; 9133 uint32_t len; 9134 9135 wmi_debug("Send encrypt decrypt cmd"); 9136 9137 len = sizeof(*cmd) + 9138 encrypt_decrypt_params->data_len + 9139 WMI_TLV_HDR_SIZE; 9140 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9141 if (!wmi_buf) 9142 return QDF_STATUS_E_NOMEM; 9143 9144 buf_ptr = wmi_buf_data(wmi_buf); 9145 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 9146 9147 WMITLV_SET_HDR(&cmd->tlv_header, 9148 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 9149 WMITLV_GET_STRUCT_TLVLEN( 9150 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 9151 9152 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 9153 cmd->key_flag = encrypt_decrypt_params->key_flag; 9154 cmd->key_idx = encrypt_decrypt_params->key_idx; 9155 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 9156 cmd->key_len = encrypt_decrypt_params->key_len; 9157 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 9158 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 9159 9160 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 9161 encrypt_decrypt_params->key_len); 9162 9163 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 9164 MAX_MAC_HEADER_LEN); 9165 9166 cmd->data_len = encrypt_decrypt_params->data_len; 9167 9168 if (cmd->data_len) { 9169 buf_ptr += sizeof(*cmd); 9170 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 9171 roundup(encrypt_decrypt_params->data_len, 9172 sizeof(uint32_t))); 9173 buf_ptr += WMI_TLV_HDR_SIZE; 9174 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 9175 encrypt_decrypt_params->data_len); 9176 } 9177 9178 /* This conversion is to facilitate data to FW in little endian */ 9179 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 9180 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 9181 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 9182 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 9183 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 9184 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 9185 9186 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 9187 ret = wmi_unified_cmd_send(wmi_handle, 9188 wmi_buf, len, 9189 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 9190 if (QDF_IS_STATUS_ERROR(ret)) { 9191 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 9192 wmi_buf_free(wmi_buf); 9193 } 9194 9195 return ret; 9196 } 9197 #endif /* WLAN_FEATURE_DISA */ 9198 9199 /** 9200 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 9201 * @wmi_handle: wmi handle 9202 * @param: pointer to hold pdev fips param 9203 * 9204 * Return: 0 for success or error code 9205 */ 9206 static QDF_STATUS 9207 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 9208 struct fips_params *param) 9209 { 9210 wmi_pdev_fips_cmd_fixed_param *cmd; 9211 wmi_buf_t buf; 9212 uint8_t *buf_ptr; 9213 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 9214 QDF_STATUS retval = QDF_STATUS_SUCCESS; 9215 9216 /* Length TLV placeholder for array of bytes */ 9217 len += WMI_TLV_HDR_SIZE; 9218 if (param->data_len) 9219 len += (param->data_len*sizeof(uint8_t)); 9220 9221 /* 9222 * Data length must be multiples of 16 bytes - checked against 0xF - 9223 * and must be less than WMI_SVC_MSG_SIZE - static size of 9224 * wmi_pdev_fips_cmd structure 9225 */ 9226 9227 /* do sanity on the input */ 9228 if (!(((param->data_len & 0xF) == 0) && 9229 ((param->data_len > 0) && 9230 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 9231 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 9232 return QDF_STATUS_E_INVAL; 9233 } 9234 9235 buf = wmi_buf_alloc(wmi_handle, len); 9236 if (!buf) 9237 return QDF_STATUS_E_FAILURE; 9238 9239 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9240 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 9241 WMITLV_SET_HDR(&cmd->tlv_header, 9242 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 9243 WMITLV_GET_STRUCT_TLVLEN 9244 (wmi_pdev_fips_cmd_fixed_param)); 9245 9246 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9247 wmi_handle, 9248 param->pdev_id); 9249 if (param->key && param->data) { 9250 cmd->key_len = param->key_len; 9251 cmd->data_len = param->data_len; 9252 cmd->fips_cmd = !!(param->op); 9253 9254 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 9255 return QDF_STATUS_E_FAILURE; 9256 9257 qdf_mem_copy(cmd->key, param->key, param->key_len); 9258 9259 if (param->mode == FIPS_ENGINE_AES_CTR || 9260 param->mode == FIPS_ENGINE_AES_MIC) { 9261 cmd->mode = param->mode; 9262 } else { 9263 cmd->mode = FIPS_ENGINE_AES_CTR; 9264 } 9265 qdf_print("Key len = %d, Data len = %d", 9266 cmd->key_len, cmd->data_len); 9267 9268 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 9269 cmd->key, cmd->key_len, true); 9270 buf_ptr += sizeof(*cmd); 9271 9272 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 9273 9274 buf_ptr += WMI_TLV_HDR_SIZE; 9275 if (param->data_len) 9276 qdf_mem_copy(buf_ptr, 9277 (uint8_t *) param->data, param->data_len); 9278 9279 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 9280 16, 1, buf_ptr, cmd->data_len, true); 9281 9282 buf_ptr += param->data_len; 9283 9284 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 9285 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 9286 WMI_PDEV_FIPS_CMDID); 9287 qdf_print("%s return value %d", __func__, retval); 9288 } else { 9289 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 9290 wmi_buf_free(buf); 9291 retval = -QDF_STATUS_E_BADMSG; 9292 } 9293 9294 return retval; 9295 } 9296 9297 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9298 /** 9299 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 9300 * @wmi_handle: wmi handle 9301 * @param: pointer to hold pdev fips param 9302 * 9303 * Return: 0 for success or error code 9304 */ 9305 static QDF_STATUS 9306 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 9307 struct fips_extend_params *param) 9308 { 9309 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 9310 wmi_buf_t buf; 9311 uint8_t *buf_ptr; 9312 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 9313 uint32_t data_len_aligned; 9314 QDF_STATUS retval = QDF_STATUS_SUCCESS; 9315 9316 len += WMI_TLV_HDR_SIZE; 9317 if (param->frag_idx == 0) 9318 len += sizeof(wmi_fips_extend_cmd_init_params); 9319 9320 /* Length TLV placeholder for array of bytes */ 9321 len += WMI_TLV_HDR_SIZE; 9322 if (param->data_len) { 9323 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 9324 len += (data_len_aligned * sizeof(uint8_t)); 9325 } 9326 9327 buf = wmi_buf_alloc(wmi_handle, len); 9328 if (!buf) 9329 return QDF_STATUS_E_FAILURE; 9330 9331 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9332 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 9333 WMITLV_SET_HDR(&cmd->tlv_header, 9334 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 9335 WMITLV_GET_STRUCT_TLVLEN 9336 (wmi_pdev_fips_extend_cmd_fixed_param)); 9337 9338 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9339 wmi_handle, 9340 param->pdev_id); 9341 9342 cmd->fips_cookie = param->cookie; 9343 cmd->frag_idx = param->frag_idx; 9344 cmd->more_bit = param->more_bit; 9345 cmd->data_len = param->data_len; 9346 9347 if (fips_extend_align_data_be(wmi_handle, param) != 9348 QDF_STATUS_SUCCESS) { 9349 wmi_buf_free(buf); 9350 return QDF_STATUS_E_FAILURE; 9351 } 9352 9353 buf_ptr = (uint8_t *)(cmd + 1); 9354 if (cmd->frag_idx == 0) { 9355 wmi_fips_extend_cmd_init_params *cmd_params; 9356 9357 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9358 sizeof(wmi_fips_extend_cmd_init_params)); 9359 buf_ptr += WMI_TLV_HDR_SIZE; 9360 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 9361 WMITLV_SET_HDR(buf_ptr, 9362 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 9363 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 9364 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 9365 cmd_params->key_cipher = param->cmd_params.key_cipher; 9366 cmd_params->key_len = param->cmd_params.key_len; 9367 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 9368 cmd_params->tag_len = param->cmd_params.tag_len; 9369 cmd_params->aad_len = param->cmd_params.aad_len; 9370 cmd_params->payload_len = param->cmd_params.payload_len; 9371 9372 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 9373 param->cmd_params.key_len); 9374 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 9375 param->cmd_params.nonce_iv_len); 9376 9377 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 9378 cmd_params->key_len, cmd_params->nonce_iv_len, 9379 cmd_params->tag_len, cmd_params->aad_len, 9380 cmd_params->payload_len); 9381 9382 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 9383 } else { 9384 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9385 buf_ptr += WMI_TLV_HDR_SIZE; 9386 } 9387 9388 if (param->data_len && param->data) { 9389 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 9390 data_len_aligned); 9391 9392 buf_ptr += WMI_TLV_HDR_SIZE; 9393 if (param->data_len) 9394 qdf_mem_copy(buf_ptr, 9395 (uint8_t *)param->data, param->data_len); 9396 9397 wmi_debug("Data: "); 9398 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9399 buf_ptr, cmd->data_len); 9400 9401 if (param->data_len) 9402 buf_ptr += param->data_len; 9403 } else { 9404 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 9405 buf_ptr += WMI_TLV_HDR_SIZE; 9406 } 9407 9408 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 9409 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 9410 WMI_PDEV_FIPS_EXTEND_CMDID); 9411 9412 if (retval) { 9413 wmi_err("Failed to send FIPS cmd"); 9414 wmi_buf_free(buf); 9415 } 9416 9417 return retval; 9418 } 9419 9420 /** 9421 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 9422 * @wmi_handle: wmi handle 9423 * @param: pointer to hold pdev fips param 9424 * 9425 * Return: 0 for success or error code 9426 */ 9427 static QDF_STATUS 9428 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 9429 struct fips_mode_set_params *param) 9430 { 9431 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 9432 wmi_buf_t buf; 9433 uint8_t *buf_ptr; 9434 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 9435 QDF_STATUS retval = QDF_STATUS_SUCCESS; 9436 9437 buf = wmi_buf_alloc(wmi_handle, len); 9438 if (!buf) 9439 return QDF_STATUS_E_FAILURE; 9440 9441 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9442 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 9443 WMITLV_SET_HDR(&cmd->tlv_header, 9444 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 9445 WMITLV_GET_STRUCT_TLVLEN 9446 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 9447 9448 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9449 wmi_handle, 9450 param->pdev_id); 9451 9452 cmd->fips_mode_set = param->mode; 9453 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 9454 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 9455 WMI_PDEV_FIPS_MODE_SET_CMDID); 9456 if (retval) { 9457 wmi_err("Failed to send FIPS mode enable cmd"); 9458 wmi_buf_free(buf); 9459 } 9460 return retval; 9461 } 9462 #endif 9463 9464 /** 9465 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 9466 * to fw 9467 * @wmi_handle: wmi handle 9468 * @param: pointer to wlan profile param 9469 * 9470 * Return: 0 for success or error code 9471 */ 9472 static QDF_STATUS 9473 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 9474 struct wlan_profile_params *param) 9475 { 9476 wmi_buf_t buf; 9477 uint16_t len; 9478 QDF_STATUS ret; 9479 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 9480 9481 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 9482 buf = wmi_buf_alloc(wmi_handle, len); 9483 if (!buf) { 9484 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 9485 return QDF_STATUS_E_NOMEM; 9486 } 9487 9488 profile_enable_cmd = 9489 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 9490 wmi_buf_data(buf); 9491 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 9492 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 9493 WMITLV_GET_STRUCT_TLVLEN 9494 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 9495 9496 profile_enable_cmd->profile_id = param->profile_id; 9497 profile_enable_cmd->enable = param->enable; 9498 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 9499 NO_SESSION, 0); 9500 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9501 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 9502 if (ret) { 9503 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 9504 wmi_buf_free(buf); 9505 } 9506 return ret; 9507 } 9508 9509 /** 9510 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 9511 * to fw 9512 * @wmi_handle: wmi handle 9513 * @param: pointer to wlan profile param 9514 * 9515 * Return: 0 for success or error code 9516 */ 9517 static QDF_STATUS 9518 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 9519 struct wlan_profile_params *param) 9520 { 9521 wmi_buf_t buf; 9522 uint16_t len; 9523 QDF_STATUS ret; 9524 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 9525 9526 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 9527 buf = wmi_buf_alloc(wmi_handle, len); 9528 if (!buf) { 9529 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 9530 return QDF_STATUS_E_NOMEM; 9531 } 9532 9533 prof_trig_cmd = 9534 (wmi_wlan_profile_trigger_cmd_fixed_param *) 9535 wmi_buf_data(buf); 9536 9537 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 9538 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 9539 WMITLV_GET_STRUCT_TLVLEN 9540 (wmi_wlan_profile_trigger_cmd_fixed_param)); 9541 9542 prof_trig_cmd->enable = param->enable; 9543 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 9544 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9545 WMI_WLAN_PROFILE_TRIGGER_CMDID); 9546 if (ret) { 9547 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 9548 wmi_buf_free(buf); 9549 } 9550 return ret; 9551 } 9552 9553 /** 9554 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 9555 * to fw 9556 * @wmi_handle: wmi handle 9557 * @param: pointer to wlan profile param 9558 * 9559 * Return: 0 for success or error code 9560 */ 9561 static QDF_STATUS 9562 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 9563 struct wlan_profile_params *param) 9564 { 9565 wmi_buf_t buf; 9566 int32_t len = 0; 9567 QDF_STATUS ret; 9568 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 9569 9570 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 9571 buf = wmi_buf_alloc(wmi_handle, len); 9572 if (!buf) { 9573 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 9574 return QDF_STATUS_E_NOMEM; 9575 } 9576 9577 hist_intvl_cmd = 9578 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 9579 wmi_buf_data(buf); 9580 9581 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 9582 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 9583 WMITLV_GET_STRUCT_TLVLEN 9584 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 9585 9586 hist_intvl_cmd->profile_id = param->profile_id; 9587 hist_intvl_cmd->value = param->enable; 9588 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 9589 NO_SESSION, 0); 9590 9591 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9592 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 9593 if (ret) { 9594 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 9595 wmi_buf_free(buf); 9596 } 9597 return ret; 9598 } 9599 9600 /** 9601 * send_fw_test_cmd_tlv() - send fw test command to fw. 9602 * @wmi_handle: wmi handle 9603 * @wmi_fwtest: fw test command 9604 * 9605 * This function sends fw test command to fw. 9606 * 9607 * Return: CDF STATUS 9608 */ 9609 static 9610 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 9611 struct set_fwtest_params *wmi_fwtest) 9612 { 9613 wmi_fwtest_set_param_cmd_fixed_param *cmd; 9614 wmi_buf_t wmi_buf; 9615 uint16_t len; 9616 9617 len = sizeof(*cmd); 9618 9619 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9620 if (!wmi_buf) 9621 return QDF_STATUS_E_NOMEM; 9622 9623 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 9624 WMITLV_SET_HDR(&cmd->tlv_header, 9625 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 9626 WMITLV_GET_STRUCT_TLVLEN( 9627 wmi_fwtest_set_param_cmd_fixed_param)); 9628 cmd->param_id = wmi_fwtest->arg; 9629 cmd->param_value = wmi_fwtest->value; 9630 9631 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 9632 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9633 WMI_FWTEST_CMDID)) { 9634 wmi_err("Failed to send fw test command"); 9635 wmi_buf_free(wmi_buf); 9636 return QDF_STATUS_E_FAILURE; 9637 } 9638 9639 return QDF_STATUS_SUCCESS; 9640 } 9641 9642 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 9643 { 9644 uint16_t len = 0; 9645 9646 if (config == WFA_CONFIG_RXNE) 9647 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 9648 else 9649 len += WMI_TLV_HDR_SIZE; 9650 9651 if (config == WFA_CONFIG_CSA) 9652 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 9653 else 9654 len += WMI_TLV_HDR_SIZE; 9655 9656 if (config == WFA_CONFIG_OCV) 9657 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 9658 else 9659 len += WMI_TLV_HDR_SIZE; 9660 9661 if (config == WFA_CONFIG_SA_QUERY) 9662 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 9663 else 9664 len += WMI_TLV_HDR_SIZE; 9665 9666 return len; 9667 } 9668 9669 /** 9670 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 9671 * @host_frmtype: Host defined OCV frame type 9672 * @ocv_frmtype: Pointer to hold WMI OCV frame type 9673 * 9674 * This function converts and fills host defined OCV frame type into WMI OCV 9675 * frame type. 9676 * 9677 * Return: CDF STATUS 9678 */ 9679 static QDF_STATUS 9680 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 9681 { 9682 switch (host_frmtype) { 9683 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 9684 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 9685 break; 9686 9687 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 9688 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 9689 break; 9690 9691 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 9692 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 9693 break; 9694 9695 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 9696 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 9697 break; 9698 9699 default: 9700 wmi_err("Invalid command type cmd %d", host_frmtype); 9701 return QDF_STATUS_E_FAILURE; 9702 } 9703 9704 return QDF_STATUS_SUCCESS; 9705 } 9706 9707 /** 9708 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 9709 * @wmi_handle: wmi handle 9710 * @wmi_wfatest: wfa test command 9711 * 9712 * This function sends wfa test command to fw. 9713 * 9714 * Return: CDF STATUS 9715 */ 9716 static 9717 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 9718 struct set_wfatest_params *wmi_wfatest) 9719 { 9720 wmi_wfa_config_cmd_fixed_param *cmd; 9721 wmi_wfa_config_rsnxe *rxne; 9722 wmi_wfa_config_csa *csa; 9723 wmi_wfa_config_ocv *ocv; 9724 wmi_wfa_config_saquery *saquery; 9725 wmi_buf_t wmi_buf; 9726 uint16_t len = sizeof(*cmd); 9727 uint8_t *buf_ptr; 9728 9729 len += wfa_config_param_len(wmi_wfatest->cmd); 9730 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9731 if (!wmi_buf) 9732 return QDF_STATUS_E_NOMEM; 9733 9734 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 9735 WMITLV_SET_HDR(&cmd->tlv_header, 9736 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 9737 WMITLV_GET_STRUCT_TLVLEN( 9738 wmi_wfa_config_cmd_fixed_param)); 9739 9740 cmd->vdev_id = wmi_wfatest->vdev_id; 9741 buf_ptr = (uint8_t *)(cmd + 1); 9742 9743 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 9744 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9745 sizeof(wmi_wfa_config_rsnxe)); 9746 buf_ptr += WMI_TLV_HDR_SIZE; 9747 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 9748 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 9749 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 9750 rxne->rsnxe_param = wmi_wfatest->value; 9751 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 9752 } else { 9753 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9754 buf_ptr += WMI_TLV_HDR_SIZE; 9755 } 9756 9757 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 9758 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9759 sizeof(wmi_wfa_config_csa)); 9760 buf_ptr += WMI_TLV_HDR_SIZE; 9761 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 9762 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 9763 csa = (wmi_wfa_config_csa *)buf_ptr; 9764 csa->ignore_csa = wmi_wfatest->value; 9765 buf_ptr += sizeof(wmi_wfa_config_csa); 9766 } else { 9767 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9768 buf_ptr += WMI_TLV_HDR_SIZE; 9769 } 9770 9771 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 9772 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9773 sizeof(wmi_wfa_config_ocv)); 9774 buf_ptr += WMI_TLV_HDR_SIZE; 9775 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 9776 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 9777 ocv = (wmi_wfa_config_ocv *)buf_ptr; 9778 9779 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 9780 &ocv->frame_types)) 9781 goto error; 9782 9783 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 9784 buf_ptr += sizeof(wmi_wfa_config_ocv); 9785 } else { 9786 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9787 buf_ptr += WMI_TLV_HDR_SIZE; 9788 } 9789 9790 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 9791 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9792 sizeof(wmi_wfa_config_saquery)); 9793 buf_ptr += WMI_TLV_HDR_SIZE; 9794 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 9795 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 9796 9797 saquery = (wmi_wfa_config_saquery *)buf_ptr; 9798 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 9799 } else { 9800 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 9801 buf_ptr += WMI_TLV_HDR_SIZE; 9802 } 9803 9804 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 9805 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9806 WMI_WFA_CONFIG_CMDID)) { 9807 wmi_err("Failed to send wfa test command"); 9808 goto error; 9809 } 9810 9811 return QDF_STATUS_SUCCESS; 9812 9813 error: 9814 wmi_buf_free(wmi_buf); 9815 return QDF_STATUS_E_FAILURE; 9816 } 9817 9818 /** 9819 * send_unit_test_cmd_tlv() - send unit test command to fw. 9820 * @wmi_handle: wmi handle 9821 * @wmi_utest: unit test command 9822 * 9823 * This function send unit test command to fw. 9824 * 9825 * Return: CDF STATUS 9826 */ 9827 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 9828 struct wmi_unit_test_cmd *wmi_utest) 9829 { 9830 wmi_unit_test_cmd_fixed_param *cmd; 9831 wmi_buf_t wmi_buf; 9832 uint8_t *buf_ptr; 9833 int i; 9834 uint16_t len, args_tlv_len; 9835 uint32_t *unit_test_cmd_args; 9836 9837 args_tlv_len = 9838 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 9839 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 9840 9841 wmi_buf = wmi_buf_alloc(wmi_handle, len); 9842 if (!wmi_buf) 9843 return QDF_STATUS_E_NOMEM; 9844 9845 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 9846 buf_ptr = (uint8_t *) cmd; 9847 WMITLV_SET_HDR(&cmd->tlv_header, 9848 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 9849 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 9850 cmd->vdev_id = wmi_utest->vdev_id; 9851 cmd->module_id = wmi_utest->module_id; 9852 cmd->num_args = wmi_utest->num_args; 9853 cmd->diag_token = wmi_utest->diag_token; 9854 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 9855 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9856 (wmi_utest->num_args * sizeof(uint32_t))); 9857 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9858 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 9859 cmd->vdev_id, cmd->module_id, cmd->diag_token); 9860 wmi_debug("%d num of args = ", wmi_utest->num_args); 9861 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 9862 unit_test_cmd_args[i] = wmi_utest->args[i]; 9863 wmi_debug("%d,", wmi_utest->args[i]); 9864 } 9865 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 9866 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 9867 WMI_UNIT_TEST_CMDID)) { 9868 wmi_err("Failed to send unit test command"); 9869 wmi_buf_free(wmi_buf); 9870 return QDF_STATUS_E_FAILURE; 9871 } 9872 9873 return QDF_STATUS_SUCCESS; 9874 } 9875 9876 /** 9877 * send_power_dbg_cmd_tlv() - send power debug commands 9878 * @wmi_handle: wmi handle 9879 * @param: wmi power debug parameter 9880 * 9881 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 9882 * 9883 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 9884 */ 9885 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 9886 struct wmi_power_dbg_params *param) 9887 { 9888 wmi_buf_t buf = NULL; 9889 QDF_STATUS status; 9890 int len, args_tlv_len; 9891 uint8_t *buf_ptr; 9892 uint8_t i; 9893 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 9894 uint32_t *cmd_args; 9895 9896 /* Prepare and send power debug cmd parameters */ 9897 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 9898 len = sizeof(*cmd) + args_tlv_len; 9899 buf = wmi_buf_alloc(wmi_handle, len); 9900 if (!buf) 9901 return QDF_STATUS_E_NOMEM; 9902 9903 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9904 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 9905 WMITLV_SET_HDR(&cmd->tlv_header, 9906 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 9907 WMITLV_GET_STRUCT_TLVLEN 9908 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 9909 9910 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9911 wmi_handle, 9912 param->pdev_id); 9913 cmd->module_id = param->module_id; 9914 cmd->num_args = param->num_args; 9915 buf_ptr += sizeof(*cmd); 9916 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9917 (param->num_args * sizeof(uint32_t))); 9918 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9919 wmi_debug("%d num of args = ", param->num_args); 9920 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 9921 cmd_args[i] = param->args[i]; 9922 wmi_debug("%d,", param->args[i]); 9923 } 9924 9925 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 9926 status = wmi_unified_cmd_send(wmi_handle, buf, 9927 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 9928 if (QDF_IS_STATUS_ERROR(status)) { 9929 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 9930 status); 9931 goto error; 9932 } 9933 9934 return QDF_STATUS_SUCCESS; 9935 error: 9936 wmi_buf_free(buf); 9937 9938 return status; 9939 } 9940 9941 /** 9942 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 9943 * @wmi_handle: wmi handle 9944 * @pdev_id: pdev id 9945 * 9946 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 9947 * 9948 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 9949 */ 9950 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 9951 uint32_t pdev_id) 9952 { 9953 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 9954 wmi_buf_t buf; 9955 uint16_t len; 9956 QDF_STATUS ret; 9957 9958 len = sizeof(*cmd); 9959 buf = wmi_buf_alloc(wmi_handle, len); 9960 9961 wmi_debug("pdev_id=%d", pdev_id); 9962 9963 if (!buf) 9964 return QDF_STATUS_E_NOMEM; 9965 9966 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 9967 wmi_buf_data(buf); 9968 9969 WMITLV_SET_HDR(&cmd->tlv_header, 9970 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 9971 WMITLV_GET_STRUCT_TLVLEN( 9972 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 9973 9974 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9975 wmi_handle, 9976 pdev_id); 9977 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 9978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9979 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 9980 if (QDF_IS_STATUS_ERROR(ret)) { 9981 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 9982 ret, pdev_id); 9983 wmi_buf_free(buf); 9984 return QDF_STATUS_E_FAILURE; 9985 } 9986 9987 return QDF_STATUS_SUCCESS; 9988 } 9989 9990 /** 9991 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 9992 * @wmi_handle: wmi handle 9993 * @pdev_id: pdev id 9994 * 9995 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 9996 * 9997 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 9998 */ 9999 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 10000 uint32_t pdev_id) 10001 { 10002 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 10003 wmi_buf_t buf; 10004 uint16_t len; 10005 QDF_STATUS ret; 10006 10007 len = sizeof(*cmd); 10008 buf = wmi_buf_alloc(wmi_handle, len); 10009 10010 wmi_debug("pdev_id=%d", pdev_id); 10011 10012 if (!buf) 10013 return QDF_STATUS_E_NOMEM; 10014 10015 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 10016 wmi_buf_data(buf); 10017 10018 WMITLV_SET_HDR(&cmd->tlv_header, 10019 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 10020 WMITLV_GET_STRUCT_TLVLEN( 10021 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 10022 10023 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10024 wmi_handle, 10025 pdev_id); 10026 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 10027 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10028 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 10029 if (QDF_IS_STATUS_ERROR(ret)) { 10030 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 10031 ret, pdev_id); 10032 wmi_buf_free(buf); 10033 return QDF_STATUS_E_FAILURE; 10034 } 10035 10036 return QDF_STATUS_SUCCESS; 10037 } 10038 10039 #ifdef QCA_SUPPORT_AGILE_DFS 10040 static 10041 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 10042 struct vdev_adfs_ch_cfg_params *param) 10043 { 10044 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 10045 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 10046 wmi_buf_t buf; 10047 QDF_STATUS ret; 10048 uint16_t len; 10049 10050 len = sizeof(*cmd); 10051 buf = wmi_buf_alloc(wmi_handle, len); 10052 10053 if (!buf) { 10054 wmi_err("wmi_buf_alloc failed"); 10055 return QDF_STATUS_E_NOMEM; 10056 } 10057 10058 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 10059 wmi_buf_data(buf); 10060 10061 WMITLV_SET_HDR(&cmd->tlv_header, 10062 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 10063 WMITLV_GET_STRUCT_TLVLEN 10064 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 10065 10066 cmd->vdev_id = param->vdev_id; 10067 cmd->ocac_mode = param->ocac_mode; 10068 cmd->center_freq1 = param->center_freq1; 10069 cmd->center_freq2 = param->center_freq2; 10070 cmd->chan_freq = param->chan_freq; 10071 cmd->chan_width = param->chan_width; 10072 cmd->min_duration_ms = param->min_duration_ms; 10073 cmd->max_duration_ms = param->max_duration_ms; 10074 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 10075 cmd->vdev_id, cmd->ocac_mode, 10076 cmd->center_freq); 10077 10078 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 10079 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10080 WMI_VDEV_ADFS_CH_CFG_CMDID); 10081 10082 if (QDF_IS_STATUS_ERROR(ret)) { 10083 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10084 wmi_buf_free(buf); 10085 return QDF_STATUS_E_FAILURE; 10086 } 10087 10088 return QDF_STATUS_SUCCESS; 10089 } 10090 10091 static 10092 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 10093 struct vdev_adfs_abort_params *param) 10094 { 10095 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 10096 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 10097 wmi_buf_t buf; 10098 QDF_STATUS ret; 10099 uint16_t len; 10100 10101 len = sizeof(*cmd); 10102 buf = wmi_buf_alloc(wmi_handle, len); 10103 10104 if (!buf) { 10105 wmi_err("wmi_buf_alloc failed"); 10106 return QDF_STATUS_E_NOMEM; 10107 } 10108 10109 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 10110 wmi_buf_data(buf); 10111 10112 WMITLV_SET_HDR 10113 (&cmd->tlv_header, 10114 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 10115 WMITLV_GET_STRUCT_TLVLEN 10116 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 10117 10118 cmd->vdev_id = param->vdev_id; 10119 10120 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 10121 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10122 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 10123 10124 if (QDF_IS_STATUS_ERROR(ret)) { 10125 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10126 wmi_buf_free(buf); 10127 return QDF_STATUS_E_FAILURE; 10128 } 10129 10130 return QDF_STATUS_SUCCESS; 10131 } 10132 #endif 10133 10134 /** 10135 * init_cmd_send_tlv() - send initialization cmd to fw 10136 * @wmi_handle: wmi handle 10137 * @param param: pointer to wmi init param 10138 * 10139 * Return: QDF_STATUS_SUCCESS for success or error code 10140 */ 10141 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 10142 struct wmi_init_cmd_param *param) 10143 { 10144 wmi_buf_t buf; 10145 wmi_init_cmd_fixed_param *cmd; 10146 uint8_t *buf_ptr; 10147 wmi_resource_config *resource_cfg; 10148 wlan_host_memory_chunk *host_mem_chunks; 10149 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 10150 uint16_t idx; 10151 int len; 10152 QDF_STATUS ret; 10153 10154 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 10155 WMI_TLV_HDR_SIZE; 10156 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 10157 10158 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 10159 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10160 WMI_TLV_HDR_SIZE + 10161 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 10162 10163 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 10164 if (!buf) 10165 return QDF_STATUS_E_FAILURE; 10166 10167 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10168 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 10169 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 10170 10171 host_mem_chunks = (wlan_host_memory_chunk *) 10172 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 10173 + WMI_TLV_HDR_SIZE); 10174 10175 WMITLV_SET_HDR(&cmd->tlv_header, 10176 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 10177 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 10178 wmi_copy_resource_config(resource_cfg, param->res_cfg); 10179 WMITLV_SET_HDR(&resource_cfg->tlv_header, 10180 WMITLV_TAG_STRUC_wmi_resource_config, 10181 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 10182 10183 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 10184 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 10185 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 10186 WMITLV_GET_STRUCT_TLVLEN 10187 (wlan_host_memory_chunk)); 10188 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 10189 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 10190 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 10191 if (is_service_enabled_tlv(wmi_handle, 10192 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 10193 host_mem_chunks[idx].ptr_high = 10194 qdf_get_upper_32_bits( 10195 param->mem_chunks[idx].paddr); 10196 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 10197 "chunk %d len %d requested ,ptr 0x%x ", 10198 idx, host_mem_chunks[idx].size, 10199 host_mem_chunks[idx].ptr); 10200 } 10201 cmd->num_host_mem_chunks = param->num_mem_chunks; 10202 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 10203 10204 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 10205 WMITLV_TAG_ARRAY_STRUC, 10206 (sizeof(wlan_host_memory_chunk) * 10207 param->num_mem_chunks)); 10208 10209 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", 10210 resource_cfg->num_peers, resource_cfg->num_offload_peers, 10211 resource_cfg->num_vdevs, resource_cfg->num_tids, 10212 resource_cfg->num_tdls_conn_table_entries, 10213 resource_cfg->num_tdls_vdevs); 10214 10215 /* Fill hw mode id config */ 10216 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 10217 10218 /* Fill fw_abi_vers */ 10219 copy_fw_abi_version_tlv(wmi_handle, cmd); 10220 10221 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 10222 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 10223 if (QDF_IS_STATUS_ERROR(ret)) { 10224 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 10225 ret); 10226 wmi_buf_free(buf); 10227 } 10228 10229 return ret; 10230 10231 } 10232 10233 /** 10234 * send_addba_send_cmd_tlv() - send addba send command to fw 10235 * @wmi_handle: wmi handle 10236 * @param: pointer to delba send params 10237 * @macaddr: peer mac address 10238 * 10239 * Send WMI_ADDBA_SEND_CMDID command to firmware 10240 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 10241 */ 10242 static QDF_STATUS 10243 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 10244 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 10245 struct addba_send_params *param) 10246 { 10247 wmi_addba_send_cmd_fixed_param *cmd; 10248 wmi_buf_t buf; 10249 uint16_t len; 10250 QDF_STATUS ret; 10251 10252 len = sizeof(*cmd); 10253 10254 buf = wmi_buf_alloc(wmi_handle, len); 10255 if (!buf) 10256 return QDF_STATUS_E_NOMEM; 10257 10258 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 10259 10260 WMITLV_SET_HDR(&cmd->tlv_header, 10261 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 10262 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 10263 10264 cmd->vdev_id = param->vdev_id; 10265 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10266 cmd->tid = param->tidno; 10267 cmd->buffersize = param->buffersize; 10268 10269 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 10270 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 10271 if (QDF_IS_STATUS_ERROR(ret)) { 10272 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10273 wmi_buf_free(buf); 10274 return QDF_STATUS_E_FAILURE; 10275 } 10276 10277 return QDF_STATUS_SUCCESS; 10278 } 10279 10280 /** 10281 * send_delba_send_cmd_tlv() - send delba send command to fw 10282 * @wmi_handle: wmi handle 10283 * @param: pointer to delba send params 10284 * @macaddr: peer mac address 10285 * 10286 * Send WMI_DELBA_SEND_CMDID command to firmware 10287 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 10288 */ 10289 static QDF_STATUS 10290 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 10291 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 10292 struct delba_send_params *param) 10293 { 10294 wmi_delba_send_cmd_fixed_param *cmd; 10295 wmi_buf_t buf; 10296 uint16_t len; 10297 QDF_STATUS ret; 10298 10299 len = sizeof(*cmd); 10300 10301 buf = wmi_buf_alloc(wmi_handle, len); 10302 if (!buf) 10303 return QDF_STATUS_E_NOMEM; 10304 10305 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 10306 10307 WMITLV_SET_HDR(&cmd->tlv_header, 10308 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 10309 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 10310 10311 cmd->vdev_id = param->vdev_id; 10312 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10313 cmd->tid = param->tidno; 10314 cmd->initiator = param->initiator; 10315 cmd->reasoncode = param->reasoncode; 10316 10317 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 10318 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 10319 if (QDF_IS_STATUS_ERROR(ret)) { 10320 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10321 wmi_buf_free(buf); 10322 return QDF_STATUS_E_FAILURE; 10323 } 10324 10325 return QDF_STATUS_SUCCESS; 10326 } 10327 10328 /** 10329 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 10330 * to fw 10331 * @wmi_handle: wmi handle 10332 * @param: pointer to addba clearresp params 10333 * @macaddr: peer mac address 10334 * Return: 0 for success or error code 10335 */ 10336 static QDF_STATUS 10337 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 10338 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 10339 struct addba_clearresponse_params *param) 10340 { 10341 wmi_addba_clear_resp_cmd_fixed_param *cmd; 10342 wmi_buf_t buf; 10343 uint16_t len; 10344 QDF_STATUS ret; 10345 10346 len = sizeof(*cmd); 10347 10348 buf = wmi_buf_alloc(wmi_handle, len); 10349 if (!buf) 10350 return QDF_STATUS_E_FAILURE; 10351 10352 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 10353 10354 WMITLV_SET_HDR(&cmd->tlv_header, 10355 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 10356 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 10357 10358 cmd->vdev_id = param->vdev_id; 10359 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 10360 10361 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 10362 ret = wmi_unified_cmd_send(wmi_handle, 10363 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 10364 if (QDF_IS_STATUS_ERROR(ret)) { 10365 wmi_err("Failed to send cmd to fw, ret=%d", ret); 10366 wmi_buf_free(buf); 10367 return QDF_STATUS_E_FAILURE; 10368 } 10369 10370 return QDF_STATUS_SUCCESS; 10371 } 10372 10373 #ifdef OBSS_PD 10374 /** 10375 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 10376 * def thresh to fw 10377 * @wmi_handle: wmi handle 10378 * @thresh: pointer to obss_spatial_reuse_def_thresh 10379 * 10380 * Return: QDF_STATUS_SUCCESS for success or error code 10381 */ 10382 static 10383 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 10384 wmi_unified_t wmi_handle, 10385 struct wmi_host_obss_spatial_reuse_set_def_thresh 10386 *thresh) 10387 { 10388 wmi_buf_t buf; 10389 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 10390 QDF_STATUS ret; 10391 uint32_t cmd_len; 10392 uint32_t tlv_len; 10393 10394 cmd_len = sizeof(*cmd); 10395 10396 buf = wmi_buf_alloc(wmi_handle, cmd_len); 10397 if (!buf) 10398 return QDF_STATUS_E_NOMEM; 10399 10400 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 10401 wmi_buf_data(buf); 10402 10403 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 10404 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 10405 10406 WMITLV_SET_HDR(&cmd->tlv_header, 10407 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 10408 tlv_len); 10409 10410 cmd->obss_min = thresh->obss_min; 10411 cmd->obss_max = thresh->obss_max; 10412 cmd->vdev_type = thresh->vdev_type; 10413 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 10414 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 10415 if (QDF_IS_STATUS_ERROR(ret)) 10416 wmi_buf_free(buf); 10417 10418 return ret; 10419 } 10420 10421 /** 10422 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 10423 * @wmi_handle: wmi handle 10424 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 10425 * 10426 * Return: QDF_STATUS_SUCCESS for success or error code 10427 */ 10428 static 10429 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 10430 struct wmi_host_obss_spatial_reuse_set_param 10431 *obss_spatial_reuse_param) 10432 { 10433 wmi_buf_t buf; 10434 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 10435 QDF_STATUS ret; 10436 uint32_t len; 10437 10438 len = sizeof(*cmd); 10439 10440 buf = wmi_buf_alloc(wmi_handle, len); 10441 if (!buf) 10442 return QDF_STATUS_E_FAILURE; 10443 10444 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 10445 WMITLV_SET_HDR(&cmd->tlv_header, 10446 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 10447 WMITLV_GET_STRUCT_TLVLEN 10448 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 10449 10450 cmd->enable = obss_spatial_reuse_param->enable; 10451 cmd->obss_min = obss_spatial_reuse_param->obss_min; 10452 cmd->obss_max = obss_spatial_reuse_param->obss_max; 10453 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 10454 10455 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10456 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 10457 10458 if (QDF_IS_STATUS_ERROR(ret)) { 10459 wmi_err( 10460 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 10461 ret); 10462 wmi_buf_free(buf); 10463 } 10464 10465 return ret; 10466 } 10467 10468 /** 10469 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 10470 * to be used by SRG based Spatial Reuse feature to the FW 10471 * @wmi_handle: wmi handle 10472 * @bitmap_0: lower 32 bits in BSS color bitmap 10473 * @bitmap_1: upper 32 bits in BSS color bitmap 10474 * @pdev_id: pdev ID 10475 * 10476 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10477 */ 10478 static QDF_STATUS 10479 send_self_srg_bss_color_bitmap_set_cmd_tlv( 10480 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10481 uint32_t bitmap_1, uint8_t pdev_id) 10482 { 10483 wmi_buf_t buf; 10484 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 10485 QDF_STATUS ret; 10486 uint32_t len; 10487 10488 len = sizeof(*cmd); 10489 10490 buf = wmi_buf_alloc(wmi_handle, len); 10491 if (!buf) 10492 return QDF_STATUS_E_FAILURE; 10493 10494 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 10495 wmi_buf_data(buf); 10496 10497 WMITLV_SET_HDR( 10498 &cmd->tlv_header, 10499 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 10500 WMITLV_GET_STRUCT_TLVLEN 10501 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 10502 10503 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10504 wmi_handle, pdev_id); 10505 cmd->srg_bss_color_bitmap[0] = bitmap_0; 10506 cmd->srg_bss_color_bitmap[1] = bitmap_1; 10507 10508 ret = wmi_unified_cmd_send( 10509 wmi_handle, buf, len, 10510 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 10511 10512 if (QDF_IS_STATUS_ERROR(ret)) { 10513 wmi_err( 10514 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 10515 ret); 10516 wmi_buf_free(buf); 10517 } 10518 10519 return ret; 10520 } 10521 10522 /** 10523 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 10524 * bitmap to be used by SRG based Spatial Reuse feature to the FW 10525 * @wmi_handle: wmi handle 10526 * @bitmap_0: lower 32 bits in partial BSSID bitmap 10527 * @bitmap_1: upper 32 bits in partial BSSID bitmap 10528 * @pdev_id: pdev ID 10529 * 10530 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10531 */ 10532 static QDF_STATUS 10533 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 10534 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10535 uint32_t bitmap_1, uint8_t pdev_id) 10536 { 10537 wmi_buf_t buf; 10538 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 10539 QDF_STATUS ret; 10540 uint32_t len; 10541 10542 len = sizeof(*cmd); 10543 10544 buf = wmi_buf_alloc(wmi_handle, len); 10545 if (!buf) 10546 return QDF_STATUS_E_FAILURE; 10547 10548 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 10549 wmi_buf_data(buf); 10550 10551 WMITLV_SET_HDR( 10552 &cmd->tlv_header, 10553 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 10554 WMITLV_GET_STRUCT_TLVLEN 10555 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 10556 10557 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10558 wmi_handle, pdev_id); 10559 10560 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 10561 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 10562 10563 ret = wmi_unified_cmd_send( 10564 wmi_handle, buf, len, 10565 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 10566 10567 if (QDF_IS_STATUS_ERROR(ret)) { 10568 wmi_err( 10569 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 10570 ret); 10571 wmi_buf_free(buf); 10572 } 10573 10574 return ret; 10575 } 10576 10577 /** 10578 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 10579 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 10580 * @wmi_handle: wmi handle 10581 * @bitmap_0: lower 32 bits in BSS color enable bitmap 10582 * @bitmap_1: upper 32 bits in BSS color enable bitmap 10583 * @pdev_id: pdev ID 10584 * 10585 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10586 */ 10587 static QDF_STATUS 10588 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 10589 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10590 uint32_t bitmap_1, uint8_t pdev_id) 10591 { 10592 wmi_buf_t buf; 10593 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 10594 QDF_STATUS ret; 10595 uint32_t len; 10596 10597 len = sizeof(*cmd); 10598 10599 buf = wmi_buf_alloc(wmi_handle, len); 10600 if (!buf) 10601 return QDF_STATUS_E_FAILURE; 10602 10603 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 10604 wmi_buf_data(buf); 10605 10606 WMITLV_SET_HDR( 10607 &cmd->tlv_header, 10608 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 10609 WMITLV_GET_STRUCT_TLVLEN 10610 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 10611 10612 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10613 wmi_handle, pdev_id); 10614 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 10615 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 10616 10617 ret = wmi_unified_cmd_send( 10618 wmi_handle, buf, len, 10619 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 10620 10621 if (QDF_IS_STATUS_ERROR(ret)) { 10622 wmi_err( 10623 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 10624 ret); 10625 wmi_buf_free(buf); 10626 } 10627 10628 return ret; 10629 } 10630 10631 /** 10632 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 10633 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 10634 * @wmi_handle: wmi handle 10635 * @bitmap_0: lower 32 bits in BSSID enable bitmap 10636 * @bitmap_1: upper 32 bits in BSSID enable bitmap 10637 * @pdev_id: pdev ID 10638 * 10639 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10640 */ 10641 static QDF_STATUS 10642 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 10643 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10644 uint32_t bitmap_1, uint8_t pdev_id) 10645 { 10646 wmi_buf_t buf; 10647 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 10648 QDF_STATUS ret; 10649 uint32_t len; 10650 10651 len = sizeof(*cmd); 10652 10653 buf = wmi_buf_alloc(wmi_handle, len); 10654 if (!buf) 10655 return QDF_STATUS_E_FAILURE; 10656 10657 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 10658 wmi_buf_data(buf); 10659 10660 WMITLV_SET_HDR( 10661 &cmd->tlv_header, 10662 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 10663 WMITLV_GET_STRUCT_TLVLEN 10664 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 10665 10666 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10667 wmi_handle, pdev_id); 10668 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 10669 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 10670 10671 ret = wmi_unified_cmd_send( 10672 wmi_handle, buf, len, 10673 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 10674 10675 if (QDF_IS_STATUS_ERROR(ret)) { 10676 wmi_err( 10677 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 10678 ret); 10679 wmi_buf_free(buf); 10680 } 10681 10682 return ret; 10683 } 10684 10685 /** 10686 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 10687 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 10688 * @wmi_handle: wmi handle 10689 * @bitmap_0: lower 32 bits in BSS color enable bitmap 10690 * @bitmap_1: upper 32 bits in BSS color enable bitmap 10691 * @pdev_id: pdev ID 10692 * 10693 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10694 */ 10695 static QDF_STATUS 10696 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 10697 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10698 uint32_t bitmap_1, uint8_t pdev_id) 10699 { 10700 wmi_buf_t buf; 10701 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 10702 QDF_STATUS ret; 10703 uint32_t len; 10704 10705 len = sizeof(*cmd); 10706 10707 buf = wmi_buf_alloc(wmi_handle, len); 10708 if (!buf) 10709 return QDF_STATUS_E_FAILURE; 10710 10711 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 10712 wmi_buf_data(buf); 10713 10714 WMITLV_SET_HDR( 10715 &cmd->tlv_header, 10716 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 10717 WMITLV_GET_STRUCT_TLVLEN 10718 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 10719 10720 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10721 wmi_handle, pdev_id); 10722 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 10723 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 10724 10725 ret = wmi_unified_cmd_send( 10726 wmi_handle, buf, len, 10727 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 10728 10729 if (QDF_IS_STATUS_ERROR(ret)) { 10730 wmi_err( 10731 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 10732 ret); 10733 wmi_buf_free(buf); 10734 } 10735 10736 return ret; 10737 } 10738 10739 /** 10740 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 10741 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 10742 * @wmi_handle: wmi handle 10743 * @bitmap_0: lower 32 bits in BSSID enable bitmap 10744 * @bitmap_1: upper 32 bits in BSSID enable bitmap 10745 * @pdev_id: pdev ID 10746 * 10747 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 10748 */ 10749 static QDF_STATUS 10750 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 10751 wmi_unified_t wmi_handle, uint32_t bitmap_0, 10752 uint32_t bitmap_1, uint8_t pdev_id) 10753 { 10754 wmi_buf_t buf; 10755 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 10756 QDF_STATUS ret; 10757 uint32_t len; 10758 10759 len = sizeof(*cmd); 10760 10761 buf = wmi_buf_alloc(wmi_handle, len); 10762 if (!buf) 10763 return QDF_STATUS_E_FAILURE; 10764 10765 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 10766 wmi_buf_data(buf); 10767 10768 WMITLV_SET_HDR( 10769 &cmd->tlv_header, 10770 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 10771 WMITLV_GET_STRUCT_TLVLEN 10772 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 10773 10774 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10775 wmi_handle, pdev_id); 10776 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 10777 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 10778 10779 ret = wmi_unified_cmd_send( 10780 wmi_handle, buf, len, 10781 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 10782 10783 if (QDF_IS_STATUS_ERROR(ret)) { 10784 wmi_err( 10785 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 10786 ret); 10787 wmi_buf_free(buf); 10788 } 10789 10790 return ret; 10791 } 10792 #endif 10793 10794 static 10795 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 10796 struct wmi_host_injector_frame_params *inject_config_params) 10797 { 10798 wmi_buf_t buf; 10799 wmi_frame_inject_cmd_fixed_param *cmd; 10800 QDF_STATUS ret; 10801 uint32_t len; 10802 10803 len = sizeof(*cmd); 10804 10805 buf = wmi_buf_alloc(wmi_handle, len); 10806 if (!buf) 10807 return QDF_STATUS_E_NOMEM; 10808 10809 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 10810 WMITLV_SET_HDR(&cmd->tlv_header, 10811 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 10812 WMITLV_GET_STRUCT_TLVLEN 10813 (wmi_frame_inject_cmd_fixed_param)); 10814 10815 cmd->vdev_id = inject_config_params->vdev_id; 10816 cmd->enable = inject_config_params->enable; 10817 cmd->frame_type = inject_config_params->frame_type; 10818 cmd->frame_inject_period = inject_config_params->frame_inject_period; 10819 cmd->fc_duration = inject_config_params->frame_duration; 10820 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 10821 &cmd->frame_addr1); 10822 10823 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10824 WMI_PDEV_FRAME_INJECT_CMDID); 10825 10826 if (QDF_IS_STATUS_ERROR(ret)) { 10827 wmi_err( 10828 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 10829 ret); 10830 wmi_buf_free(buf); 10831 } 10832 10833 return ret; 10834 } 10835 #ifdef QCA_SUPPORT_CP_STATS 10836 /** 10837 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 10838 * @wmi_handle: wma handle 10839 * @evt_buf: event buffer 10840 * @out_buff: buffer to populated after stats extraction 10841 * 10842 * Return: status of operation 10843 */ 10844 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 10845 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 10846 { 10847 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10848 wmi_congestion_stats *congestion_stats; 10849 10850 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 10851 congestion_stats = param_buf->congestion_stats; 10852 if (!congestion_stats) 10853 return QDF_STATUS_E_INVAL; 10854 10855 out_buff->vdev_id = congestion_stats->vdev_id; 10856 out_buff->congestion = congestion_stats->congestion; 10857 10858 wmi_debug("cca stats event processed"); 10859 return QDF_STATUS_SUCCESS; 10860 } 10861 #endif /* QCA_SUPPORT_CP_STATS */ 10862 10863 /** 10864 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 10865 * event 10866 * @wmi_handle: wmi handle 10867 * @param evt_buf: pointer to event buffer 10868 * @param param: Pointer to hold peer ctl data 10869 * 10870 * Return: QDF_STATUS_SUCCESS for success or error code 10871 */ 10872 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 10873 wmi_unified_t wmi_handle, 10874 void *evt_buf, 10875 struct wmi_host_pdev_ctl_failsafe_event *param) 10876 { 10877 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 10878 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 10879 10880 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 10881 if (!param_buf) { 10882 wmi_err("Invalid ctl_failsafe event buffer"); 10883 return QDF_STATUS_E_INVAL; 10884 } 10885 10886 fix_param = param_buf->fixed_param; 10887 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 10888 10889 return QDF_STATUS_SUCCESS; 10890 } 10891 10892 /** 10893 * save_service_bitmap_tlv() - save service bitmap 10894 * @wmi_handle: wmi handle 10895 * @param evt_buf: pointer to event buffer 10896 * @param bitmap_buf: bitmap buffer, for converged legacy support 10897 * 10898 * Return: QDF_STATUS 10899 */ 10900 static 10901 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 10902 void *bitmap_buf) 10903 { 10904 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10905 struct wmi_soc *soc = wmi_handle->soc; 10906 10907 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10908 10909 /* If it is already allocated, use that buffer. This can happen 10910 * during target stop/start scenarios where host allocation is skipped. 10911 */ 10912 if (!soc->wmi_service_bitmap) { 10913 soc->wmi_service_bitmap = 10914 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 10915 if (!soc->wmi_service_bitmap) 10916 return QDF_STATUS_E_NOMEM; 10917 } 10918 10919 qdf_mem_copy(soc->wmi_service_bitmap, 10920 param_buf->wmi_service_bitmap, 10921 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 10922 10923 if (bitmap_buf) 10924 qdf_mem_copy(bitmap_buf, 10925 param_buf->wmi_service_bitmap, 10926 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 10927 10928 return QDF_STATUS_SUCCESS; 10929 } 10930 10931 /** 10932 * save_ext_service_bitmap_tlv() - save extendend service bitmap 10933 * @wmi_handle: wmi handle 10934 * @param evt_buf: pointer to event buffer 10935 * @param bitmap_buf: bitmap buffer, for converged legacy support 10936 * 10937 * Return: QDF_STATUS 10938 */ 10939 static 10940 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 10941 void *bitmap_buf) 10942 { 10943 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 10944 wmi_service_available_event_fixed_param *ev; 10945 struct wmi_soc *soc = wmi_handle->soc; 10946 uint32_t i = 0; 10947 10948 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 10949 10950 ev = param_buf->fixed_param; 10951 10952 /* If it is already allocated, use that buffer. This can happen 10953 * during target stop/start scenarios where host allocation is skipped. 10954 */ 10955 if (!soc->wmi_ext_service_bitmap) { 10956 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 10957 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 10958 if (!soc->wmi_ext_service_bitmap) 10959 return QDF_STATUS_E_NOMEM; 10960 } 10961 10962 qdf_mem_copy(soc->wmi_ext_service_bitmap, 10963 ev->wmi_service_segment_bitmap, 10964 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 10965 10966 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 10967 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 10968 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 10969 10970 if (bitmap_buf) 10971 qdf_mem_copy(bitmap_buf, 10972 soc->wmi_ext_service_bitmap, 10973 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 10974 10975 if (!param_buf->wmi_service_ext_bitmap) { 10976 wmi_debug("wmi_service_ext_bitmap not available"); 10977 return QDF_STATUS_SUCCESS; 10978 } 10979 10980 if (!soc->wmi_ext2_service_bitmap) { 10981 soc->wmi_ext2_service_bitmap = 10982 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 10983 sizeof(uint32_t)); 10984 if (!soc->wmi_ext2_service_bitmap) 10985 return QDF_STATUS_E_NOMEM; 10986 } 10987 10988 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 10989 param_buf->wmi_service_ext_bitmap, 10990 (param_buf->num_wmi_service_ext_bitmap * 10991 sizeof(uint32_t))); 10992 10993 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 10994 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 10995 i, soc->wmi_ext2_service_bitmap[i]); 10996 } 10997 10998 return QDF_STATUS_SUCCESS; 10999 } 11000 11001 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 11002 struct wlan_psoc_target_capability_info *cap) 11003 { 11004 /* except LDPC all flags are common betwen legacy and here 11005 * also IBFEER is not defined for TLV 11006 */ 11007 cap->ht_cap_info |= ev_target_cap & ( 11008 WMI_HT_CAP_ENABLED 11009 | WMI_HT_CAP_HT20_SGI 11010 | WMI_HT_CAP_DYNAMIC_SMPS 11011 | WMI_HT_CAP_TX_STBC 11012 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 11013 | WMI_HT_CAP_RX_STBC 11014 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 11015 | WMI_HT_CAP_LDPC 11016 | WMI_HT_CAP_L_SIG_TXOP_PROT 11017 | WMI_HT_CAP_MPDU_DENSITY 11018 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 11019 | WMI_HT_CAP_HT40_SGI); 11020 if (ev_target_cap & WMI_HT_CAP_LDPC) 11021 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 11022 WMI_HOST_HT_CAP_TX_LDPC; 11023 } 11024 /** 11025 * extract_service_ready_tlv() - extract service ready event 11026 * @wmi_handle: wmi handle 11027 * @param evt_buf: pointer to received event buffer 11028 * @param cap: pointer to hold target capability information extracted from even 11029 * 11030 * Return: QDF_STATUS_SUCCESS for success or error code 11031 */ 11032 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 11033 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 11034 { 11035 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11036 wmi_service_ready_event_fixed_param *ev; 11037 11038 11039 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11040 11041 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11042 if (!ev) { 11043 qdf_print("%s: wmi_buf_alloc failed", __func__); 11044 return QDF_STATUS_E_FAILURE; 11045 } 11046 11047 cap->phy_capability = ev->phy_capability; 11048 cap->max_frag_entry = ev->max_frag_entry; 11049 cap->num_rf_chains = ev->num_rf_chains; 11050 copy_ht_cap_info(ev->ht_cap_info, cap); 11051 cap->vht_cap_info = ev->vht_cap_info; 11052 cap->vht_supp_mcs = ev->vht_supp_mcs; 11053 cap->hw_min_tx_power = ev->hw_min_tx_power; 11054 cap->hw_max_tx_power = ev->hw_max_tx_power; 11055 cap->sys_cap_info = ev->sys_cap_info; 11056 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 11057 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 11058 cap->max_num_scan_channels = ev->max_num_scan_channels; 11059 cap->max_supported_macs = ev->max_supported_macs; 11060 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 11061 cap->txrx_chainmask = ev->txrx_chainmask; 11062 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 11063 cap->num_msdu_desc = ev->num_msdu_desc; 11064 cap->fw_version = ev->fw_build_vers; 11065 /* fw_version_1 is not available in TLV. */ 11066 cap->fw_version_1 = 0; 11067 11068 return QDF_STATUS_SUCCESS; 11069 } 11070 11071 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 11072 * to host internal HOST_REGDMN_MODE values. 11073 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 11074 * host currently. Add this in the future if required. 11075 * 11AX (Phase II) : 11ax related values are not currently 11076 * advertised separately by FW. As part of phase II regulatory bring-up, 11077 * finalize the advertisement mechanism. 11078 * @target_wireless_mode: target wireless mode received in message 11079 * 11080 * Return: returns the host internal wireless mode. 11081 */ 11082 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 11083 { 11084 11085 uint32_t wireless_modes = 0; 11086 11087 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 11088 11089 if (target_wireless_mode & REGDMN_MODE_11A) 11090 wireless_modes |= HOST_REGDMN_MODE_11A; 11091 11092 if (target_wireless_mode & REGDMN_MODE_TURBO) 11093 wireless_modes |= HOST_REGDMN_MODE_TURBO; 11094 11095 if (target_wireless_mode & REGDMN_MODE_11B) 11096 wireless_modes |= HOST_REGDMN_MODE_11B; 11097 11098 if (target_wireless_mode & REGDMN_MODE_PUREG) 11099 wireless_modes |= HOST_REGDMN_MODE_PUREG; 11100 11101 if (target_wireless_mode & REGDMN_MODE_11G) 11102 wireless_modes |= HOST_REGDMN_MODE_11G; 11103 11104 if (target_wireless_mode & REGDMN_MODE_108G) 11105 wireless_modes |= HOST_REGDMN_MODE_108G; 11106 11107 if (target_wireless_mode & REGDMN_MODE_108A) 11108 wireless_modes |= HOST_REGDMN_MODE_108A; 11109 11110 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 11111 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 11112 11113 if (target_wireless_mode & REGDMN_MODE_XR) 11114 wireless_modes |= HOST_REGDMN_MODE_XR; 11115 11116 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 11117 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 11118 11119 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 11120 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 11121 11122 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 11123 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 11124 11125 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 11126 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 11127 11128 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 11129 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 11130 11131 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 11132 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 11133 11134 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 11135 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 11136 11137 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 11138 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 11139 11140 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 11141 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 11142 11143 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 11144 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 11145 11146 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 11147 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 11148 11149 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 11150 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 11151 11152 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 11153 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 11154 11155 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 11156 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 11157 11158 return wireless_modes; 11159 } 11160 11161 /** 11162 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 11163 * to regulatory flags. 11164 * @target_phybitmap: target phybitmap. 11165 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 11166 * phybitmap. 11167 * 11168 * Return: None 11169 */ 11170 11171 #ifdef WLAN_FEATURE_11BE 11172 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 11173 uint32_t *phybitmap) 11174 { 11175 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 11176 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 11177 } 11178 #else 11179 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 11180 uint32_t *phybitmap) 11181 { 11182 } 11183 #endif 11184 11185 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 11186 * target to host internal REGULATORY_PHYMODE values. 11187 * 11188 * @target_target_phybitmap: target phybitmap received in the message. 11189 * 11190 * Return: returns the host internal REGULATORY_PHYMODE. 11191 */ 11192 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 11193 { 11194 uint32_t phybitmap = 0; 11195 11196 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 11197 11198 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 11199 phybitmap |= REGULATORY_PHYMODE_NO11A; 11200 11201 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 11202 phybitmap |= REGULATORY_PHYMODE_NO11B; 11203 11204 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 11205 phybitmap |= REGULATORY_PHYMODE_NO11G; 11206 11207 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 11208 phybitmap |= REGULATORY_CHAN_NO11N; 11209 11210 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 11211 phybitmap |= REGULATORY_PHYMODE_NO11AC; 11212 11213 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 11214 phybitmap |= REGULATORY_PHYMODE_NO11AX; 11215 11216 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 11217 11218 return phybitmap; 11219 } 11220 11221 /** 11222 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 11223 * advertised by the target to wireless mode ext flags. 11224 * @target_wireless_modes_ext: Target wireless mode 11225 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 11226 * 11227 * Return: None 11228 */ 11229 #ifdef WLAN_FEATURE_11BE 11230 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 11231 uint64_t *wireless_modes_ext) 11232 { 11233 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 11234 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 11235 11236 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 11237 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 11238 11239 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 11240 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 11241 11242 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 11243 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 11244 11245 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 11246 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 11247 11248 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 11249 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 11250 11251 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 11252 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 11253 11254 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 11255 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 11256 11257 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 11258 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 11259 } 11260 #else 11261 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 11262 uint64_t *wireless_modes_ext) 11263 { 11264 } 11265 #endif 11266 11267 static inline uint64_t convert_wireless_modes_ext_tlv( 11268 uint32_t target_wireless_modes_ext) 11269 { 11270 uint64_t wireless_modes_ext = 0; 11271 11272 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 11273 11274 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 11275 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 11276 11277 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 11278 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 11279 11280 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 11281 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 11282 11283 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 11284 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 11285 11286 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 11287 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 11288 11289 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 11290 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 11291 11292 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 11293 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 11294 11295 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 11296 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 11297 11298 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 11299 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 11300 11301 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 11302 &wireless_modes_ext); 11303 11304 return wireless_modes_ext; 11305 } 11306 11307 /** 11308 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 11309 * @wmi_handle: wmi handle 11310 * @param evt_buf: Pointer to event buffer 11311 * @param cap: pointer to hold HAL reg capabilities 11312 * 11313 * Return: QDF_STATUS_SUCCESS for success or error code 11314 */ 11315 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 11316 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 11317 { 11318 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11319 11320 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11321 if (!param_buf || !param_buf->hal_reg_capabilities) { 11322 wmi_err("Invalid arguments"); 11323 return QDF_STATUS_E_FAILURE; 11324 } 11325 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 11326 sizeof(uint32_t)), 11327 sizeof(struct wlan_psoc_hal_reg_capability)); 11328 11329 cap->wireless_modes = convert_wireless_modes_tlv( 11330 param_buf->hal_reg_capabilities->wireless_modes); 11331 11332 return QDF_STATUS_SUCCESS; 11333 } 11334 11335 /** 11336 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 11337 * @wmi_handle: wmi handle 11338 * @param evt_buf: Pointer to event buffer 11339 * @param cap: pointer to hold HAL reg capabilities 11340 * 11341 * Return: QDF_STATUS_SUCCESS for success or error code 11342 */ 11343 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 11344 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 11345 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 11346 { 11347 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11348 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 11349 11350 if (!evt_buf) { 11351 wmi_err("null evt_buf"); 11352 return QDF_STATUS_E_INVAL; 11353 } 11354 11355 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 11356 11357 if (!param_buf->num_hal_reg_caps) 11358 return QDF_STATUS_SUCCESS; 11359 11360 if (phy_idx >= param_buf->num_hal_reg_caps) 11361 return QDF_STATUS_E_INVAL; 11362 11363 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 11364 11365 param->phy_id = reg_caps->phy_id; 11366 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 11367 reg_caps->wireless_modes_ext); 11368 11369 return QDF_STATUS_SUCCESS; 11370 } 11371 11372 /** 11373 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 11374 * @wmi_handle: wmi handle 11375 * @evt_buf: pointer to event buffer 11376 * 11377 * Return: Number of entries requested 11378 */ 11379 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 11380 void *evt_buf) 11381 { 11382 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11383 wmi_service_ready_event_fixed_param *ev; 11384 11385 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11386 11387 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11388 if (!ev) { 11389 qdf_print("%s: wmi_buf_alloc failed", __func__); 11390 return 0; 11391 } 11392 11393 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 11394 wmi_err("Invalid num_mem_reqs %d:%d", 11395 ev->num_mem_reqs, param_buf->num_mem_reqs); 11396 return 0; 11397 } 11398 11399 return ev->num_mem_reqs; 11400 } 11401 11402 /** 11403 * extract_host_mem_req_tlv() - Extract host memory required from 11404 * service ready event 11405 * @wmi_handle: wmi handle 11406 * @evt_buf: pointer to event buffer 11407 * @mem_reqs: pointer to host memory request structure 11408 * @num_active_peers: number of active peers for peer cache 11409 * @num_peers: number of peers 11410 * @fw_prio: FW priority 11411 * @idx: index for memory request 11412 * 11413 * Return: Host memory request parameters requested by target 11414 */ 11415 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 11416 void *evt_buf, 11417 host_mem_req *mem_reqs, 11418 uint32_t num_active_peers, 11419 uint32_t num_peers, 11420 enum wmi_fw_mem_prio fw_prio, 11421 uint16_t idx) 11422 { 11423 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11424 11425 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 11426 11427 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 11428 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 11429 mem_reqs->num_unit_info = 11430 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 11431 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 11432 mem_reqs->tgt_num_units = 0; 11433 11434 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 11435 (mem_reqs->num_unit_info & 11436 REQ_TO_HOST_FOR_CONT_MEMORY)) || 11437 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 11438 (!(mem_reqs->num_unit_info & 11439 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 11440 /* First allocate the memory that requires contiguous memory */ 11441 mem_reqs->tgt_num_units = mem_reqs->num_units; 11442 if (mem_reqs->num_unit_info) { 11443 if (mem_reqs->num_unit_info & 11444 NUM_UNITS_IS_NUM_PEERS) { 11445 /* 11446 * number of units allocated is equal to number 11447 * of peers, 1 extra for self peer on target. 11448 * this needs to be fixed, host and target can 11449 * get out of sync 11450 */ 11451 mem_reqs->tgt_num_units = num_peers + 1; 11452 } 11453 if (mem_reqs->num_unit_info & 11454 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 11455 /* 11456 * Requesting allocation of memory using 11457 * num_active_peers in qcache. if qcache is 11458 * disabled in host, then it should allocate 11459 * memory for num_peers instead of 11460 * num_active_peers. 11461 */ 11462 if (num_active_peers) 11463 mem_reqs->tgt_num_units = 11464 num_active_peers + 1; 11465 else 11466 mem_reqs->tgt_num_units = 11467 num_peers + 1; 11468 } 11469 } 11470 11471 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 11472 "unit size %d actual units %d", 11473 idx, mem_reqs->req_id, 11474 mem_reqs->num_units, 11475 mem_reqs->num_unit_info, 11476 mem_reqs->unit_size, 11477 mem_reqs->tgt_num_units); 11478 } 11479 11480 return QDF_STATUS_SUCCESS; 11481 } 11482 11483 /** 11484 * save_fw_version_in_service_ready_tlv() - Save fw version in service 11485 * ready function 11486 * @wmi_handle: wmi handle 11487 * @param evt_buf: pointer to event buffer 11488 * 11489 * Return: QDF_STATUS_SUCCESS for success or error code 11490 */ 11491 static QDF_STATUS 11492 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 11493 { 11494 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 11495 wmi_service_ready_event_fixed_param *ev; 11496 11497 11498 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 11499 11500 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 11501 if (!ev) { 11502 qdf_print("%s: wmi_buf_alloc failed", __func__); 11503 return QDF_STATUS_E_FAILURE; 11504 } 11505 11506 /*Save fw version from service ready message */ 11507 /*This will be used while sending INIT message */ 11508 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 11509 sizeof(wmi_handle->fw_abi_version)); 11510 11511 return QDF_STATUS_SUCCESS; 11512 } 11513 11514 /** 11515 * ready_extract_init_status_tlv() - Extract init status from ready event 11516 * @wmi_handle: wmi handle 11517 * @param evt_buf: Pointer to event buffer 11518 * 11519 * Return: ready status 11520 */ 11521 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 11522 void *evt_buf) 11523 { 11524 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11525 wmi_ready_event_fixed_param *ev = NULL; 11526 11527 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11528 ev = param_buf->fixed_param; 11529 11530 qdf_print("%s:%d", __func__, ev->status); 11531 11532 return ev->status; 11533 } 11534 11535 /** 11536 * ready_extract_mac_addr_tlv() - extract mac address from ready event 11537 * @wmi_handle: wmi handle 11538 * @param evt_buf: pointer to event buffer 11539 * @param macaddr: Pointer to hold MAC address 11540 * 11541 * Return: QDF_STATUS_SUCCESS for success or error code 11542 */ 11543 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 11544 void *evt_buf, uint8_t *macaddr) 11545 { 11546 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11547 wmi_ready_event_fixed_param *ev = NULL; 11548 11549 11550 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11551 ev = param_buf->fixed_param; 11552 11553 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 11554 11555 return QDF_STATUS_SUCCESS; 11556 } 11557 11558 /** 11559 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 11560 * @wmi_handle: wmi handle 11561 * @param evt_buf: pointer to event buffer 11562 * @param macaddr: Pointer to hold number of MAC addresses 11563 * 11564 * Return: Pointer to addr list 11565 */ 11566 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 11567 void *evt_buf, uint8_t *num_mac) 11568 { 11569 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11570 wmi_ready_event_fixed_param *ev = NULL; 11571 11572 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11573 ev = param_buf->fixed_param; 11574 11575 *num_mac = ev->num_extra_mac_addr; 11576 11577 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 11578 } 11579 11580 /** 11581 * extract_ready_params_tlv() - Extract data from ready event apart from 11582 * status, macaddr and version. 11583 * @wmi_handle: Pointer to WMI handle. 11584 * @evt_buf: Pointer to Ready event buffer. 11585 * @ev_param: Pointer to host defined struct to copy the data from event. 11586 * 11587 * Return: QDF_STATUS_SUCCESS on success. 11588 */ 11589 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 11590 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 11591 { 11592 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 11593 wmi_ready_event_fixed_param *ev = NULL; 11594 11595 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 11596 ev = param_buf->fixed_param; 11597 11598 ev_param->status = ev->status; 11599 ev_param->num_dscp_table = ev->num_dscp_table; 11600 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 11601 ev_param->num_total_peer = ev->num_total_peers; 11602 ev_param->num_extra_peer = ev->num_extra_peers; 11603 /* Agile_capability in ready event is supported in TLV target, 11604 * as per aDFS FR 11605 */ 11606 ev_param->max_ast_index = ev->max_ast_index; 11607 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 11608 ev_param->agile_capability = 1; 11609 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 11610 11611 return QDF_STATUS_SUCCESS; 11612 } 11613 11614 /** 11615 * extract_dbglog_data_len_tlv() - extract debuglog data length 11616 * @wmi_handle: wmi handle 11617 * @param evt_buf: pointer to event buffer 11618 * 11619 * Return: length 11620 */ 11621 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 11622 void *evt_buf, uint32_t *len) 11623 { 11624 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 11625 11626 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 11627 11628 *len = param_buf->num_bufp; 11629 11630 return param_buf->bufp; 11631 } 11632 11633 11634 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 11635 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 11636 #else 11637 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 11638 ((_status) & WMI_RXERR_DECRYPT) 11639 #endif 11640 11641 /** 11642 * extract_mgmt_rx_params_tlv() - extract management rx params from event 11643 * @wmi_handle: wmi handle 11644 * @param evt_buf: pointer to event buffer 11645 * @param hdr: Pointer to hold header 11646 * @param bufp: Pointer to hold pointer to rx param buffer 11647 * 11648 * Return: QDF_STATUS_SUCCESS for success or error code 11649 */ 11650 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 11651 void *evt_buf, struct mgmt_rx_event_params *hdr, 11652 uint8_t **bufp) 11653 { 11654 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 11655 wmi_mgmt_rx_hdr *ev_hdr = NULL; 11656 int i; 11657 11658 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 11659 if (!param_tlvs) { 11660 wmi_err("Get NULL point message from FW"); 11661 return QDF_STATUS_E_INVAL; 11662 } 11663 11664 ev_hdr = param_tlvs->hdr; 11665 if (!hdr) { 11666 wmi_err("Rx event is NULL"); 11667 return QDF_STATUS_E_INVAL; 11668 } 11669 11670 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 11671 wmi_err("RX mgmt frame decrypt error, discard it"); 11672 return QDF_STATUS_E_INVAL; 11673 } 11674 11675 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 11676 wmi_err("Rx mgmt frame length mismatch, discard it"); 11677 return QDF_STATUS_E_INVAL; 11678 } 11679 11680 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11681 wmi_handle, 11682 ev_hdr->pdev_id); 11683 hdr->chan_freq = ev_hdr->chan_freq; 11684 hdr->channel = ev_hdr->channel; 11685 hdr->snr = ev_hdr->snr; 11686 hdr->rate = ev_hdr->rate; 11687 hdr->phy_mode = ev_hdr->phy_mode; 11688 hdr->buf_len = ev_hdr->buf_len; 11689 hdr->status = ev_hdr->status; 11690 hdr->flags = ev_hdr->flags; 11691 hdr->rssi = ev_hdr->rssi; 11692 hdr->tsf_delta = ev_hdr->tsf_delta; 11693 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 11694 for (i = 0; i < ATH_MAX_ANTENNA; i++) 11695 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 11696 11697 *bufp = param_tlvs->bufp; 11698 11699 return QDF_STATUS_SUCCESS; 11700 } 11701 11702 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 11703 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 11704 { 11705 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 11706 wmi_mgmt_rx_params_ext *ext_params_tlv; 11707 wmi_mgmt_rx_hdr *ev_hdr; 11708 11709 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 11710 if (!param_tlvs) { 11711 wmi_err("param_tlvs is NULL"); 11712 return QDF_STATUS_E_INVAL; 11713 } 11714 11715 ev_hdr = param_tlvs->hdr; 11716 if (!ev_hdr) { 11717 wmi_err("Rx event is NULL"); 11718 return QDF_STATUS_E_INVAL; 11719 } 11720 11721 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 11722 if (ext_params_tlv) { 11723 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 11724 ext_params_tlv->mgmt_rx_params_ext_dword1); 11725 if (ext_params->ba_win_size > 1024) { 11726 wmi_err("ba win size from TLV is Invalid"); 11727 return QDF_STATUS_E_INVAL; 11728 } 11729 11730 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 11731 ext_params_tlv->mgmt_rx_params_ext_dword1); 11732 if (ext_params->reo_win_size > 2048) { 11733 wmi_err("reo win size from TLV is Invalid"); 11734 return QDF_STATUS_E_INVAL; 11735 } 11736 } else { 11737 ext_params->ba_win_size = 0; 11738 ext_params->reo_win_size = 0; 11739 } 11740 11741 return QDF_STATUS_SUCCESS; 11742 } 11743 11744 #ifdef WLAN_MGMT_RX_REO_SUPPORT 11745 /** 11746 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 11747 * @wmi_handle: wmi handle 11748 * @evt_buf: pointer to event buffer 11749 * @params: Pointer to MGMT Rx REO parameters 11750 * 11751 * Return: QDF_STATUS_SUCCESS for success or error code 11752 */ 11753 static QDF_STATUS 11754 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 11755 void *evt_buf, 11756 struct mgmt_rx_reo_params *params) 11757 { 11758 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 11759 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 11760 11761 param_tlvs = evt_buf; 11762 if (!param_tlvs) { 11763 wmi_err("param_tlvs is NULL"); 11764 return QDF_STATUS_E_INVAL; 11765 } 11766 11767 ev_hdr = param_tlvs->hdr; 11768 if (!params) { 11769 wmi_err("Rx REO parameters is NULL"); 11770 return QDF_STATUS_E_INVAL; 11771 } 11772 11773 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11774 wmi_handle, 11775 ev_hdr->pdev_id); 11776 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 11777 ev_hdr->mgmt_pkt_ctr_info); 11778 params->global_timestamp = ev_hdr->global_timestamp; 11779 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 11780 ev_hdr->mgmt_pkt_ctr_info); 11781 params->duration_us = ev_hdr->rx_ppdu_duration_us; 11782 params->start_timestamp = params->global_timestamp; 11783 params->end_timestamp = params->start_timestamp + 11784 params->duration_us; 11785 11786 return QDF_STATUS_SUCCESS; 11787 } 11788 11789 /** 11790 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 11791 * MGMT_RX_EVENT_ID 11792 * @wmi_handle: wmi handle 11793 * @evt_buf: pointer to event buffer 11794 * @params: Pointer to MGMT Rx REO parameters 11795 * 11796 * Return: QDF_STATUS_SUCCESS for success or error code 11797 */ 11798 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 11799 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 11800 { 11801 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 11802 wmi_mgmt_rx_reo_params *reo_params_tlv; 11803 wmi_mgmt_rx_hdr *ev_hdr; 11804 11805 param_tlvs = evt_buf; 11806 if (!param_tlvs) { 11807 wmi_err("param_tlvs is NULL"); 11808 return QDF_STATUS_E_INVAL; 11809 } 11810 11811 ev_hdr = param_tlvs->hdr; 11812 if (!ev_hdr) { 11813 wmi_err("Rx event is NULL"); 11814 return QDF_STATUS_E_INVAL; 11815 } 11816 11817 reo_params_tlv = param_tlvs->reo_params; 11818 if (!reo_params_tlv) { 11819 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 11820 return QDF_STATUS_E_INVAL; 11821 } 11822 11823 if (!reo_params) { 11824 wmi_err("MGMT Rx REO params is NULL"); 11825 return QDF_STATUS_E_INVAL; 11826 } 11827 11828 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11829 wmi_handle, 11830 ev_hdr->pdev_id); 11831 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 11832 reo_params_tlv->mgmt_pkt_ctr_link_info); 11833 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 11834 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 11835 reo_params_tlv->mgmt_pkt_ctr_link_info); 11836 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 11837 reo_params->start_timestamp = reo_params->global_timestamp; 11838 reo_params->end_timestamp = reo_params->start_timestamp + 11839 reo_params->duration_us; 11840 11841 return QDF_STATUS_SUCCESS; 11842 } 11843 11844 /** 11845 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 11846 * configuration command 11847 * @wmi_handle: wmi handle 11848 * @pdev_id: pdev ID of the radio 11849 * @filter: Pointer to MGMT Rx REO filter 11850 * 11851 * Return: QDF_STATUS_SUCCESS for success or error code 11852 */ 11853 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 11854 wmi_unified_t wmi_handle, 11855 uint8_t pdev_id, 11856 struct mgmt_rx_reo_filter *filter) 11857 { 11858 QDF_STATUS ret; 11859 wmi_buf_t buf; 11860 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 11861 size_t len = sizeof(*cmd); 11862 11863 if (!filter) { 11864 wmi_err("mgmt_rx_reo_filter is NULL"); 11865 return QDF_STATUS_E_INVAL; 11866 } 11867 11868 buf = wmi_buf_alloc(wmi_handle, len); 11869 if (!buf) { 11870 wmi_err("wmi_buf_alloc failed"); 11871 return QDF_STATUS_E_NOMEM; 11872 } 11873 11874 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 11875 wmi_buf_data(buf); 11876 11877 WMITLV_SET_HDR(&cmd->tlv_header, 11878 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 11879 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 11880 11881 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 11882 wmi_handle, 11883 pdev_id); 11884 cmd->filter_low = filter->low; 11885 cmd->filter_high = filter->high; 11886 11887 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 11888 ret = wmi_unified_cmd_send( 11889 wmi_handle, buf, len, 11890 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 11891 11892 if (QDF_IS_STATUS_ERROR(ret)) { 11893 wmi_err("Failed to send WMI command"); 11894 wmi_buf_free(buf); 11895 } 11896 11897 return ret; 11898 } 11899 #endif 11900 11901 /** 11902 * extract_frame_pn_params_tlv() - extract PN params from event 11903 * @wmi_handle: wmi handle 11904 * @evt_buf: pointer to event buffer 11905 * @pn_params: Pointer to Frame PN params 11906 * 11907 * Return: QDF_STATUS_SUCCESS for success or error code 11908 */ 11909 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 11910 void *evt_buf, 11911 struct frame_pn_params *pn_params) 11912 { 11913 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 11914 wmi_frame_pn_params *pn_params_tlv; 11915 11916 if (!is_service_enabled_tlv(wmi_handle, 11917 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 11918 return QDF_STATUS_SUCCESS; 11919 11920 param_tlvs = evt_buf; 11921 if (!param_tlvs) { 11922 wmi_err("Got NULL point message from FW"); 11923 return QDF_STATUS_E_INVAL; 11924 } 11925 11926 if (!pn_params) { 11927 wmi_err("PN Params is NULL"); 11928 return QDF_STATUS_E_INVAL; 11929 } 11930 11931 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 11932 * found by target 11933 */ 11934 pn_params_tlv = param_tlvs->pn_params; 11935 if (!pn_params_tlv) 11936 return QDF_STATUS_SUCCESS; 11937 11938 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 11939 sizeof(pn_params->curr_pn)); 11940 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 11941 sizeof(pn_params->prev_pn)); 11942 11943 return QDF_STATUS_SUCCESS; 11944 } 11945 11946 /** 11947 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 11948 * @wmi_handle: wmi handle 11949 * @param evt_buf: pointer to event buffer 11950 * @param param: Pointer to hold roam param 11951 * 11952 * Return: QDF_STATUS_SUCCESS for success or error code 11953 */ 11954 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 11955 void *evt_buf, wmi_host_roam_event *param) 11956 { 11957 WMI_ROAM_EVENTID_param_tlvs *param_buf; 11958 wmi_roam_event_fixed_param *evt; 11959 11960 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 11961 if (!param_buf) { 11962 wmi_err("Invalid roam event buffer"); 11963 return QDF_STATUS_E_INVAL; 11964 } 11965 11966 evt = param_buf->fixed_param; 11967 qdf_mem_zero(param, sizeof(*param)); 11968 11969 param->vdev_id = evt->vdev_id; 11970 param->reason = evt->reason; 11971 param->rssi = evt->rssi; 11972 11973 return QDF_STATUS_SUCCESS; 11974 } 11975 11976 /** 11977 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 11978 * @wmi_handle: wmi handle 11979 * @param evt_buf: pointer to event buffer 11980 * @param param: Pointer to hold vdev scan param 11981 * 11982 * Return: QDF_STATUS_SUCCESS for success or error code 11983 */ 11984 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 11985 void *evt_buf, struct scan_event *param) 11986 { 11987 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 11988 wmi_scan_event_fixed_param *evt = NULL; 11989 11990 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 11991 evt = param_buf->fixed_param; 11992 11993 qdf_mem_zero(param, sizeof(*param)); 11994 11995 switch (evt->event) { 11996 case WMI_SCAN_EVENT_STARTED: 11997 param->type = SCAN_EVENT_TYPE_STARTED; 11998 break; 11999 case WMI_SCAN_EVENT_COMPLETED: 12000 param->type = SCAN_EVENT_TYPE_COMPLETED; 12001 break; 12002 case WMI_SCAN_EVENT_BSS_CHANNEL: 12003 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 12004 break; 12005 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 12006 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 12007 break; 12008 case WMI_SCAN_EVENT_DEQUEUED: 12009 param->type = SCAN_EVENT_TYPE_DEQUEUED; 12010 break; 12011 case WMI_SCAN_EVENT_PREEMPTED: 12012 param->type = SCAN_EVENT_TYPE_PREEMPTED; 12013 break; 12014 case WMI_SCAN_EVENT_START_FAILED: 12015 param->type = SCAN_EVENT_TYPE_START_FAILED; 12016 break; 12017 case WMI_SCAN_EVENT_RESTARTED: 12018 param->type = SCAN_EVENT_TYPE_RESTARTED; 12019 break; 12020 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 12021 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 12022 break; 12023 case WMI_SCAN_EVENT_MAX: 12024 default: 12025 param->type = SCAN_EVENT_TYPE_MAX; 12026 break; 12027 }; 12028 12029 switch (evt->reason) { 12030 case WMI_SCAN_REASON_NONE: 12031 param->reason = SCAN_REASON_NONE; 12032 break; 12033 case WMI_SCAN_REASON_COMPLETED: 12034 param->reason = SCAN_REASON_COMPLETED; 12035 break; 12036 case WMI_SCAN_REASON_CANCELLED: 12037 param->reason = SCAN_REASON_CANCELLED; 12038 break; 12039 case WMI_SCAN_REASON_PREEMPTED: 12040 param->reason = SCAN_REASON_PREEMPTED; 12041 break; 12042 case WMI_SCAN_REASON_TIMEDOUT: 12043 param->reason = SCAN_REASON_TIMEDOUT; 12044 break; 12045 case WMI_SCAN_REASON_INTERNAL_FAILURE: 12046 param->reason = SCAN_REASON_INTERNAL_FAILURE; 12047 break; 12048 case WMI_SCAN_REASON_SUSPENDED: 12049 param->reason = SCAN_REASON_SUSPENDED; 12050 break; 12051 case WMI_SCAN_REASON_DFS_VIOLATION: 12052 param->reason = SCAN_REASON_DFS_VIOLATION; 12053 break; 12054 case WMI_SCAN_REASON_MAX: 12055 param->reason = SCAN_REASON_MAX; 12056 break; 12057 default: 12058 param->reason = SCAN_REASON_MAX; 12059 break; 12060 }; 12061 12062 param->chan_freq = evt->channel_freq; 12063 param->requester = evt->requestor; 12064 param->scan_id = evt->scan_id; 12065 param->vdev_id = evt->vdev_id; 12066 param->timestamp = evt->tsf_timestamp; 12067 12068 return QDF_STATUS_SUCCESS; 12069 } 12070 12071 #ifdef FEATURE_WLAN_SCAN_PNO 12072 /** 12073 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 12074 * @wmi_handle: pointer to WMI handle 12075 * @evt_buf: pointer to WMI event buffer 12076 * @param: pointer to scan event param for NLO match 12077 * 12078 * Return: QDF_STATUS_SUCCESS for success or error code 12079 */ 12080 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 12081 void *evt_buf, 12082 struct scan_event *param) 12083 { 12084 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 12085 wmi_nlo_event *evt = param_buf->fixed_param; 12086 12087 qdf_mem_zero(param, sizeof(*param)); 12088 12089 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 12090 param->vdev_id = evt->vdev_id; 12091 12092 return QDF_STATUS_SUCCESS; 12093 } 12094 12095 /** 12096 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 12097 * @wmi_handle: pointer to WMI handle 12098 * @evt_buf: pointer to WMI event buffer 12099 * @param: pointer to scan event param for NLO complete 12100 * 12101 * Return: QDF_STATUS_SUCCESS for success or error code 12102 */ 12103 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 12104 void *evt_buf, 12105 struct scan_event *param) 12106 { 12107 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 12108 wmi_nlo_event *evt = param_buf->fixed_param; 12109 12110 qdf_mem_zero(param, sizeof(*param)); 12111 12112 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 12113 param->vdev_id = evt->vdev_id; 12114 12115 return QDF_STATUS_SUCCESS; 12116 } 12117 #endif 12118 12119 /** 12120 * extract_unit_test_tlv() - extract unit test data 12121 * @wmi_handle: wmi handle 12122 * @param evt_buf: pointer to event buffer 12123 * @param unit_test: pointer to hold unit test data 12124 * @param maxspace: Amount of space in evt_buf 12125 * 12126 * Return: QDF_STATUS_SUCCESS for success or error code 12127 */ 12128 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 12129 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 12130 { 12131 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 12132 wmi_unit_test_event_fixed_param *ev_param; 12133 uint32_t num_bufp; 12134 uint32_t copy_size; 12135 uint8_t *bufp; 12136 12137 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 12138 ev_param = param_buf->fixed_param; 12139 bufp = param_buf->bufp; 12140 num_bufp = param_buf->num_bufp; 12141 unit_test->vdev_id = ev_param->vdev_id; 12142 unit_test->module_id = ev_param->module_id; 12143 unit_test->diag_token = ev_param->diag_token; 12144 unit_test->flag = ev_param->flag; 12145 unit_test->payload_len = ev_param->payload_len; 12146 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 12147 ev_param->vdev_id, 12148 ev_param->module_id, 12149 ev_param->diag_token, 12150 ev_param->flag); 12151 wmi_debug("Unit-test data given below %d", num_bufp); 12152 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 12153 bufp, num_bufp); 12154 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 12155 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 12156 unit_test->buffer_len = copy_size; 12157 12158 return QDF_STATUS_SUCCESS; 12159 } 12160 12161 /** 12162 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 12163 * @wmi_handle: wmi handle 12164 * @param evt_buf: pointer to event buffer 12165 * @param index: Index into extended pdev stats 12166 * @param pdev_ext_stats: Pointer to hold extended pdev stats 12167 * 12168 * Return: QDF_STATUS_SUCCESS for success or error code 12169 */ 12170 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 12171 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 12172 { 12173 return QDF_STATUS_SUCCESS; 12174 } 12175 12176 /** 12177 * extract_bcn_stats_tlv() - extract bcn stats from event 12178 * @wmi_handle: wmi handle 12179 * @param evt_buf: pointer to event buffer 12180 * @param index: Index into vdev stats 12181 * @param bcn_stats: Pointer to hold bcn stats 12182 * 12183 * Return: QDF_STATUS_SUCCESS for success or error code 12184 */ 12185 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 12186 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 12187 { 12188 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12189 wmi_stats_event_fixed_param *ev_param; 12190 uint8_t *data; 12191 12192 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 12193 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 12194 data = (uint8_t *) param_buf->data; 12195 12196 if (index < ev_param->num_bcn_stats) { 12197 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 12198 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 12199 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 12200 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 12201 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 12202 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 12203 (index * sizeof(wmi_bcn_stats))); 12204 12205 bcn_stats->vdev_id = ev->vdev_id; 12206 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 12207 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 12208 } 12209 12210 return QDF_STATUS_SUCCESS; 12211 } 12212 12213 /** 12214 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 12215 * stats from event 12216 * @wmi_handle: wmi handle 12217 * @param evt_buf: pointer to event buffer 12218 * @param index: Index into vdev stats 12219 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 12220 * 12221 * Return: QDF_STATUS_SUCCESS for success or error code 12222 */ 12223 static QDF_STATUS 12224 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 12225 void *evt_buf, uint32_t index, 12226 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 12227 { 12228 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12229 wmi_vdev_extd_stats *ev; 12230 12231 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12232 12233 if (param_buf->vdev_extd_stats) { 12234 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 12235 index); 12236 vdev_stats->vdev_id = ev->vdev_id; 12237 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 12238 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 12239 vdev_stats->unsolicited_prb_succ_cnt = 12240 ev->unsolicited_prb_succ_cnt; 12241 vdev_stats->unsolicited_prb_fail_cnt = 12242 ev->unsolicited_prb_fail_cnt; 12243 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 12244 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 12245 ev->unsolicited_prb_succ_cnt, 12246 ev->unsolicited_prb_fail_cnt); 12247 } 12248 12249 return QDF_STATUS_SUCCESS; 12250 } 12251 12252 /** 12253 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 12254 * @wmi_handle: wmi handle 12255 * @param evt_buf: pointer to event buffer 12256 * @param index: Index into bcn fault stats 12257 * @param bcnflt_stats: Pointer to hold bcn fault stats 12258 * 12259 * Return: QDF_STATUS_SUCCESS for success or error code 12260 */ 12261 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 12262 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 12263 { 12264 return QDF_STATUS_SUCCESS; 12265 } 12266 12267 /** 12268 * extract_chan_stats_tlv() - extract chan stats from event 12269 * @wmi_handle: wmi handle 12270 * @param evt_buf: pointer to event buffer 12271 * @param index: Index into chan stats 12272 * @param vdev_extd_stats: Pointer to hold chan stats 12273 * 12274 * Return: QDF_STATUS_SUCCESS for success or error code 12275 */ 12276 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 12277 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 12278 { 12279 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12280 wmi_stats_event_fixed_param *ev_param; 12281 uint8_t *data; 12282 12283 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 12284 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 12285 data = (uint8_t *) param_buf->data; 12286 12287 if (index < ev_param->num_chan_stats) { 12288 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 12289 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 12290 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 12291 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 12292 (index * sizeof(wmi_chan_stats))); 12293 12294 12295 /* Non-TLV doesn't have num_chan_stats */ 12296 chan_stats->chan_mhz = ev->chan_mhz; 12297 chan_stats->sampling_period_us = ev->sampling_period_us; 12298 chan_stats->rx_clear_count = ev->rx_clear_count; 12299 chan_stats->tx_duration_us = ev->tx_duration_us; 12300 chan_stats->rx_duration_us = ev->rx_duration_us; 12301 } 12302 12303 return QDF_STATUS_SUCCESS; 12304 } 12305 12306 /** 12307 * extract_profile_ctx_tlv() - extract profile context from event 12308 * @wmi_handle: wmi handle 12309 * @param evt_buf: pointer to event buffer 12310 * @idx: profile stats index to extract 12311 * @param profile_ctx: Pointer to hold profile context 12312 * 12313 * Return: QDF_STATUS_SUCCESS for success or error code 12314 */ 12315 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 12316 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 12317 { 12318 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 12319 12320 wmi_wlan_profile_ctx_t *ev; 12321 12322 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 12323 if (!param_buf) { 12324 wmi_err("Invalid profile data event buf"); 12325 return QDF_STATUS_E_INVAL; 12326 } 12327 12328 ev = param_buf->profile_ctx; 12329 12330 profile_ctx->tot = ev->tot; 12331 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 12332 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 12333 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 12334 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 12335 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 12336 profile_ctx->bin_count = ev->bin_count; 12337 12338 return QDF_STATUS_SUCCESS; 12339 } 12340 12341 /** 12342 * extract_profile_data_tlv() - extract profile data from event 12343 * @wmi_handle: wmi handle 12344 * @param evt_buf: pointer to event buffer 12345 * @param profile_data: Pointer to hold profile data 12346 * 12347 * Return: QDF_STATUS_SUCCESS for success or error code 12348 */ 12349 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 12350 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 12351 { 12352 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 12353 wmi_wlan_profile_t *ev; 12354 12355 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 12356 if (!param_buf) { 12357 wmi_err("Invalid profile data event buf"); 12358 return QDF_STATUS_E_INVAL; 12359 } 12360 12361 ev = ¶m_buf->profile_data[idx]; 12362 profile_data->id = ev->id; 12363 profile_data->cnt = ev->cnt; 12364 profile_data->tot = ev->tot; 12365 profile_data->min = ev->min; 12366 profile_data->max = ev->max; 12367 profile_data->hist_intvl = ev->hist_intvl; 12368 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 12369 12370 return QDF_STATUS_SUCCESS; 12371 } 12372 12373 /** 12374 * extract_pdev_utf_event_tlv() - extract UTF data info from event 12375 * @wmi_handle: WMI handle 12376 * @param evt_buf: Pointer to event buffer 12377 * @param param: Pointer to hold data 12378 * 12379 * Return : QDF_STATUS_SUCCESS for success or error code 12380 */ 12381 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 12382 uint8_t *evt_buf, 12383 struct wmi_host_pdev_utf_event *event) 12384 { 12385 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 12386 struct wmi_host_utf_seg_header_info *seg_hdr; 12387 12388 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 12389 event->data = param_buf->data; 12390 event->datalen = param_buf->num_data; 12391 12392 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 12393 wmi_err("Invalid datalen: %d", event->datalen); 12394 return QDF_STATUS_E_INVAL; 12395 } 12396 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 12397 /* Set pdev_id=1 until FW adds support to include pdev_id */ 12398 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12399 wmi_handle, 12400 seg_hdr->pdev_id); 12401 12402 return QDF_STATUS_SUCCESS; 12403 } 12404 12405 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 12406 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 12407 uint8_t *event, 12408 uint32_t *num_rf_characterization_entries) 12409 { 12410 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 12411 12412 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 12413 if (!param_buf) 12414 return QDF_STATUS_E_INVAL; 12415 12416 *num_rf_characterization_entries = 12417 param_buf->num_wmi_chan_rf_characterization_info; 12418 12419 return QDF_STATUS_SUCCESS; 12420 } 12421 12422 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 12423 uint8_t *event, 12424 uint32_t num_rf_characterization_entries, 12425 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 12426 { 12427 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 12428 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 12429 uint8_t ix; 12430 12431 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 12432 if (!param_buf) 12433 return QDF_STATUS_E_INVAL; 12434 12435 wmi_rf_characterization_entry = 12436 param_buf->wmi_chan_rf_characterization_info; 12437 if (!wmi_rf_characterization_entry) 12438 return QDF_STATUS_E_INVAL; 12439 12440 /* 12441 * Using num_wmi_chan_rf_characterization instead of param_buf value 12442 * since memory for rf_characterization_entries was allocated using 12443 * the former. 12444 */ 12445 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 12446 rf_characterization_entries[ix].freq = 12447 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 12448 &wmi_rf_characterization_entry[ix]); 12449 12450 rf_characterization_entries[ix].bw = 12451 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 12452 &wmi_rf_characterization_entry[ix]); 12453 12454 rf_characterization_entries[ix].chan_metric = 12455 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 12456 &wmi_rf_characterization_entry[ix]); 12457 12458 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 12459 "bw: %u, chan_metric: %u", 12460 ix, rf_characterization_entries[ix].freq, 12461 rf_characterization_entries[ix].bw, 12462 rf_characterization_entries[ix].chan_metric); 12463 } 12464 12465 return QDF_STATUS_SUCCESS; 12466 } 12467 #endif 12468 12469 #ifdef WLAN_FEATURE_11BE 12470 static void 12471 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 12472 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 12473 { 12474 cap->supports_chan_width_320 = 12475 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 12476 } 12477 #else 12478 static void 12479 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 12480 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 12481 { 12482 } 12483 #endif /* WLAN_FEATURE_11BE */ 12484 12485 /** 12486 * extract_chainmask_tables_tlv() - extract chain mask tables from event 12487 * @wmi_handle: wmi handle 12488 * @param evt_buf: pointer to event buffer 12489 * @param param: Pointer to hold evt buf 12490 * 12491 * Return: QDF_STATUS_SUCCESS for success or error code 12492 */ 12493 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 12494 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 12495 { 12496 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12497 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 12498 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12499 uint8_t i = 0, j = 0; 12500 uint32_t num_mac_phy_chainmask_caps = 0; 12501 12502 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12503 if (!param_buf) 12504 return QDF_STATUS_E_INVAL; 12505 12506 hw_caps = param_buf->soc_hw_mode_caps; 12507 if (!hw_caps) 12508 return QDF_STATUS_E_INVAL; 12509 12510 if ((!hw_caps->num_chainmask_tables) || 12511 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 12512 (hw_caps->num_chainmask_tables > 12513 param_buf->num_mac_phy_chainmask_combo)) 12514 return QDF_STATUS_E_INVAL; 12515 12516 chainmask_caps = param_buf->mac_phy_chainmask_caps; 12517 12518 if (!chainmask_caps) 12519 return QDF_STATUS_E_INVAL; 12520 12521 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 12522 if (chainmask_table[i].num_valid_chainmasks > 12523 (UINT_MAX - num_mac_phy_chainmask_caps)) { 12524 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 12525 num_mac_phy_chainmask_caps, i, 12526 chainmask_table[i].num_valid_chainmasks); 12527 return QDF_STATUS_E_INVAL; 12528 } 12529 num_mac_phy_chainmask_caps += 12530 chainmask_table[i].num_valid_chainmasks; 12531 } 12532 12533 if (num_mac_phy_chainmask_caps > 12534 param_buf->num_mac_phy_chainmask_caps) { 12535 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 12536 num_mac_phy_chainmask_caps, 12537 param_buf->num_mac_phy_chainmask_caps); 12538 return QDF_STATUS_E_INVAL; 12539 } 12540 12541 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 12542 12543 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 12544 i); 12545 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 12546 12547 chainmask_table[i].cap_list[j].chainmask = 12548 chainmask_caps->chainmask; 12549 12550 chainmask_table[i].cap_list[j].supports_chan_width_20 = 12551 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 12552 12553 chainmask_table[i].cap_list[j].supports_chan_width_40 = 12554 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 12555 12556 chainmask_table[i].cap_list[j].supports_chan_width_80 = 12557 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 12558 12559 chainmask_table[i].cap_list[j].supports_chan_width_160 = 12560 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 12561 12562 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 12563 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 12564 12565 chainmask_table[i].cap_list[j].chain_mask_2G = 12566 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 12567 12568 chainmask_table[i].cap_list[j].chain_mask_5G = 12569 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 12570 12571 chainmask_table[i].cap_list[j].chain_mask_tx = 12572 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 12573 12574 chainmask_table[i].cap_list[j].chain_mask_rx = 12575 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 12576 12577 chainmask_table[i].cap_list[j].supports_aDFS = 12578 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 12579 12580 chainmask_table[i].cap_list[j].supports_aSpectral = 12581 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 12582 12583 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 12584 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 12585 12586 chainmask_table[i].cap_list[j].supports_aDFS_160 = 12587 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 12588 12589 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 12590 chainmask_caps); 12591 12592 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 12593 chainmask_caps->supported_flags, 12594 chainmask_caps->chainmask); 12595 chainmask_caps++; 12596 } 12597 } 12598 12599 return QDF_STATUS_SUCCESS; 12600 } 12601 12602 /** 12603 * extract_service_ready_ext_tlv() - extract basic extended service ready params 12604 * from event 12605 * @wmi_handle: wmi handle 12606 * @param evt_buf: pointer to event buffer 12607 * @param param: Pointer to hold evt buf 12608 * 12609 * Return: QDF_STATUS_SUCCESS for success or error code 12610 */ 12611 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 12612 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 12613 { 12614 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12615 wmi_service_ready_ext_event_fixed_param *ev; 12616 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12617 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 12618 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 12619 uint8_t i = 0; 12620 12621 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12622 if (!param_buf) 12623 return QDF_STATUS_E_INVAL; 12624 12625 ev = param_buf->fixed_param; 12626 if (!ev) 12627 return QDF_STATUS_E_INVAL; 12628 12629 /* Move this to host based bitmap */ 12630 param->default_conc_scan_config_bits = 12631 ev->default_conc_scan_config_bits; 12632 param->default_fw_config_bits = ev->default_fw_config_bits; 12633 param->he_cap_info = ev->he_cap_info; 12634 param->mpdu_density = ev->mpdu_density; 12635 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 12636 param->fw_build_vers_ext = ev->fw_build_vers_ext; 12637 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 12638 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 12639 param->max_bssid_indicator = ev->max_bssid_indicator; 12640 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 12641 12642 hw_caps = param_buf->soc_hw_mode_caps; 12643 if (hw_caps) 12644 param->num_hw_modes = hw_caps->num_hw_modes; 12645 else 12646 param->num_hw_modes = 0; 12647 12648 reg_caps = param_buf->soc_hal_reg_caps; 12649 if (reg_caps) 12650 param->num_phy = reg_caps->num_phy; 12651 else 12652 param->num_phy = 0; 12653 12654 if (hw_caps) { 12655 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 12656 wmi_nofl_debug("Num chain mask tables: %d", 12657 hw_caps->num_chainmask_tables); 12658 } else 12659 param->num_chainmask_tables = 0; 12660 12661 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 12662 param->num_chainmask_tables > 12663 param_buf->num_mac_phy_chainmask_combo) { 12664 wmi_err_rl("num_chainmask_tables is OOB: %u", 12665 param->num_chainmask_tables); 12666 return QDF_STATUS_E_INVAL; 12667 } 12668 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 12669 12670 if (!chain_mask_combo) 12671 return QDF_STATUS_SUCCESS; 12672 12673 wmi_nofl_debug("Dumping chain mask combo data"); 12674 12675 for (i = 0; i < param->num_chainmask_tables; i++) { 12676 12677 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 12678 chain_mask_combo->chainmask_table_id, 12679 chain_mask_combo->num_valid_chainmask); 12680 12681 param->chainmask_table[i].table_id = 12682 chain_mask_combo->chainmask_table_id; 12683 param->chainmask_table[i].num_valid_chainmasks = 12684 chain_mask_combo->num_valid_chainmask; 12685 chain_mask_combo++; 12686 } 12687 wmi_nofl_debug("chain mask combo end"); 12688 12689 return QDF_STATUS_SUCCESS; 12690 } 12691 12692 #if defined(CONFIG_AFC_SUPPORT) 12693 /** 12694 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 12695 * type from event 12696 * @ev: pointer to event fixed param 12697 * @param: Pointer to hold the params 12698 * 12699 * Return: void 12700 */ 12701 static void 12702 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 12703 struct wlan_psoc_host_service_ext2_param *param) 12704 { 12705 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 12706 enum reg_afc_dev_deploy_type reg_afc_dev_type; 12707 12708 tgt_afc_dev_type = ev->afc_deployment_type; 12709 switch (tgt_afc_dev_type) { 12710 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 12711 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 12712 break; 12713 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 12714 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 12715 break; 12716 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 12717 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 12718 break; 12719 default: 12720 wmi_err("invalid afc deloyment %d", tgt_afc_dev_type); 12721 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 12722 break; 12723 } 12724 param->afc_dev_type = reg_afc_dev_type; 12725 12726 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 12727 } 12728 #else 12729 static inline void 12730 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 12731 struct wlan_psoc_host_service_ext2_param *param) 12732 { 12733 } 12734 #endif 12735 12736 /** 12737 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 12738 * event 12739 * @wmi_handle: wmi handle 12740 * @event: pointer to event buffer 12741 * @param: Pointer to hold the params 12742 * 12743 * Return: QDF_STATUS_SUCCESS for success or error code 12744 */ 12745 static QDF_STATUS 12746 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 12747 struct wlan_psoc_host_service_ext2_param *param) 12748 { 12749 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12750 wmi_service_ready_ext2_event_fixed_param *ev; 12751 12752 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12753 if (!param_buf) 12754 return QDF_STATUS_E_INVAL; 12755 12756 ev = param_buf->fixed_param; 12757 if (!ev) 12758 return QDF_STATUS_E_INVAL; 12759 12760 param->reg_db_version_major = 12761 WMI_REG_DB_VERSION_MAJOR_GET( 12762 ev->reg_db_version); 12763 param->reg_db_version_minor = 12764 WMI_REG_DB_VERSION_MINOR_GET( 12765 ev->reg_db_version); 12766 param->bdf_reg_db_version_major = 12767 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 12768 ev->reg_db_version); 12769 param->bdf_reg_db_version_minor = 12770 WMI_BDF_REG_DB_VERSION_MINOR_GET( 12771 ev->reg_db_version); 12772 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 12773 12774 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 12775 12776 if (param_buf->nan_cap) 12777 param->max_ndp_sessions = 12778 param_buf->nan_cap->max_ndp_sessions; 12779 else 12780 param->max_ndp_sessions = 0; 12781 12782 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 12783 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 12784 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 12785 ev->max_user_per_ppdu_ofdma); 12786 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 12787 ev->max_user_per_ppdu_ofdma); 12788 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 12789 ev->max_user_per_ppdu_mumimo); 12790 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 12791 ev->max_user_per_ppdu_mumimo); 12792 param->target_cap_flags = ev->target_cap_flags; 12793 wmi_debug("htt peer data :%d", ev->target_cap_flags); 12794 12795 extract_svc_rdy_ext2_afc_tlv(ev, param); 12796 12797 return QDF_STATUS_SUCCESS; 12798 } 12799 12800 /* 12801 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 12802 * service ready ext 2 12803 * 12804 * @wmi_handle: wmi handle 12805 * @event: pointer to event buffer 12806 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 12807 * it indicates async SBS mode is supported, and 12808 * lower-band/higher band to MAC mapping is 12809 * switch-able. unit: mhz. examples 5180, 5320 12810 * 12811 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 12812 */ 12813 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 12814 wmi_unified_t wmi_handle, uint8_t *event, 12815 uint32_t *sbs_lower_band_end_freq) 12816 { 12817 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12818 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 12819 12820 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12821 if (!param_buf) 12822 return QDF_STATUS_E_INVAL; 12823 12824 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 12825 if (!dbs_or_sbs_caps) 12826 return QDF_STATUS_E_INVAL; 12827 12828 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 12829 12830 return QDF_STATUS_SUCCESS; 12831 } 12832 12833 /** 12834 * extract_sar_cap_service_ready_ext_tlv() - 12835 * extract SAR cap from service ready event 12836 * @wmi_handle: wmi handle 12837 * @event: pointer to event buffer 12838 * @ext_param: extended target info 12839 * 12840 * Return: QDF_STATUS_SUCCESS for success or error code 12841 */ 12842 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 12843 wmi_unified_t wmi_handle, 12844 uint8_t *event, 12845 struct wlan_psoc_host_service_ext_param *ext_param) 12846 { 12847 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12848 WMI_SAR_CAPABILITIES *sar_caps; 12849 12850 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 12851 12852 if (!param_buf) 12853 return QDF_STATUS_E_INVAL; 12854 12855 sar_caps = param_buf->sar_caps; 12856 if (sar_caps) 12857 ext_param->sar_version = sar_caps->active_version; 12858 else 12859 ext_param->sar_version = 0; 12860 12861 return QDF_STATUS_SUCCESS; 12862 } 12863 12864 /** 12865 * extract_hw_mode_cap_service_ready_ext_tlv() - 12866 * extract HW mode cap from service ready event 12867 * @wmi_handle: wmi handle 12868 * @param evt_buf: pointer to event buffer 12869 * @param param: Pointer to hold evt buf 12870 * @param hw_mode_idx: hw mode idx should be less than num_mode 12871 * 12872 * Return: QDF_STATUS_SUCCESS for success or error code 12873 */ 12874 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 12875 wmi_unified_t wmi_handle, 12876 uint8_t *event, uint8_t hw_mode_idx, 12877 struct wlan_psoc_host_hw_mode_caps *param) 12878 { 12879 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12880 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12881 12882 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12883 if (!param_buf) 12884 return QDF_STATUS_E_INVAL; 12885 12886 hw_caps = param_buf->soc_hw_mode_caps; 12887 if (!hw_caps) 12888 return QDF_STATUS_E_INVAL; 12889 12890 if (!hw_caps->num_hw_modes || 12891 !param_buf->hw_mode_caps || 12892 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 12893 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 12894 return QDF_STATUS_E_INVAL; 12895 12896 if (hw_mode_idx >= hw_caps->num_hw_modes) 12897 return QDF_STATUS_E_INVAL; 12898 12899 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 12900 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 12901 12902 param->hw_mode_config_type = 12903 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 12904 12905 return QDF_STATUS_SUCCESS; 12906 } 12907 12908 /** 12909 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 12910 * @param param: host mac phy capabilities 12911 * @param mac_phy_caps: mac phy capabilities 12912 * 12913 * Return: void 12914 */ 12915 #ifdef WLAN_FEATURE_11BE 12916 static void 12917 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 12918 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12919 { 12920 param->supports_11be = 12921 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 12922 12923 wmi_debug("11be support %d", param->supports_11be); 12924 } 12925 #else 12926 static void 12927 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 12928 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12929 { 12930 } 12931 #endif 12932 12933 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 12934 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 12935 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12936 { 12937 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 12938 } 12939 #else 12940 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 12941 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 12942 { 12943 } 12944 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 12945 12946 /** 12947 * extract_mac_phy_cap_service_ready_ext_tlv() - 12948 * extract MAC phy cap from service ready event 12949 * @wmi_handle: wmi handle 12950 * @param evt_buf: pointer to event buffer 12951 * @param param: Pointer to hold evt buf 12952 * @param hw_mode_idx: hw mode idx should be less than num_mode 12953 * @param phy_id: phy id within hw_mode 12954 * 12955 * Return: QDF_STATUS_SUCCESS for success or error code 12956 */ 12957 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 12958 wmi_unified_t wmi_handle, 12959 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 12960 struct wlan_psoc_host_mac_phy_caps *param) 12961 { 12962 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12963 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 12964 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 12965 uint32_t phy_map; 12966 uint8_t hw_idx, phy_idx = 0, pdev_id; 12967 12968 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 12969 if (!param_buf) 12970 return QDF_STATUS_E_INVAL; 12971 12972 hw_caps = param_buf->soc_hw_mode_caps; 12973 if (!hw_caps) 12974 return QDF_STATUS_E_INVAL; 12975 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 12976 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 12977 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 12978 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 12979 return QDF_STATUS_E_INVAL; 12980 } 12981 12982 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 12983 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 12984 break; 12985 12986 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 12987 while (phy_map) { 12988 phy_map >>= 1; 12989 phy_idx++; 12990 } 12991 } 12992 12993 if (hw_idx == hw_caps->num_hw_modes) 12994 return QDF_STATUS_E_INVAL; 12995 12996 phy_idx += phy_id; 12997 if (phy_idx >= param_buf->num_mac_phy_caps) 12998 return QDF_STATUS_E_INVAL; 12999 13000 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 13001 13002 param->hw_mode_id = mac_phy_caps->hw_mode_id; 13003 param->phy_idx = phy_idx; 13004 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 13005 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13006 wmi_handle, 13007 pdev_id); 13008 param->tgt_pdev_id = pdev_id; 13009 extract_hw_link_id(param, mac_phy_caps); 13010 param->phy_id = mac_phy_caps->phy_id; 13011 param->supports_11b = 13012 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 13013 param->supports_11g = 13014 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 13015 param->supports_11a = 13016 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 13017 param->supports_11n = 13018 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 13019 param->supports_11ac = 13020 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 13021 param->supports_11ax = 13022 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 13023 13024 extract_service_ready_11be_support(param, mac_phy_caps); 13025 13026 param->supported_bands = mac_phy_caps->supported_bands; 13027 param->ampdu_density = mac_phy_caps->ampdu_density; 13028 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 13029 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 13030 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 13031 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 13032 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 13033 mac_phy_caps->he_cap_info_2G; 13034 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 13035 mac_phy_caps->he_cap_info_2G_ext; 13036 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 13037 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 13038 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 13039 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 13040 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 13041 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 13042 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 13043 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 13044 mac_phy_caps->he_cap_info_5G; 13045 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 13046 mac_phy_caps->he_cap_info_5G_ext; 13047 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 13048 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 13049 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 13050 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 13051 qdf_mem_copy(¶m->he_cap_phy_info_2G, 13052 &mac_phy_caps->he_cap_phy_info_2G, 13053 sizeof(param->he_cap_phy_info_2G)); 13054 qdf_mem_copy(¶m->he_cap_phy_info_5G, 13055 &mac_phy_caps->he_cap_phy_info_5G, 13056 sizeof(param->he_cap_phy_info_5G)); 13057 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 13058 sizeof(param->he_ppet2G)); 13059 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 13060 sizeof(param->he_ppet5G)); 13061 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 13062 param->lmac_id = mac_phy_caps->lmac_id; 13063 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 13064 (mac_phy_caps->wireless_modes); 13065 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 13066 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 13067 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 13068 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 13069 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 13070 mac_phy_caps->nss_ratio); 13071 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 13072 13073 return QDF_STATUS_SUCCESS; 13074 } 13075 13076 /** 13077 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 13078 * @param param: host ext2 mac phy capabilities 13079 * @param mac_phy_caps: ext mac phy capabilities 13080 * 13081 * Return: void 13082 */ 13083 #ifdef WLAN_FEATURE_11BE 13084 static void extract_mac_phy_cap_ehtcaps( 13085 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13086 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13087 { 13088 uint32_t i; 13089 13090 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 13091 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 13092 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 13093 13094 qdf_mem_copy(¶m->eht_cap_info_2G, 13095 &mac_phy_caps->eht_cap_mac_info_2G, 13096 sizeof(param->eht_cap_info_2G)); 13097 qdf_mem_copy(¶m->eht_cap_info_5G, 13098 &mac_phy_caps->eht_cap_mac_info_5G, 13099 sizeof(param->eht_cap_info_5G)); 13100 13101 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 13102 &mac_phy_caps->eht_cap_phy_info_2G, 13103 sizeof(param->eht_cap_phy_info_2G)); 13104 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 13105 &mac_phy_caps->eht_cap_phy_info_5G, 13106 sizeof(param->eht_cap_phy_info_5G)); 13107 13108 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 13109 &mac_phy_caps->eht_supp_mcs_ext_2G, 13110 sizeof(param->eht_supp_mcs_ext_2G)); 13111 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 13112 &mac_phy_caps->eht_supp_mcs_ext_5G, 13113 sizeof(param->eht_supp_mcs_ext_5G)); 13114 13115 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 13116 sizeof(param->eht_ppet2G)); 13117 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 13118 sizeof(param->eht_ppet5G)); 13119 13120 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", 13121 mac_phy_caps->eht_cap_mac_info_2G[0], 13122 mac_phy_caps->eht_cap_mac_info_5G[0], 13123 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 13124 mac_phy_caps->eht_cap_info_internal); 13125 13126 wmi_nofl_debug("EHT phy caps: "); 13127 13128 wmi_nofl_debug("2G:"); 13129 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 13130 wmi_nofl_debug("index %d value %x", 13131 i, param->eht_cap_phy_info_2G[i]); 13132 } 13133 wmi_nofl_debug("5G:"); 13134 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 13135 wmi_nofl_debug("index %d value %x", 13136 i, param->eht_cap_phy_info_5G[i]); 13137 } 13138 wmi_nofl_debug("2G MCS ext Map:"); 13139 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 13140 wmi_nofl_debug("index %d value %x", 13141 i, param->eht_supp_mcs_ext_2G[i]); 13142 } 13143 wmi_nofl_debug("5G MCS ext Map:"); 13144 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 13145 wmi_nofl_debug("index %d value %x", 13146 i, param->eht_supp_mcs_ext_5G[i]); 13147 } 13148 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 13149 param->eht_ppet2G.numss_m1, 13150 param->eht_ppet2G.ru_bit_mask); 13151 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 13152 wmi_nofl_debug("index %d value %x", 13153 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 13154 } 13155 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 13156 param->eht_ppet5G.numss_m1, 13157 param->eht_ppet5G.ru_bit_mask); 13158 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 13159 wmi_nofl_debug("index %d value %x", 13160 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 13161 } 13162 } 13163 #else 13164 static void extract_mac_phy_cap_ehtcaps( 13165 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 13166 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 13167 { 13168 } 13169 #endif 13170 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 13171 wmi_unified_t wmi_handle, 13172 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 13173 uint8_t phy_idx, 13174 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 13175 { 13176 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13177 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 13178 13179 if (!event) { 13180 wmi_err("null evt_buf"); 13181 return QDF_STATUS_E_INVAL; 13182 } 13183 13184 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13185 13186 if (!param_buf->num_mac_phy_caps) 13187 return QDF_STATUS_SUCCESS; 13188 13189 if (phy_idx >= param_buf->num_mac_phy_caps) 13190 return QDF_STATUS_E_INVAL; 13191 13192 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 13193 13194 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 13195 (phy_id != mac_phy_caps->phy_id)) 13196 return QDF_STATUS_E_INVAL; 13197 13198 param->hw_mode_id = mac_phy_caps->hw_mode_id; 13199 param->phy_id = mac_phy_caps->phy_id; 13200 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13201 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 13202 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13203 mac_phy_caps->wireless_modes_ext); 13204 13205 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 13206 13207 return QDF_STATUS_SUCCESS; 13208 } 13209 13210 /** 13211 * extract_reg_cap_service_ready_ext_tlv() - 13212 * extract REG cap from service ready event 13213 * @wmi_handle: wmi handle 13214 * @param evt_buf: pointer to event buffer 13215 * @param param: Pointer to hold evt buf 13216 * @param phy_idx: phy idx should be less than num_mode 13217 * 13218 * Return: QDF_STATUS_SUCCESS for success or error code 13219 */ 13220 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 13221 wmi_unified_t wmi_handle, 13222 uint8_t *event, uint8_t phy_idx, 13223 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 13224 { 13225 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13226 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13227 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 13228 13229 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13230 if (!param_buf) 13231 return QDF_STATUS_E_INVAL; 13232 13233 reg_caps = param_buf->soc_hal_reg_caps; 13234 if (!reg_caps) 13235 return QDF_STATUS_E_INVAL; 13236 13237 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 13238 return QDF_STATUS_E_INVAL; 13239 13240 if (phy_idx >= reg_caps->num_phy) 13241 return QDF_STATUS_E_INVAL; 13242 13243 if (!param_buf->hal_reg_caps) 13244 return QDF_STATUS_E_INVAL; 13245 13246 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 13247 13248 param->phy_id = ext_reg_cap->phy_id; 13249 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 13250 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 13251 param->regcap1 = ext_reg_cap->regcap1; 13252 param->regcap2 = ext_reg_cap->regcap2; 13253 param->wireless_modes = convert_wireless_modes_tlv( 13254 ext_reg_cap->wireless_modes); 13255 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 13256 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 13257 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 13258 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 13259 13260 return QDF_STATUS_SUCCESS; 13261 } 13262 13263 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 13264 uint8_t num_dma_ring_caps) 13265 { 13266 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 13267 if (!num_dma_ring_caps) { 13268 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 13269 return QDF_STATUS_E_INVAL; 13270 } 13271 if (idx >= num_dma_ring_caps) { 13272 wmi_err("Index %d exceeds range", idx); 13273 return QDF_STATUS_E_INVAL; 13274 } 13275 return QDF_STATUS_SUCCESS; 13276 } 13277 13278 static void 13279 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 13280 struct wlan_psoc_host_dbr_ring_caps *param, 13281 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 13282 { 13283 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 13284 wmi_handle, 13285 dbr_ring_caps->pdev_id); 13286 param->mod_id = dbr_ring_caps->mod_id; 13287 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 13288 param->min_buf_size = dbr_ring_caps->min_buf_size; 13289 param->min_buf_align = dbr_ring_caps->min_buf_align; 13290 } 13291 13292 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 13293 wmi_unified_t wmi_handle, 13294 uint8_t *event, uint8_t idx, 13295 struct wlan_psoc_host_dbr_ring_caps *param) 13296 { 13297 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13298 QDF_STATUS status; 13299 13300 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 13301 if (!param_buf) 13302 return QDF_STATUS_E_INVAL; 13303 13304 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 13305 if (status != QDF_STATUS_SUCCESS) 13306 return status; 13307 13308 populate_dbr_ring_cap_elems(wmi_handle, param, 13309 ¶m_buf->dma_ring_caps[idx]); 13310 return QDF_STATUS_SUCCESS; 13311 } 13312 13313 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 13314 wmi_unified_t wmi_handle, 13315 uint8_t *event, uint8_t idx, 13316 struct wlan_psoc_host_dbr_ring_caps *param) 13317 { 13318 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13319 QDF_STATUS status; 13320 13321 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13322 if (!param_buf) 13323 return QDF_STATUS_E_INVAL; 13324 13325 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 13326 if (status != QDF_STATUS_SUCCESS) 13327 return status; 13328 13329 populate_dbr_ring_cap_elems(wmi_handle, param, 13330 ¶m_buf->dma_ring_caps[idx]); 13331 return QDF_STATUS_SUCCESS; 13332 } 13333 13334 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 13335 wmi_unified_t wmi_handle, 13336 uint8_t *event, uint8_t idx, 13337 struct wlan_psoc_host_scan_radio_caps *param) 13338 { 13339 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13340 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 13341 13342 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13343 if (!param_buf) 13344 return QDF_STATUS_E_INVAL; 13345 13346 if (idx >= param_buf->num_wmi_scan_radio_caps) 13347 return QDF_STATUS_E_INVAL; 13348 13349 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 13350 param->phy_id = scan_radio_caps->phy_id; 13351 param->scan_radio_supported = 13352 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 13353 param->dfs_en = 13354 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 13355 13356 return QDF_STATUS_SUCCESS; 13357 } 13358 13359 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 13360 uint8_t *event, 13361 struct wmi_host_sw_cal_ver *cal) 13362 { 13363 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13364 wmi_sw_cal_ver_cap *fw_cap; 13365 13366 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13367 if (!param_buf) 13368 return QDF_STATUS_E_INVAL; 13369 13370 fw_cap = param_buf->sw_cal_ver_cap; 13371 if (!fw_cap) 13372 return QDF_STATUS_E_INVAL; 13373 13374 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 13375 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 13376 cal->status = fw_cap->status; 13377 13378 return QDF_STATUS_SUCCESS; 13379 } 13380 13381 /** 13382 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 13383 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 13384 * 13385 * Return: host thermal throt level 13386 */ 13387 static enum thermal_throttle_level 13388 wmi_tgt_thermal_level_to_host(uint32_t level) 13389 { 13390 switch (level) { 13391 case WMI_THERMAL_FULLPERF: 13392 return THERMAL_FULLPERF; 13393 case WMI_THERMAL_MITIGATION: 13394 return THERMAL_MITIGATION; 13395 case WMI_THERMAL_SHUTOFF: 13396 return THERMAL_SHUTOFF; 13397 case WMI_THERMAL_SHUTDOWN_TGT: 13398 return THERMAL_SHUTDOWN_TARGET; 13399 default: 13400 return THERMAL_UNKNOWN; 13401 } 13402 } 13403 13404 #ifdef THERMAL_STATS_SUPPORT 13405 static void 13406 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 13407 uint32_t *therm_throt_levels, 13408 struct thermal_throt_level_stats *tt_temp_range_stats) 13409 { 13410 uint8_t lvl_idx; 13411 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 13412 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 13413 13414 tt_stats_event = param_buf->fixed_param; 13415 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 13416 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 13417 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 13418 tt_stats_event->therm_throt_levels; 13419 13420 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 13421 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 13422 *therm_throt_levels, 13423 param_buf->num_temp_range_stats); 13424 return; 13425 } 13426 13427 wmi_tt_stats = param_buf->temp_range_stats; 13428 if (!wmi_tt_stats) { 13429 wmi_err("wmi_tt_stats Null"); 13430 return; 13431 } 13432 13433 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 13434 tt_temp_range_stats[lvl_idx].start_temp_level = 13435 wmi_tt_stats[lvl_idx].start_temp_level; 13436 tt_temp_range_stats[lvl_idx].end_temp_level = 13437 wmi_tt_stats[lvl_idx].end_temp_level; 13438 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 13439 wmi_tt_stats[lvl_idx].total_time_ms_lo; 13440 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 13441 wmi_tt_stats[lvl_idx].total_time_ms_hi; 13442 tt_temp_range_stats[lvl_idx].num_entry = 13443 wmi_tt_stats[lvl_idx].num_entry; 13444 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 13445 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 13446 wmi_tt_stats[lvl_idx].end_temp_level, 13447 wmi_tt_stats[lvl_idx].total_time_ms_lo, 13448 wmi_tt_stats[lvl_idx].total_time_ms_hi, 13449 wmi_tt_stats[lvl_idx].num_entry); 13450 } 13451 } 13452 #else 13453 static void 13454 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 13455 uint32_t *therm_throt_levels, 13456 struct thermal_throt_level_stats *tt_temp_range_stats) 13457 { 13458 } 13459 #endif 13460 13461 /** 13462 * extract_thermal_stats_tlv() - extract thermal stats from event 13463 * @wmi_handle: wmi handle 13464 * @param evt_buf: Pointer to event buffer 13465 * @param temp: Pointer to hold extracted temperature 13466 * @param level: Pointer to hold extracted level in host enum 13467 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 13468 * range 13469 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 13470 * every level 13471 * 13472 * Return: 0 for success or error code 13473 */ 13474 static QDF_STATUS 13475 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 13476 void *evt_buf, uint32_t *temp, 13477 enum thermal_throttle_level *level, 13478 uint32_t *therm_throt_levels, 13479 struct thermal_throt_level_stats *tt_temp_range_stats_event, 13480 uint32_t *pdev_id) 13481 { 13482 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 13483 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 13484 13485 param_buf = 13486 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 13487 if (!param_buf) 13488 return QDF_STATUS_E_INVAL; 13489 13490 tt_stats_event = param_buf->fixed_param; 13491 wmi_debug("thermal temperature %d level %d", 13492 tt_stats_event->temp, tt_stats_event->level); 13493 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13494 wmi_handle, 13495 tt_stats_event->pdev_id); 13496 *temp = tt_stats_event->temp; 13497 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 13498 13499 if (tt_stats_event->therm_throt_levels) 13500 populate_thermal_stats(param_buf, therm_throt_levels, 13501 tt_temp_range_stats_event); 13502 13503 return QDF_STATUS_SUCCESS; 13504 } 13505 13506 /** 13507 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 13508 * @wmi_handle: wmi handle 13509 * @param evt_buf: pointer to event buffer 13510 * @param idx: Index to level stats 13511 * @param levelcount: Pointer to hold levelcount 13512 * @param dccount: Pointer to hold dccount 13513 * 13514 * Return: 0 for success or error code 13515 */ 13516 static QDF_STATUS 13517 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 13518 void *evt_buf, uint8_t idx, uint32_t *levelcount, 13519 uint32_t *dccount) 13520 { 13521 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 13522 wmi_therm_throt_level_stats_info *tt_level_info; 13523 13524 param_buf = 13525 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 13526 if (!param_buf) 13527 return QDF_STATUS_E_INVAL; 13528 13529 tt_level_info = param_buf->therm_throt_level_stats_info; 13530 13531 if (idx < THERMAL_LEVELS) { 13532 *levelcount = tt_level_info[idx].level_count; 13533 *dccount = tt_level_info[idx].dc_count; 13534 return QDF_STATUS_SUCCESS; 13535 } 13536 13537 return QDF_STATUS_E_FAILURE; 13538 } 13539 #ifdef BIG_ENDIAN_HOST 13540 /** 13541 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 13542 * @param data_len - data length 13543 * @param data - pointer to data 13544 * 13545 * Return: QDF_STATUS - success or error status 13546 */ 13547 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 13548 { 13549 uint8_t *data_aligned = NULL; 13550 int c; 13551 unsigned char *data_unaligned; 13552 13553 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 13554 FIPS_ALIGN)); 13555 /* Assigning unaligned space to copy the data */ 13556 /* Checking if kmalloc does successful allocation */ 13557 if (!data_unaligned) 13558 return QDF_STATUS_E_FAILURE; 13559 13560 /* Checking if space is alligned */ 13561 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 13562 /* align the data space */ 13563 data_aligned = 13564 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 13565 } else { 13566 data_aligned = (u_int8_t *)data_unaligned; 13567 } 13568 13569 /* memset and copy content from data to data aligned */ 13570 OS_MEMSET(data_aligned, 0, data_len); 13571 OS_MEMCPY(data_aligned, data, data_len); 13572 /* Endianness to LE */ 13573 for (c = 0; c < data_len/4; c++) { 13574 *((u_int32_t *)data_aligned + c) = 13575 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 13576 } 13577 13578 /* Copy content to event->data */ 13579 OS_MEMCPY(data, data_aligned, data_len); 13580 13581 /* clean up allocated space */ 13582 qdf_mem_free(data_unaligned); 13583 data_aligned = NULL; 13584 data_unaligned = NULL; 13585 13586 /*************************************************************/ 13587 13588 return QDF_STATUS_SUCCESS; 13589 } 13590 #else 13591 /** 13592 * fips_conv_data_be() - DUMMY for LE platform 13593 * 13594 * Return: QDF_STATUS - success 13595 */ 13596 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 13597 { 13598 return QDF_STATUS_SUCCESS; 13599 } 13600 #endif 13601 13602 /** 13603 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 13604 * @wmi_handle - wmi handle 13605 * @params - PN request params for peer 13606 * 13607 * Return: QDF_STATUS - success or error status 13608 */ 13609 static QDF_STATUS 13610 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 13611 struct peer_request_pn_param *params) 13612 { 13613 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 13614 wmi_buf_t buf; 13615 uint8_t *buf_ptr; 13616 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 13617 13618 buf = wmi_buf_alloc(wmi_handle, len); 13619 if (!buf) { 13620 wmi_err("wmi_buf_alloc failed"); 13621 return QDF_STATUS_E_FAILURE; 13622 } 13623 13624 buf_ptr = (uint8_t *)wmi_buf_data(buf); 13625 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 13626 13627 WMITLV_SET_HDR(&cmd->tlv_header, 13628 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 13629 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 13630 13631 cmd->vdev_id = params->vdev_id; 13632 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 13633 cmd->key_type = params->key_type; 13634 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13635 WMI_PEER_TX_PN_REQUEST_CMDID)) { 13636 wmi_err("Failed to send WMI command"); 13637 wmi_buf_free(buf); 13638 return QDF_STATUS_E_FAILURE; 13639 } 13640 return QDF_STATUS_SUCCESS; 13641 } 13642 13643 /** 13644 * extract_get_pn_data_tlv() - extract pn resp 13645 * @wmi_handle - wmi handle 13646 * @params - PN response params for peer 13647 * 13648 * Return: QDF_STATUS - success or error status 13649 */ 13650 static QDF_STATUS 13651 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13652 struct wmi_host_get_pn_event *param) 13653 { 13654 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 13655 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 13656 13657 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 13658 event = 13659 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 13660 13661 param->vdev_id = event->vdev_id; 13662 param->key_type = event->key_type; 13663 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 13664 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 13665 13666 return QDF_STATUS_SUCCESS; 13667 } 13668 13669 /** 13670 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 13671 * @wmi_handle: wmi handle 13672 * @params: Rx PN request params for peer 13673 * 13674 * Return: QDF_STATUS - success or error status 13675 */ 13676 static QDF_STATUS 13677 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 13678 struct peer_request_rxpn_param *params) 13679 { 13680 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 13681 wmi_buf_t buf; 13682 uint8_t *buf_ptr; 13683 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 13684 13685 if (!is_service_enabled_tlv(wmi_handle, 13686 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 13687 wmi_err("Rx PN Replay Check not supported by target"); 13688 return QDF_STATUS_E_NOSUPPORT; 13689 } 13690 13691 buf = wmi_buf_alloc(wmi_handle, len); 13692 if (!buf) { 13693 wmi_err("wmi_buf_alloc failed"); 13694 return QDF_STATUS_E_FAILURE; 13695 } 13696 13697 buf_ptr = (uint8_t *)wmi_buf_data(buf); 13698 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 13699 13700 WMITLV_SET_HDR(&cmd->tlv_header, 13701 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 13702 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 13703 13704 cmd->vdev_id = params->vdev_id; 13705 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 13706 cmd->key_ix = params->keyix; 13707 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13708 WMI_PEER_RX_PN_REQUEST_CMDID)) { 13709 wmi_err("Failed to send WMI command"); 13710 wmi_buf_free(buf); 13711 return QDF_STATUS_E_FAILURE; 13712 } 13713 return QDF_STATUS_SUCCESS; 13714 } 13715 13716 /** 13717 * extract_get_rxpn_data_tlv() - extract Rx PN resp 13718 * @wmi_handle: wmi handle 13719 * @params: Rx PN response params for peer 13720 * 13721 * Return: QDF_STATUS - success or error status 13722 */ 13723 static QDF_STATUS 13724 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13725 struct wmi_host_get_rxpn_event *params) 13726 { 13727 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 13728 wmi_peer_rx_pn_response_event_fixed_param *event; 13729 13730 param_buf = evt_buf; 13731 event = param_buf->fixed_param; 13732 13733 params->vdev_id = event->vdev_id; 13734 params->keyix = event->key_idx; 13735 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 13736 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 13737 13738 return QDF_STATUS_SUCCESS; 13739 } 13740 13741 /** 13742 * extract_fips_event_data_tlv() - extract fips event data 13743 * @wmi_handle: wmi handle 13744 * @param evt_buf: pointer to event buffer 13745 * @param param: pointer FIPS event params 13746 * 13747 * Return: 0 for success or error code 13748 */ 13749 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 13750 void *evt_buf, struct wmi_host_fips_event_param *param) 13751 { 13752 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 13753 wmi_pdev_fips_event_fixed_param *event; 13754 13755 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 13756 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 13757 13758 if (event->data_len > param_buf->num_data) 13759 return QDF_STATUS_E_FAILURE; 13760 13761 if (fips_conv_data_be(event->data_len, param_buf->data) != 13762 QDF_STATUS_SUCCESS) 13763 return QDF_STATUS_E_FAILURE; 13764 13765 param->data = (uint32_t *)param_buf->data; 13766 param->data_len = event->data_len; 13767 param->error_status = event->error_status; 13768 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13769 wmi_handle, 13770 event->pdev_id); 13771 13772 return QDF_STATUS_SUCCESS; 13773 } 13774 13775 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 13776 /** 13777 * extract_fips_extend_event_data_tlv() - extract fips event data 13778 * @wmi_handle: wmi handle 13779 * @param evt_buf: pointer to event buffer 13780 * @param param: pointer FIPS event params 13781 * 13782 * Return: 0 for success or error code 13783 */ 13784 static QDF_STATUS 13785 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 13786 void *evt_buf, 13787 struct wmi_host_fips_extend_event_param 13788 *param) 13789 { 13790 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 13791 wmi_pdev_fips_extend_event_fixed_param *event; 13792 13793 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 13794 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 13795 13796 if (fips_conv_data_be(event->data_len, param_buf->data) != 13797 QDF_STATUS_SUCCESS) 13798 return QDF_STATUS_E_FAILURE; 13799 13800 param->data = (uint32_t *)param_buf->data; 13801 param->data_len = event->data_len; 13802 param->error_status = event->error_status; 13803 param->fips_cookie = event->fips_cookie; 13804 param->cmd_frag_idx = event->cmd_frag_idx; 13805 param->more_bit = event->more_bit; 13806 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13807 wmi_handle, 13808 event->pdev_id); 13809 13810 return QDF_STATUS_SUCCESS; 13811 } 13812 #endif 13813 13814 #ifdef WLAN_FEATURE_DISA 13815 /** 13816 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 13817 * params from event 13818 * @wmi_handle: wmi handle 13819 * @evt_buf: pointer to event buffer 13820 * @resp: Pointer to hold resp parameters 13821 * 13822 * Return: QDF_STATUS_SUCCESS for success or error code 13823 */ 13824 static QDF_STATUS 13825 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 13826 void *evt_buf, 13827 struct disa_encrypt_decrypt_resp_params 13828 *resp) 13829 { 13830 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 13831 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 13832 13833 param_buf = evt_buf; 13834 if (!param_buf) { 13835 wmi_err("encrypt decrypt resp evt_buf is NULL"); 13836 return QDF_STATUS_E_INVAL; 13837 } 13838 13839 data_event = param_buf->fixed_param; 13840 13841 resp->vdev_id = data_event->vdev_id; 13842 resp->status = data_event->status; 13843 13844 if ((data_event->data_length > param_buf->num_enc80211_frame) || 13845 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 13846 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 13847 wmi_err("FW msg data_len %d more than TLV hdr %d", 13848 data_event->data_length, 13849 param_buf->num_enc80211_frame); 13850 return QDF_STATUS_E_INVAL; 13851 } 13852 13853 resp->data_len = data_event->data_length; 13854 13855 if (resp->data_len) 13856 resp->data = (uint8_t *)param_buf->enc80211_frame; 13857 13858 return QDF_STATUS_SUCCESS; 13859 } 13860 #endif /* WLAN_FEATURE_DISA */ 13861 13862 static bool is_management_record_tlv(uint32_t cmd_id) 13863 { 13864 switch (cmd_id) { 13865 case WMI_MGMT_TX_SEND_CMDID: 13866 case WMI_MGMT_TX_COMPLETION_EVENTID: 13867 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 13868 case WMI_MGMT_RX_EVENTID: 13869 return true; 13870 default: 13871 return false; 13872 } 13873 } 13874 13875 static bool is_diag_event_tlv(uint32_t event_id) 13876 { 13877 if (WMI_DIAG_EVENTID == event_id) 13878 return true; 13879 13880 return false; 13881 } 13882 13883 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 13884 { 13885 uint16_t tag = 0; 13886 13887 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 13888 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 13889 __func__); 13890 return tag; 13891 } 13892 13893 if (wmi_handle->tag_crash_inject) 13894 tag = HTC_TX_PACKET_TAG_AUTO_PM; 13895 13896 wmi_handle->tag_crash_inject = false; 13897 return tag; 13898 } 13899 13900 /** 13901 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 13902 * @wmi_handle: WMI handle 13903 * @buf: WMI buffer 13904 * @cmd_id: WMI command Id 13905 * 13906 * Return htc_tx_tag 13907 */ 13908 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 13909 wmi_buf_t buf, 13910 uint32_t cmd_id) 13911 { 13912 uint16_t htc_tx_tag = 0; 13913 13914 switch (cmd_id) { 13915 case WMI_WOW_ENABLE_CMDID: 13916 case WMI_PDEV_SUSPEND_CMDID: 13917 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 13918 case WMI_PDEV_RESUME_CMDID: 13919 case WMI_HB_SET_ENABLE_CMDID: 13920 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 13921 #ifdef FEATURE_WLAN_D0WOW 13922 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 13923 #endif 13924 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 13925 break; 13926 case WMI_FORCE_FW_HANG_CMDID: 13927 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 13928 break; 13929 default: 13930 break; 13931 } 13932 13933 return htc_tx_tag; 13934 } 13935 13936 #ifdef CONFIG_BAND_6GHZ 13937 static struct cur_reg_rule 13938 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 13939 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 13940 { 13941 struct cur_reg_rule *reg_rule_ptr; 13942 uint32_t count; 13943 13944 if (!num_reg_rules) 13945 return NULL; 13946 13947 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 13948 sizeof(*reg_rule_ptr)); 13949 13950 if (!reg_rule_ptr) 13951 return NULL; 13952 13953 for (count = 0; count < num_reg_rules; count++) { 13954 reg_rule_ptr[count].start_freq = 13955 WMI_REG_RULE_START_FREQ_GET( 13956 wmi_reg_rule[count].freq_info); 13957 reg_rule_ptr[count].end_freq = 13958 WMI_REG_RULE_END_FREQ_GET( 13959 wmi_reg_rule[count].freq_info); 13960 reg_rule_ptr[count].max_bw = 13961 WMI_REG_RULE_MAX_BW_GET( 13962 wmi_reg_rule[count].bw_pwr_info); 13963 reg_rule_ptr[count].reg_power = 13964 WMI_REG_RULE_REG_POWER_GET( 13965 wmi_reg_rule[count].bw_pwr_info); 13966 reg_rule_ptr[count].ant_gain = 13967 WMI_REG_RULE_ANTENNA_GAIN_GET( 13968 wmi_reg_rule[count].bw_pwr_info); 13969 reg_rule_ptr[count].flags = 13970 WMI_REG_RULE_FLAGS_GET( 13971 wmi_reg_rule[count].flag_info); 13972 reg_rule_ptr[count].psd_flag = 13973 WMI_REG_RULE_PSD_FLAG_GET( 13974 wmi_reg_rule[count].psd_power_info); 13975 reg_rule_ptr[count].psd_eirp = 13976 WMI_REG_RULE_PSD_EIRP_GET( 13977 wmi_reg_rule[count].psd_power_info); 13978 } 13979 13980 return reg_rule_ptr; 13981 } 13982 #endif 13983 13984 static struct cur_reg_rule 13985 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 13986 wmi_regulatory_rule_struct *wmi_reg_rule) 13987 { 13988 struct cur_reg_rule *reg_rule_ptr; 13989 uint32_t count; 13990 13991 if (!num_reg_rules) 13992 return NULL; 13993 13994 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 13995 sizeof(*reg_rule_ptr)); 13996 13997 if (!reg_rule_ptr) 13998 return NULL; 13999 14000 for (count = 0; count < num_reg_rules; count++) { 14001 reg_rule_ptr[count].start_freq = 14002 WMI_REG_RULE_START_FREQ_GET( 14003 wmi_reg_rule[count].freq_info); 14004 reg_rule_ptr[count].end_freq = 14005 WMI_REG_RULE_END_FREQ_GET( 14006 wmi_reg_rule[count].freq_info); 14007 reg_rule_ptr[count].max_bw = 14008 WMI_REG_RULE_MAX_BW_GET( 14009 wmi_reg_rule[count].bw_pwr_info); 14010 reg_rule_ptr[count].reg_power = 14011 WMI_REG_RULE_REG_POWER_GET( 14012 wmi_reg_rule[count].bw_pwr_info); 14013 reg_rule_ptr[count].ant_gain = 14014 WMI_REG_RULE_ANTENNA_GAIN_GET( 14015 wmi_reg_rule[count].bw_pwr_info); 14016 reg_rule_ptr[count].flags = 14017 WMI_REG_RULE_FLAGS_GET( 14018 wmi_reg_rule[count].flag_info); 14019 } 14020 14021 return reg_rule_ptr; 14022 } 14023 14024 static enum cc_setting_code wmi_reg_status_to_reg_status( 14025 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 14026 { 14027 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 14028 return REG_SET_CC_STATUS_PASS; 14029 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 14030 return REG_CURRENT_ALPHA2_NOT_FOUND; 14031 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 14032 return REG_INIT_ALPHA2_NOT_FOUND; 14033 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 14034 return REG_SET_CC_CHANGE_NOT_ALLOWED; 14035 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 14036 return REG_SET_CC_STATUS_NO_MEMORY; 14037 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 14038 return REG_SET_CC_STATUS_FAIL; 14039 14040 wmi_debug("Unknown reg status code from WMI"); 14041 return REG_SET_CC_STATUS_FAIL; 14042 } 14043 14044 #ifdef CONFIG_BAND_6GHZ 14045 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 14046 wmi_unified_t wmi_handle, uint8_t *evt_buf, 14047 struct cur_regulatory_info *reg_info, uint32_t len) 14048 { 14049 uint32_t i, j, k; 14050 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 14051 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 14052 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 14053 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 14054 uint32_t num_2g_reg_rules, num_5g_reg_rules; 14055 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 14056 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 14057 uint32_t total_reg_rules = 0; 14058 14059 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 14060 if (!param_buf) { 14061 wmi_err("invalid channel list event buf"); 14062 return QDF_STATUS_E_FAILURE; 14063 } 14064 14065 ext_chan_list_event_hdr = param_buf->fixed_param; 14066 ext_wmi_chan_priority = param_buf->reg_chan_priority; 14067 14068 if (ext_wmi_chan_priority) 14069 reg_info->reg_6g_thresh_priority_freq = 14070 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 14071 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 14072 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 14073 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 14074 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 14075 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 14076 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 14077 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 14078 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 14079 14080 wmi_debug("num reg rules from fw"); 14081 wmi_debug("AP SP %d, LPI %d, VLP %d", 14082 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 14083 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 14084 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 14085 14086 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14087 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 14088 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 14089 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 14090 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 14091 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 14092 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 14093 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 14094 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 14095 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 14096 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 14097 } 14098 14099 num_2g_reg_rules = reg_info->num_2g_reg_rules; 14100 total_reg_rules += num_2g_reg_rules; 14101 num_5g_reg_rules = reg_info->num_5g_reg_rules; 14102 total_reg_rules += num_5g_reg_rules; 14103 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 14104 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 14105 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 14106 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 14107 num_6g_reg_rules_ap[i]); 14108 return QDF_STATUS_E_FAILURE; 14109 } 14110 total_reg_rules += num_6g_reg_rules_ap[i]; 14111 num_6g_reg_rules_client[i] = 14112 reg_info->num_6g_reg_rules_client[i]; 14113 } 14114 14115 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14116 total_reg_rules += 14117 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 14118 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 14119 total_reg_rules += 14120 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 14121 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 14122 MAX_6G_REG_RULES) || 14123 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 14124 MAX_6G_REG_RULES) || 14125 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 14126 MAX_6G_REG_RULES)) { 14127 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", 14128 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 14129 num_6g_reg_rules_client[REG_INDOOR_AP][i], 14130 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 14131 i); 14132 return QDF_STATUS_E_FAILURE; 14133 } 14134 } 14135 14136 if (total_reg_rules != param_buf->num_reg_rule_array) { 14137 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 14138 total_reg_rules, param_buf->num_reg_rule_array); 14139 return QDF_STATUS_E_FAILURE; 14140 } 14141 14142 if ((num_2g_reg_rules > MAX_REG_RULES) || 14143 (num_5g_reg_rules > MAX_REG_RULES)) { 14144 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 14145 num_2g_reg_rules, num_5g_reg_rules); 14146 return QDF_STATUS_E_FAILURE; 14147 } 14148 14149 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 14150 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 14151 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 14152 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", 14153 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 14154 num_6g_reg_rules_ap[REG_INDOOR_AP], 14155 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 14156 return QDF_STATUS_E_FAILURE; 14157 } 14158 14159 if (param_buf->num_reg_rule_array > 14160 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 14161 sizeof(*ext_wmi_reg_rule)) { 14162 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 14163 param_buf->num_reg_rule_array); 14164 return QDF_STATUS_E_FAILURE; 14165 } 14166 14167 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 14168 REG_ALPHA2_LEN); 14169 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 14170 reg_info->phybitmap = convert_phybitmap_tlv( 14171 ext_chan_list_event_hdr->phybitmap); 14172 reg_info->offload_enabled = true; 14173 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 14174 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 14175 wmi_handle, ext_chan_list_event_hdr->phy_id); 14176 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 14177 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 14178 14179 reg_info->status_code = 14180 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 14181 status_code); 14182 14183 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 14184 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 14185 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 14186 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 14187 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 14188 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 14189 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 14190 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 14191 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 14192 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 14193 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 14194 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 14195 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 14196 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 14197 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 14198 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 14199 14200 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14201 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 14202 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 14203 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 14204 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 14205 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 14206 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 14207 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 14208 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 14209 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 14210 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 14211 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 14212 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 14213 } 14214 14215 wmi_debug("num_phys = %u and phy_id = %u", 14216 reg_info->num_phy, reg_info->phy_id); 14217 14218 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 14219 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 14220 reg_info->max_bw_2g, reg_info->min_bw_5g, 14221 reg_info->max_bw_5g); 14222 14223 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", 14224 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 14225 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 14226 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 14227 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 14228 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 14229 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 14230 14231 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", 14232 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 14233 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 14234 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 14235 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 14236 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 14237 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 14238 14239 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", 14240 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 14241 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 14242 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 14243 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 14244 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 14245 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 14246 14247 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 14248 num_2g_reg_rules, num_5g_reg_rules); 14249 14250 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 14251 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 14252 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 14253 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 14254 14255 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", 14256 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 14257 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 14258 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 14259 14260 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", 14261 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 14262 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 14263 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 14264 14265 ext_wmi_reg_rule = 14266 (wmi_regulatory_rule_ext_struct *) 14267 ((uint8_t *)ext_chan_list_event_hdr + 14268 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 14269 WMI_TLV_HDR_SIZE); 14270 reg_info->reg_rules_2g_ptr = 14271 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 14272 ext_wmi_reg_rule); 14273 ext_wmi_reg_rule += num_2g_reg_rules; 14274 for (i = 0; i < num_2g_reg_rules; i++) { 14275 if (!reg_info->reg_rules_2g_ptr) 14276 break; 14277 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 14278 i, reg_info->reg_rules_2g_ptr[i].start_freq, 14279 reg_info->reg_rules_2g_ptr[i].end_freq, 14280 reg_info->reg_rules_2g_ptr[i].flags); 14281 } 14282 reg_info->reg_rules_5g_ptr = 14283 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 14284 ext_wmi_reg_rule); 14285 ext_wmi_reg_rule += num_5g_reg_rules; 14286 for (i = 0; i < num_5g_reg_rules; i++) { 14287 if (!reg_info->reg_rules_5g_ptr) 14288 break; 14289 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 14290 i, reg_info->reg_rules_5g_ptr[i].start_freq, 14291 reg_info->reg_rules_5g_ptr[i].end_freq, 14292 reg_info->reg_rules_5g_ptr[i].flags); 14293 } 14294 14295 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 14296 reg_info->reg_rules_6g_ap_ptr[i] = 14297 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 14298 ext_wmi_reg_rule); 14299 14300 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 14301 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 14302 if (!reg_info->reg_rules_6g_ap_ptr[i]) 14303 break; 14304 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 14305 i, j, 14306 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 14307 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 14308 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 14309 } 14310 } 14311 14312 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 14313 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14314 reg_info->reg_rules_6g_client_ptr[j][i] = 14315 create_ext_reg_rules_from_wmi( 14316 num_6g_reg_rules_client[j][i], 14317 ext_wmi_reg_rule); 14318 14319 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 14320 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 14321 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 14322 break; 14323 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 14324 j, i, k, 14325 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 14326 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 14327 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 14328 } 14329 } 14330 } 14331 14332 reg_info->client_type = ext_chan_list_event_hdr->client_type; 14333 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 14334 reg_info->unspecified_ap_usable = 14335 ext_chan_list_event_hdr->unspecified_ap_usable; 14336 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 14337 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 14338 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 14339 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 14340 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 14341 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 14342 14343 wmi_debug("client type %d", reg_info->client_type); 14344 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 14345 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 14346 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 14347 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 14348 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 14349 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 14350 14351 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 14352 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 14353 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 14354 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 14355 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 14356 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 14357 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 14358 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 14359 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 14360 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 14361 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 14362 } 14363 14364 reg_info->domain_code_6g_super_id = 14365 ext_chan_list_event_hdr->domain_code_6g_super_id; 14366 14367 wmi_debug("processed regulatory extended channel list"); 14368 14369 return QDF_STATUS_SUCCESS; 14370 } 14371 14372 #ifdef CONFIG_AFC_SUPPORT 14373 /** 14374 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 14375 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 14376 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 14377 * an index pointer required to store the current index of 14378 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 14379 * @chan_eirp_info: pointer to chan_eirp_info 14380 * @num_chans: Number of channels 14381 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 14382 * @index: Pointer to index 14383 * 14384 * Return: void 14385 */ 14386 static void 14387 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 14388 uint8_t num_chans, 14389 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 14390 uint8_t *index) 14391 { 14392 uint8_t chan_idx; 14393 14394 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 14395 chan_eirp_info[chan_idx].cfi = 14396 chan_eirp_power_info_hdr[*index].channel_cfi; 14397 chan_eirp_info[chan_idx].eirp_power = 14398 chan_eirp_power_info_hdr[*index].eirp_pwr; 14399 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 14400 chan_idx, 14401 chan_eirp_info[chan_idx].cfi, 14402 chan_eirp_info[chan_idx].eirp_power); 14403 } 14404 } 14405 14406 /** 14407 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 14408 * to the internal buffer afc_chan_info. 14409 * @afc_chan_info: pointer to afc_chan_info 14410 * @num_chan_objs: Number of channel objects 14411 * @channel_info_hdr: Pointer to channel_info_hdr 14412 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 14413 * 14414 * Return: void 14415 */ 14416 static void 14417 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 14418 uint8_t num_chan_objs, 14419 wmi_6g_afc_channel_info *channel_info_hdr, 14420 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 14421 { 14422 uint8_t count; 14423 uint8_t src_pwr_index = 0; 14424 14425 for (count = 0; count < num_chan_objs; count++) { 14426 afc_chan_info[count].global_opclass = 14427 channel_info_hdr[count].global_operating_class; 14428 afc_chan_info[count].num_chans = 14429 channel_info_hdr[count].num_channels; 14430 wmi_debug("Chan object count = %d global opclasss = %d", 14431 count, 14432 afc_chan_info[count].global_opclass); 14433 wmi_debug("Number of Channel EIRP objects = %d", 14434 afc_chan_info[count].num_chans); 14435 14436 if (afc_chan_info[count].num_chans > 0) { 14437 struct chan_eirp_obj *chan_eirp_info; 14438 14439 chan_eirp_info = 14440 qdf_mem_malloc(afc_chan_info[count].num_chans * 14441 sizeof(*chan_eirp_info)); 14442 14443 if (!chan_eirp_info) 14444 return; 14445 14446 copy_afc_chan_eirp_info(chan_eirp_info, 14447 afc_chan_info[count].num_chans, 14448 chan_eirp_power_info_hdr, 14449 &src_pwr_index); 14450 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 14451 } else { 14452 wmi_err("Number of channels is zero in object idx %d", 14453 count); 14454 } 14455 } 14456 } 14457 14458 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 14459 uint8_t num_freq_objs, 14460 wmi_6g_afc_frequency_info *freq_info_hdr) 14461 { 14462 uint8_t count; 14463 14464 for (count = 0; count < num_freq_objs; count++) { 14465 afc_freq_info[count].low_freq = 14466 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 14467 afc_freq_info[count].high_freq = 14468 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 14469 afc_freq_info[count].max_psd = 14470 freq_info_hdr[count].psd_power_info; 14471 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 14472 count, 14473 afc_freq_info[count].low_freq, 14474 afc_freq_info[count].high_freq, 14475 afc_freq_info[count].max_psd); 14476 } 14477 } 14478 14479 /** 14480 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 14481 * the power event info from the WMI AFC event buffer to the internal buffer 14482 * power_info. 14483 * @power_info: pointer to power_info 14484 * @afc_power_event_hdr: pointer to afc_power_event_hdr 14485 * 14486 * Return: void 14487 */ 14488 static void 14489 copy_afc_event_fixed_hdr_power_info( 14490 struct reg_fw_afc_power_event *power_info, 14491 wmi_afc_power_event_param *afc_power_event_hdr) 14492 { 14493 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 14494 power_info->resp_id = afc_power_event_hdr->resp_id; 14495 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 14496 power_info->afc_wfa_version = 14497 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 14498 power_info->afc_wfa_version |= 14499 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 14500 14501 power_info->avail_exp_time_d = 14502 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 14503 power_info->avail_exp_time_d |= 14504 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 14505 power_info->avail_exp_time_d |= 14506 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 14507 14508 power_info->avail_exp_time_t = 14509 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 14510 power_info->avail_exp_time_t |= 14511 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 14512 power_info->avail_exp_time_t |= 14513 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 14514 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 14515 power_info->fw_status_code, 14516 power_info->resp_id, 14517 power_info->serv_resp_code); 14518 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 14519 power_info->afc_wfa_version, 14520 power_info->avail_exp_time_d, 14521 power_info->avail_exp_time_t); 14522 } 14523 14524 /** 14525 * copy_power_event() - Copy the power event parameters from the AFC event 14526 * buffer to the power_info within the afc_info. 14527 * @afc_info: pointer to afc_info 14528 * @param_buf: pointer to param_buf 14529 * 14530 * Return: void 14531 */ 14532 static void copy_power_event(struct afc_regulatory_info *afc_info, 14533 WMI_AFC_EVENTID_param_tlvs *param_buf) 14534 { 14535 struct reg_fw_afc_power_event *power_info; 14536 wmi_afc_power_event_param *afc_power_event_hdr; 14537 struct afc_freq_obj *afc_freq_info; 14538 14539 power_info = qdf_mem_malloc(sizeof(*power_info)); 14540 14541 if (!power_info) 14542 return; 14543 14544 afc_power_event_hdr = param_buf->afc_power_event_param; 14545 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 14546 afc_info->power_info = power_info; 14547 14548 power_info->num_freq_objs = param_buf->num_freq_info_array; 14549 wmi_debug("Number of frequency objects = %d", 14550 power_info->num_freq_objs); 14551 if (power_info->num_freq_objs > 0) { 14552 wmi_6g_afc_frequency_info *freq_info_hdr; 14553 14554 freq_info_hdr = param_buf->freq_info_array; 14555 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 14556 sizeof(*afc_freq_info)); 14557 14558 if (!afc_freq_info) 14559 return; 14560 14561 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 14562 freq_info_hdr); 14563 power_info->afc_freq_info = afc_freq_info; 14564 } else { 14565 wmi_err("Number of frequency objects is zero"); 14566 } 14567 14568 power_info->num_chan_objs = param_buf->num_channel_info_array; 14569 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 14570 if (power_info->num_chan_objs > 0) { 14571 struct afc_chan_obj *afc_chan_info; 14572 wmi_6g_afc_channel_info *channel_info_hdr; 14573 14574 channel_info_hdr = param_buf->channel_info_array; 14575 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 14576 sizeof(*afc_chan_info)); 14577 14578 if (!afc_chan_info) 14579 return; 14580 14581 copy_afc_chan_obj_info(afc_chan_info, 14582 power_info->num_chan_objs, 14583 channel_info_hdr, 14584 param_buf->chan_eirp_power_info_array); 14585 power_info->afc_chan_info = afc_chan_info; 14586 } else { 14587 wmi_err("Number of channel objects is zero"); 14588 } 14589 } 14590 14591 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 14592 WMI_AFC_EVENTID_param_tlvs *param_buf) 14593 { 14594 struct reg_afc_expiry_event *expiry_info; 14595 14596 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 14597 14598 if (!expiry_info) 14599 return; 14600 14601 expiry_info->request_id = 14602 param_buf->expiry_event_param->request_id; 14603 expiry_info->event_subtype = 14604 param_buf->expiry_event_param->event_subtype; 14605 wmi_debug("Event subtype %d request ID %d", 14606 expiry_info->event_subtype, 14607 expiry_info->request_id); 14608 afc_info->expiry_info = expiry_info; 14609 } 14610 14611 /** 14612 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 14613 * in the AFC event. 'Common' indicates that these parameters are common for 14614 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 14615 * @wmi_handle: wmi handle 14616 * @afc_info: pointer to afc_info 14617 * @event_fixed_hdr: pointer to event_fixed_hdr 14618 * 14619 * Return: void 14620 */ 14621 static void 14622 copy_afc_event_common_info(wmi_unified_t wmi_handle, 14623 struct afc_regulatory_info *afc_info, 14624 wmi_afc_event_fixed_param *event_fixed_hdr) 14625 { 14626 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 14627 wmi_handle, event_fixed_hdr->phy_id); 14628 wmi_debug("phy_id %d", afc_info->phy_id); 14629 afc_info->event_type = event_fixed_hdr->event_type; 14630 } 14631 14632 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 14633 uint8_t *evt_buf, 14634 struct afc_regulatory_info *afc_info, 14635 uint32_t len) 14636 { 14637 WMI_AFC_EVENTID_param_tlvs *param_buf; 14638 wmi_afc_event_fixed_param *event_fixed_hdr; 14639 14640 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 14641 if (!param_buf) { 14642 wmi_err("Invalid AFC event buf"); 14643 return QDF_STATUS_E_FAILURE; 14644 } 14645 14646 event_fixed_hdr = param_buf->fixed_param; 14647 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 14648 wmi_debug("AFC event type %d received", afc_info->event_type); 14649 14650 switch (afc_info->event_type) { 14651 case WMI_AFC_EVENT_POWER_INFO: 14652 copy_power_event(afc_info, param_buf); 14653 break; 14654 case WMI_AFC_EVENT_TIMER_EXPIRY: 14655 copy_expiry_event(afc_info, param_buf); 14656 return QDF_STATUS_SUCCESS; 14657 default: 14658 wmi_err("Invalid event type"); 14659 return QDF_STATUS_E_FAILURE; 14660 } 14661 14662 return QDF_STATUS_SUCCESS; 14663 } 14664 #endif 14665 #endif 14666 14667 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 14668 wmi_unified_t wmi_handle, uint8_t *evt_buf, 14669 struct cur_regulatory_info *reg_info, uint32_t len) 14670 { 14671 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 14672 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 14673 wmi_regulatory_rule_struct *wmi_reg_rule; 14674 uint32_t num_2g_reg_rules, num_5g_reg_rules; 14675 14676 wmi_debug("processing regulatory channel list"); 14677 14678 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 14679 if (!param_buf) { 14680 wmi_err("invalid channel list event buf"); 14681 return QDF_STATUS_E_FAILURE; 14682 } 14683 14684 chan_list_event_hdr = param_buf->fixed_param; 14685 14686 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 14687 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 14688 num_2g_reg_rules = reg_info->num_2g_reg_rules; 14689 num_5g_reg_rules = reg_info->num_5g_reg_rules; 14690 if ((num_2g_reg_rules > MAX_REG_RULES) || 14691 (num_5g_reg_rules > MAX_REG_RULES) || 14692 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 14693 (num_2g_reg_rules + num_5g_reg_rules != 14694 param_buf->num_reg_rule_array)) { 14695 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 14696 num_2g_reg_rules, num_5g_reg_rules); 14697 return QDF_STATUS_E_FAILURE; 14698 } 14699 if (param_buf->num_reg_rule_array > 14700 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 14701 sizeof(*wmi_reg_rule)) { 14702 wmi_err_rl("Invalid num_reg_rule_array: %u", 14703 param_buf->num_reg_rule_array); 14704 return QDF_STATUS_E_FAILURE; 14705 } 14706 14707 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 14708 REG_ALPHA2_LEN); 14709 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 14710 reg_info->phybitmap = convert_phybitmap_tlv( 14711 chan_list_event_hdr->phybitmap); 14712 reg_info->offload_enabled = true; 14713 reg_info->num_phy = chan_list_event_hdr->num_phy; 14714 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 14715 wmi_handle, chan_list_event_hdr->phy_id); 14716 reg_info->ctry_code = chan_list_event_hdr->country_id; 14717 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 14718 14719 reg_info->status_code = 14720 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 14721 14722 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 14723 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 14724 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 14725 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 14726 14727 wmi_debug("num_phys = %u and phy_id = %u", 14728 reg_info->num_phy, reg_info->phy_id); 14729 14730 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 14731 reg_info->alpha2, reg_info->dfs_region, 14732 reg_info->min_bw_2g, reg_info->max_bw_2g, 14733 reg_info->min_bw_5g, reg_info->max_bw_5g); 14734 14735 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 14736 num_2g_reg_rules, num_5g_reg_rules); 14737 wmi_reg_rule = 14738 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 14739 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 14740 + WMI_TLV_HDR_SIZE); 14741 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 14742 wmi_reg_rule); 14743 wmi_reg_rule += num_2g_reg_rules; 14744 14745 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 14746 wmi_reg_rule); 14747 14748 wmi_debug("processed regulatory channel list"); 14749 14750 return QDF_STATUS_SUCCESS; 14751 } 14752 14753 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 14754 wmi_unified_t wmi_handle, uint8_t *evt_buf, 14755 struct reg_11d_new_country *reg_11d_country, uint32_t len) 14756 { 14757 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 14758 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 14759 14760 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 14761 if (!param_buf) { 14762 wmi_err("invalid 11d country event buf"); 14763 return QDF_STATUS_E_FAILURE; 14764 } 14765 14766 reg_11d_country_event = param_buf->fixed_param; 14767 14768 qdf_mem_copy(reg_11d_country->alpha2, 14769 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 14770 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 14771 14772 wmi_debug("processed 11d country event, new cc %s", 14773 reg_11d_country->alpha2); 14774 14775 return QDF_STATUS_SUCCESS; 14776 } 14777 14778 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 14779 wmi_unified_t wmi_handle, uint8_t *evt_buf, 14780 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 14781 { 14782 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 14783 wmi_avoid_freq_range_desc *afr_desc; 14784 uint32_t num_freq_ranges, freq_range_idx; 14785 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 14786 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 14787 14788 if (!param_buf) { 14789 wmi_err("Invalid channel avoid event buffer"); 14790 return QDF_STATUS_E_INVAL; 14791 } 14792 14793 afr_fixed_param = param_buf->fixed_param; 14794 if (!afr_fixed_param) { 14795 wmi_err("Invalid channel avoid event fixed param buffer"); 14796 return QDF_STATUS_E_INVAL; 14797 } 14798 14799 if (!ch_avoid_ind) { 14800 wmi_err("Invalid channel avoid indication buffer"); 14801 return QDF_STATUS_E_INVAL; 14802 } 14803 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 14804 wmi_err("no.of freq ranges exceeded the limit"); 14805 return QDF_STATUS_E_INVAL; 14806 } 14807 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 14808 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 14809 afr_fixed_param->num_freq_ranges; 14810 14811 wmi_debug("Channel avoid event received with %d ranges", 14812 num_freq_ranges); 14813 14814 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 14815 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 14816 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 14817 freq_range_idx++) { 14818 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 14819 afr_desc->start_freq; 14820 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 14821 afr_desc->end_freq; 14822 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 14823 freq_range_idx, afr_desc->tlv_header, 14824 afr_desc->start_freq, afr_desc->end_freq); 14825 afr_desc++; 14826 } 14827 14828 return QDF_STATUS_SUCCESS; 14829 } 14830 14831 #ifdef DFS_COMPONENT_ENABLE 14832 /** 14833 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 14834 * @wmi_handle: wma handle 14835 * @evt_buf: event buffer 14836 * @vdev_id: vdev id 14837 * @len: length of buffer 14838 * 14839 * Return: 0 for success or error code 14840 */ 14841 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 14842 uint8_t *evt_buf, 14843 uint32_t *vdev_id, 14844 uint32_t len) 14845 { 14846 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 14847 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 14848 14849 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 14850 if (!param_tlvs) { 14851 wmi_err("invalid cac complete event buf"); 14852 return QDF_STATUS_E_FAILURE; 14853 } 14854 14855 cac_event = param_tlvs->fixed_param; 14856 *vdev_id = cac_event->vdev_id; 14857 wmi_debug("processed cac complete event vdev %d", *vdev_id); 14858 14859 return QDF_STATUS_SUCCESS; 14860 } 14861 14862 /** 14863 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 14864 * @wmi_handle: wma handle 14865 * @evt_buf: event buffer 14866 * @vdev_id: vdev id 14867 * @len: length of buffer 14868 * 14869 * Return: 0 for success or error code 14870 */ 14871 static QDF_STATUS 14872 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 14873 uint8_t *evt_buf, 14874 struct vdev_adfs_complete_status *param) 14875 { 14876 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 14877 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 14878 14879 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 14880 if (!param_tlvs) { 14881 wmi_err("invalid ocac complete event buf"); 14882 return QDF_STATUS_E_FAILURE; 14883 } 14884 14885 if (!param_tlvs->fixed_param) { 14886 wmi_err("invalid param_tlvs->fixed_param"); 14887 return QDF_STATUS_E_FAILURE; 14888 } 14889 14890 ocac_complete_status = param_tlvs->fixed_param; 14891 param->vdev_id = ocac_complete_status->vdev_id; 14892 param->chan_freq = ocac_complete_status->chan_freq; 14893 param->center_freq1 = ocac_complete_status->center_freq1; 14894 param->center_freq2 = ocac_complete_status->center_freq2; 14895 param->ocac_status = ocac_complete_status->status; 14896 param->chan_width = ocac_complete_status->chan_width; 14897 wmi_debug("processed ocac complete event vdev %d" 14898 " agile chan %d %d width %d status %d", 14899 param->vdev_id, 14900 param->center_freq1, 14901 param->center_freq2, 14902 param->chan_width, 14903 param->ocac_status); 14904 14905 return QDF_STATUS_SUCCESS; 14906 } 14907 14908 /** 14909 * extract_dfs_radar_detection_event_tlv() - extract radar found event 14910 * @wmi_handle: wma handle 14911 * @evt_buf: event buffer 14912 * @radar_found: radar found event info 14913 * @len: length of buffer 14914 * 14915 * Return: 0 for success or error code 14916 */ 14917 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 14918 wmi_unified_t wmi_handle, 14919 uint8_t *evt_buf, 14920 struct radar_found_info *radar_found, 14921 uint32_t len) 14922 { 14923 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 14924 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 14925 14926 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 14927 if (!param_tlv) { 14928 wmi_err("invalid radar detection event buf"); 14929 return QDF_STATUS_E_FAILURE; 14930 } 14931 14932 radar_event = param_tlv->fixed_param; 14933 14934 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 14935 wmi_handle, 14936 radar_event->pdev_id); 14937 14938 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 14939 return QDF_STATUS_E_FAILURE; 14940 14941 radar_found->detection_mode = radar_event->detection_mode; 14942 radar_found->chan_freq = radar_event->chan_freq; 14943 radar_found->chan_width = radar_event->chan_width; 14944 radar_found->detector_id = radar_event->detector_id; 14945 radar_found->segment_id = radar_event->segment_id; 14946 radar_found->timestamp = radar_event->timestamp; 14947 radar_found->is_chirp = radar_event->is_chirp; 14948 radar_found->freq_offset = radar_event->freq_offset; 14949 radar_found->sidx = radar_event->sidx; 14950 14951 wmi_debug("processed radar found event pdev %d," 14952 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 14953 "chan_width (RSSI) %d,detector_id (false_radar) %d," 14954 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 14955 "is_chirp %d,detection mode %d", 14956 radar_event->pdev_id, radar_found->pdev_id, 14957 radar_event->timestamp, radar_event->chan_freq, 14958 radar_event->chan_width, radar_event->detector_id, 14959 radar_event->freq_offset, radar_event->segment_id, 14960 radar_event->sidx, radar_event->is_chirp, 14961 radar_event->detection_mode); 14962 14963 return QDF_STATUS_SUCCESS; 14964 } 14965 14966 #ifdef MOBILE_DFS_SUPPORT 14967 /** 14968 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 14969 * @wmi_handle: wma handle 14970 * @evt_buf: event buffer 14971 * @wlan_radar_event: Pointer to struct radar_event_info 14972 * @len: length of buffer 14973 * 14974 * Return: QDF_STATUS 14975 */ 14976 static QDF_STATUS extract_wlan_radar_event_info_tlv( 14977 wmi_unified_t wmi_handle, 14978 uint8_t *evt_buf, 14979 struct radar_event_info *wlan_radar_event, 14980 uint32_t len) 14981 { 14982 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 14983 wmi_dfs_radar_event_fixed_param *radar_event; 14984 14985 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 14986 if (!param_tlv) { 14987 wmi_err("invalid wlan radar event buf"); 14988 return QDF_STATUS_E_FAILURE; 14989 } 14990 14991 radar_event = param_tlv->fixed_param; 14992 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 14993 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 14994 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 14995 wlan_radar_event->rssi = radar_event->rssi; 14996 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 14997 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 14998 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 14999 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 15000 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 15001 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 15002 if (radar_event->pulse_flags & 15003 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 15004 wlan_radar_event->is_psidx_diff_valid = true; 15005 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 15006 } else { 15007 wlan_radar_event->is_psidx_diff_valid = false; 15008 } 15009 15010 wlan_radar_event->pdev_id = radar_event->pdev_id; 15011 15012 return QDF_STATUS_SUCCESS; 15013 } 15014 #else 15015 static QDF_STATUS extract_wlan_radar_event_info_tlv( 15016 wmi_unified_t wmi_handle, 15017 uint8_t *evt_buf, 15018 struct radar_event_info *wlan_radar_event, 15019 uint32_t len) 15020 { 15021 return QDF_STATUS_SUCCESS; 15022 } 15023 #endif 15024 #endif 15025 15026 /** 15027 * send_get_rcpi_cmd_tlv() - send request for rcpi value 15028 * @wmi_handle: wmi handle 15029 * @get_rcpi_param: rcpi params 15030 * 15031 * Return: QDF status 15032 */ 15033 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 15034 struct rcpi_req *get_rcpi_param) 15035 { 15036 wmi_buf_t buf; 15037 wmi_request_rcpi_cmd_fixed_param *cmd; 15038 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 15039 15040 buf = wmi_buf_alloc(wmi_handle, len); 15041 if (!buf) 15042 return QDF_STATUS_E_NOMEM; 15043 15044 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 15045 WMITLV_SET_HDR(&cmd->tlv_header, 15046 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 15047 WMITLV_GET_STRUCT_TLVLEN 15048 (wmi_request_rcpi_cmd_fixed_param)); 15049 15050 cmd->vdev_id = get_rcpi_param->vdev_id; 15051 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 15052 &cmd->peer_macaddr); 15053 15054 switch (get_rcpi_param->measurement_type) { 15055 15056 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 15057 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 15058 break; 15059 15060 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 15061 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 15062 break; 15063 15064 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 15065 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 15066 break; 15067 15068 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 15069 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 15070 break; 15071 15072 default: 15073 /* 15074 * invalid rcpi measurement type, fall back to 15075 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 15076 */ 15077 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 15078 break; 15079 } 15080 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 15081 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 15082 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15083 WMI_REQUEST_RCPI_CMDID)) { 15084 15085 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 15086 wmi_buf_free(buf); 15087 return QDF_STATUS_E_FAILURE; 15088 } 15089 15090 return QDF_STATUS_SUCCESS; 15091 } 15092 15093 /** 15094 * extract_rcpi_response_event_tlv() - Extract RCPI event params 15095 * @wmi_handle: wmi handle 15096 * @evt_buf: pointer to event buffer 15097 * @res: pointer to hold rcpi response from firmware 15098 * 15099 * Return: QDF_STATUS_SUCCESS for successful event parse 15100 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 15101 */ 15102 static QDF_STATUS 15103 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 15104 void *evt_buf, struct rcpi_res *res) 15105 { 15106 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 15107 wmi_update_rcpi_event_fixed_param *event; 15108 15109 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 15110 if (!param_buf) { 15111 wmi_err("Invalid rcpi event"); 15112 return QDF_STATUS_E_INVAL; 15113 } 15114 15115 event = param_buf->fixed_param; 15116 res->vdev_id = event->vdev_id; 15117 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 15118 15119 switch (event->measurement_type) { 15120 15121 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 15122 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 15123 break; 15124 15125 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 15126 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 15127 break; 15128 15129 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 15130 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 15131 break; 15132 15133 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 15134 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 15135 break; 15136 15137 default: 15138 wmi_err("Invalid rcpi measurement type from firmware"); 15139 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 15140 return QDF_STATUS_E_FAILURE; 15141 } 15142 15143 if (event->status) 15144 return QDF_STATUS_E_FAILURE; 15145 else 15146 return QDF_STATUS_SUCCESS; 15147 } 15148 15149 /** 15150 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 15151 * host to target defines. For legacy there is not conversion 15152 * required. Just return pdev_id as it is. 15153 * @param pdev_id: host pdev_id to be converted. 15154 * Return: target pdev_id after conversion. 15155 */ 15156 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 15157 wmi_unified_t wmi_handle, 15158 uint32_t pdev_id) 15159 { 15160 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 15161 return WMI_PDEV_ID_SOC; 15162 15163 /*No conversion required*/ 15164 return pdev_id; 15165 } 15166 15167 /** 15168 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 15169 * target to host defines. For legacy there is not conversion 15170 * required. Just return pdev_id as it is. 15171 * @param pdev_id: target pdev_id to be converted. 15172 * Return: host pdev_id after conversion. 15173 */ 15174 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 15175 wmi_unified_t wmi_handle, 15176 uint32_t pdev_id) 15177 { 15178 /*No conversion required*/ 15179 return pdev_id; 15180 } 15181 15182 /** 15183 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 15184 * host to target defines. For legacy there is not conversion 15185 * required. Just return phy_id as it is. 15186 * @param pdev_id: host phy_id to be converted. 15187 * Return: target phy_id after conversion. 15188 */ 15189 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 15190 wmi_unified_t wmi_handle, 15191 uint32_t phy_id) 15192 { 15193 /*No conversion required*/ 15194 return phy_id; 15195 } 15196 15197 /** 15198 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 15199 * target to host defines. For legacy there is not conversion 15200 * required. Just return phy_id as it is. 15201 * @param pdev_id: target phy_id to be converted. 15202 * Return: host phy_id after conversion. 15203 */ 15204 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 15205 wmi_unified_t wmi_handle, 15206 uint32_t phy_id) 15207 { 15208 /*No conversion required*/ 15209 return phy_id; 15210 } 15211 15212 /** 15213 * send_set_country_cmd_tlv() - WMI scan channel list function 15214 * @param wmi_handle : handle to WMI. 15215 * @param param : pointer to hold scan channel list parameter 15216 * 15217 * Return: 0 on success and -ve on failure. 15218 */ 15219 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 15220 struct set_country *params) 15221 { 15222 wmi_buf_t buf; 15223 QDF_STATUS qdf_status; 15224 wmi_set_current_country_cmd_fixed_param *cmd; 15225 uint16_t len = sizeof(*cmd); 15226 uint8_t pdev_id = params->pdev_id; 15227 15228 buf = wmi_buf_alloc(wmi_handle, len); 15229 if (!buf) { 15230 qdf_status = QDF_STATUS_E_NOMEM; 15231 goto end; 15232 } 15233 15234 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 15235 WMITLV_SET_HDR(&cmd->tlv_header, 15236 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 15237 WMITLV_GET_STRUCT_TLVLEN 15238 (wmi_set_current_country_cmd_fixed_param)); 15239 15240 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 15241 wmi_handle, 15242 pdev_id); 15243 wmi_debug("setting current country to %s and target pdev_id = %u", 15244 params->country, cmd->pdev_id); 15245 15246 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 15247 15248 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 15249 qdf_status = wmi_unified_cmd_send(wmi_handle, 15250 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 15251 15252 if (QDF_IS_STATUS_ERROR(qdf_status)) { 15253 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 15254 wmi_buf_free(buf); 15255 } 15256 15257 end: 15258 return qdf_status; 15259 } 15260 15261 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 15262 WMI_SET_BITS(alpha, 0, 8, val0); \ 15263 WMI_SET_BITS(alpha, 8, 8, val1); \ 15264 WMI_SET_BITS(alpha, 16, 8, val2); \ 15265 } while (0) 15266 15267 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 15268 uint8_t pdev_id, struct cc_regdmn_s *rd) 15269 { 15270 wmi_set_init_country_cmd_fixed_param *cmd; 15271 uint16_t len; 15272 wmi_buf_t buf; 15273 int ret; 15274 15275 len = sizeof(wmi_set_init_country_cmd_fixed_param); 15276 buf = wmi_buf_alloc(wmi_handle, len); 15277 if (!buf) 15278 return QDF_STATUS_E_NOMEM; 15279 15280 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 15281 WMITLV_SET_HDR(&cmd->tlv_header, 15282 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 15283 WMITLV_GET_STRUCT_TLVLEN 15284 (wmi_set_init_country_cmd_fixed_param)); 15285 15286 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15287 wmi_handle, 15288 pdev_id); 15289 15290 if (rd->flags == CC_IS_SET) { 15291 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 15292 cmd->country_code.country_id = rd->cc.country_code; 15293 } else if (rd->flags == ALPHA_IS_SET) { 15294 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 15295 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 15296 rd->cc.alpha[0], 15297 rd->cc.alpha[1], 15298 rd->cc.alpha[2]); 15299 } else if (rd->flags == REGDMN_IS_SET) { 15300 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 15301 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 15302 rd->cc.regdmn.reg_2g_5g_pair_id); 15303 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 15304 rd->cc.regdmn.sixg_superdmn_id); 15305 } 15306 15307 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 15308 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15309 WMI_SET_INIT_COUNTRY_CMDID); 15310 if (ret) { 15311 wmi_err("Failed to config wow wakeup event"); 15312 wmi_buf_free(buf); 15313 return QDF_STATUS_E_FAILURE; 15314 } 15315 15316 return QDF_STATUS_SUCCESS; 15317 } 15318 15319 /** 15320 * send_obss_detection_cfg_cmd_tlv() - send obss detection 15321 * configurations to firmware. 15322 * @wmi_handle: wmi handle 15323 * @obss_cfg_param: obss detection configurations 15324 * 15325 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 15326 * 15327 * Return: QDF_STATUS 15328 */ 15329 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 15330 struct wmi_obss_detection_cfg_param *obss_cfg_param) 15331 { 15332 wmi_buf_t buf; 15333 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 15334 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 15335 15336 buf = wmi_buf_alloc(wmi_handle, len); 15337 if (!buf) 15338 return QDF_STATUS_E_NOMEM; 15339 15340 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 15341 WMITLV_SET_HDR(&cmd->tlv_header, 15342 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 15343 WMITLV_GET_STRUCT_TLVLEN 15344 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 15345 15346 cmd->vdev_id = obss_cfg_param->vdev_id; 15347 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 15348 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 15349 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 15350 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 15351 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 15352 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 15353 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 15354 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 15355 15356 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 15357 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15358 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 15359 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 15360 wmi_buf_free(buf); 15361 return QDF_STATUS_E_FAILURE; 15362 } 15363 15364 return QDF_STATUS_SUCCESS; 15365 } 15366 15367 /** 15368 * extract_obss_detection_info_tlv() - Extract obss detection info 15369 * received from firmware. 15370 * @evt_buf: pointer to event buffer 15371 * @obss_detection: Pointer to hold obss detection info 15372 * 15373 * Return: QDF_STATUS 15374 */ 15375 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 15376 struct wmi_obss_detect_info 15377 *obss_detection) 15378 { 15379 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 15380 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 15381 15382 if (!obss_detection) { 15383 wmi_err("Invalid obss_detection event buffer"); 15384 return QDF_STATUS_E_INVAL; 15385 } 15386 15387 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 15388 if (!param_buf) { 15389 wmi_err("Invalid evt_buf"); 15390 return QDF_STATUS_E_INVAL; 15391 } 15392 15393 fix_param = param_buf->fixed_param; 15394 obss_detection->vdev_id = fix_param->vdev_id; 15395 obss_detection->matched_detection_masks = 15396 fix_param->matched_detection_masks; 15397 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 15398 &obss_detection->matched_bssid_addr[0]); 15399 switch (fix_param->reason) { 15400 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 15401 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 15402 break; 15403 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 15404 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 15405 break; 15406 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 15407 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 15408 break; 15409 default: 15410 wmi_err("Invalid reason: %d", fix_param->reason); 15411 return QDF_STATUS_E_INVAL; 15412 } 15413 15414 return QDF_STATUS_SUCCESS; 15415 } 15416 15417 /** 15418 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 15419 * @wmi_handle: wmi handle 15420 * @params: pointer to request structure 15421 * 15422 * Return: QDF_STATUS 15423 */ 15424 static QDF_STATUS 15425 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 15426 struct wmi_roam_scan_stats_req *params) 15427 { 15428 wmi_buf_t buf; 15429 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 15430 WMITLV_TAG_ID tag; 15431 uint32_t size; 15432 uint32_t len = sizeof(*cmd); 15433 15434 buf = wmi_buf_alloc(wmi_handle, len); 15435 if (!buf) 15436 return QDF_STATUS_E_FAILURE; 15437 15438 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 15439 15440 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 15441 size = WMITLV_GET_STRUCT_TLVLEN( 15442 wmi_request_roam_scan_stats_cmd_fixed_param); 15443 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 15444 15445 cmd->vdev_id = params->vdev_id; 15446 15447 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 15448 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15449 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 15450 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 15451 wmi_buf_free(buf); 15452 return QDF_STATUS_E_FAILURE; 15453 } 15454 15455 return QDF_STATUS_SUCCESS; 15456 } 15457 15458 /** 15459 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 15460 * channel list from firmware 15461 * @wmi_handle: wmi handler 15462 * @vdev_id: vdev id 15463 * 15464 * Return: QDF_STATUS 15465 */ 15466 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 15467 uint32_t vdev_id) 15468 { 15469 wmi_buf_t buf; 15470 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 15471 uint16_t len = sizeof(*cmd); 15472 int ret; 15473 15474 buf = wmi_buf_alloc(wmi_handle, len); 15475 if (!buf) { 15476 wmi_err("Failed to allocate wmi buffer"); 15477 return QDF_STATUS_E_NOMEM; 15478 } 15479 15480 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 15481 wmi_buf_data(buf); 15482 WMITLV_SET_HDR(&cmd->tlv_header, 15483 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 15484 WMITLV_GET_STRUCT_TLVLEN( 15485 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 15486 cmd->vdev_id = vdev_id; 15487 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 15488 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15489 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 15490 if (QDF_IS_STATUS_ERROR(ret)) { 15491 wmi_err("Failed to send get roam scan channels request = %d", 15492 ret); 15493 wmi_buf_free(buf); 15494 } 15495 return ret; 15496 } 15497 15498 /** 15499 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 15500 * @wmi_handle: wmi handle 15501 * @evt_buf: pointer to event buffer 15502 * @vdev_id: output pointer to hold vdev id 15503 * @res_param: output pointer to hold the allocated response 15504 * 15505 * Return: QDF_STATUS 15506 */ 15507 static QDF_STATUS 15508 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15509 uint32_t *vdev_id, 15510 struct wmi_roam_scan_stats_res **res_param) 15511 { 15512 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 15513 wmi_roam_scan_stats_event_fixed_param *fixed_param; 15514 uint32_t *client_id = NULL; 15515 wmi_roaming_timestamp *timestamp = NULL; 15516 uint32_t *num_channels = NULL; 15517 uint32_t *chan_info = NULL; 15518 wmi_mac_addr *old_bssid = NULL; 15519 uint32_t *is_roaming_success = NULL; 15520 wmi_mac_addr *new_bssid = NULL; 15521 uint32_t *num_roam_candidates = NULL; 15522 wmi_roam_scan_trigger_reason *roam_reason = NULL; 15523 wmi_mac_addr *bssid = NULL; 15524 uint32_t *score = NULL; 15525 uint32_t *channel = NULL; 15526 uint32_t *rssi = NULL; 15527 int chan_idx = 0, cand_idx = 0; 15528 uint32_t total_len; 15529 struct wmi_roam_scan_stats_res *res; 15530 uint32_t i, j; 15531 uint32_t num_scans, scan_param_size; 15532 15533 *res_param = NULL; 15534 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 15535 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 15536 if (!param_buf) { 15537 wmi_err("Invalid roam scan stats event"); 15538 return QDF_STATUS_E_INVAL; 15539 } 15540 15541 fixed_param = param_buf->fixed_param; 15542 15543 num_scans = fixed_param->num_roam_scans; 15544 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 15545 *vdev_id = fixed_param->vdev_id; 15546 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 15547 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 15548 num_scans, WMI_ROAM_SCAN_STATS_MAX); 15549 return QDF_STATUS_E_INVAL; 15550 } 15551 15552 total_len = sizeof(*res) + num_scans * scan_param_size; 15553 15554 res = qdf_mem_malloc(total_len); 15555 if (!res) 15556 return QDF_STATUS_E_NOMEM; 15557 15558 if (!num_scans) { 15559 *res_param = res; 15560 return QDF_STATUS_SUCCESS; 15561 } 15562 15563 if (param_buf->client_id && 15564 param_buf->num_client_id == num_scans) 15565 client_id = param_buf->client_id; 15566 15567 if (param_buf->timestamp && 15568 param_buf->num_timestamp == num_scans) 15569 timestamp = param_buf->timestamp; 15570 15571 if (param_buf->old_bssid && 15572 param_buf->num_old_bssid == num_scans) 15573 old_bssid = param_buf->old_bssid; 15574 15575 if (param_buf->new_bssid && 15576 param_buf->num_new_bssid == num_scans) 15577 new_bssid = param_buf->new_bssid; 15578 15579 if (param_buf->is_roaming_success && 15580 param_buf->num_is_roaming_success == num_scans) 15581 is_roaming_success = param_buf->is_roaming_success; 15582 15583 if (param_buf->roam_reason && 15584 param_buf->num_roam_reason == num_scans) 15585 roam_reason = param_buf->roam_reason; 15586 15587 if (param_buf->num_channels && 15588 param_buf->num_num_channels == num_scans) { 15589 uint32_t count, chan_info_sum = 0; 15590 15591 num_channels = param_buf->num_channels; 15592 for (count = 0; count < param_buf->num_num_channels; count++) { 15593 if (param_buf->num_channels[count] > 15594 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 15595 wmi_err_rl("%u exceeded max scan channels %u", 15596 param_buf->num_channels[count], 15597 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 15598 goto error; 15599 } 15600 chan_info_sum += param_buf->num_channels[count]; 15601 } 15602 15603 if (param_buf->chan_info && 15604 param_buf->num_chan_info == chan_info_sum) 15605 chan_info = param_buf->chan_info; 15606 } 15607 15608 if (param_buf->num_roam_candidates && 15609 param_buf->num_num_roam_candidates == num_scans) { 15610 uint32_t cnt, roam_cand_sum = 0; 15611 15612 num_roam_candidates = param_buf->num_roam_candidates; 15613 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 15614 if (param_buf->num_roam_candidates[cnt] > 15615 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 15616 wmi_err_rl("%u exceeded max scan cand %u", 15617 param_buf->num_roam_candidates[cnt], 15618 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 15619 goto error; 15620 } 15621 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 15622 } 15623 15624 if (param_buf->bssid && 15625 param_buf->num_bssid == roam_cand_sum) 15626 bssid = param_buf->bssid; 15627 15628 if (param_buf->score && 15629 param_buf->num_score == roam_cand_sum) 15630 score = param_buf->score; 15631 15632 if (param_buf->channel && 15633 param_buf->num_channel == roam_cand_sum) 15634 channel = param_buf->channel; 15635 15636 if (param_buf->rssi && 15637 param_buf->num_rssi == roam_cand_sum) 15638 rssi = param_buf->rssi; 15639 } 15640 15641 res->num_roam_scans = num_scans; 15642 for (i = 0; i < num_scans; i++) { 15643 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 15644 15645 if (timestamp) 15646 roam->time_stamp = timestamp[i].lower32bit | 15647 (timestamp[i].upper32bit << 31); 15648 15649 if (client_id) 15650 roam->client_id = client_id[i]; 15651 15652 if (num_channels) { 15653 roam->num_scan_chans = num_channels[i]; 15654 if (chan_info) { 15655 for (j = 0; j < num_channels[i]; j++) 15656 roam->scan_freqs[j] = 15657 chan_info[chan_idx++]; 15658 } 15659 } 15660 15661 if (is_roaming_success) 15662 roam->is_roam_successful = is_roaming_success[i]; 15663 15664 if (roam_reason) { 15665 roam->trigger_id = roam_reason[i].trigger_id; 15666 roam->trigger_value = roam_reason[i].trigger_value; 15667 } 15668 15669 if (num_roam_candidates) { 15670 roam->num_roam_candidates = num_roam_candidates[i]; 15671 15672 for (j = 0; j < num_roam_candidates[i]; j++) { 15673 if (score) 15674 roam->cand[j].score = score[cand_idx]; 15675 if (rssi) 15676 roam->cand[j].rssi = rssi[cand_idx]; 15677 if (channel) 15678 roam->cand[j].freq = 15679 channel[cand_idx]; 15680 15681 if (bssid) 15682 WMI_MAC_ADDR_TO_CHAR_ARRAY( 15683 &bssid[cand_idx], 15684 roam->cand[j].bssid); 15685 15686 cand_idx++; 15687 } 15688 } 15689 15690 if (old_bssid) 15691 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 15692 roam->old_bssid); 15693 15694 if (new_bssid) 15695 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 15696 roam->new_bssid); 15697 } 15698 15699 *res_param = res; 15700 15701 return QDF_STATUS_SUCCESS; 15702 error: 15703 qdf_mem_free(res); 15704 return QDF_STATUS_E_FAILURE; 15705 } 15706 15707 /** 15708 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 15709 * @wmi_handle: wmi handle 15710 * @evt_buf: pointer to event buffer 15711 * @vdev_id: output pointer to hold vdev id 15712 * @tx_status: output pointer to hold the tx_status 15713 * 15714 * Return: QDF_STATUS 15715 */ 15716 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 15717 void *evt_buf, 15718 uint32_t *vdev_id, 15719 uint32_t *tx_status) { 15720 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 15721 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 15722 15723 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 15724 if (!param_buf) { 15725 wmi_err("Invalid offload bcn tx status event buffer"); 15726 return QDF_STATUS_E_INVAL; 15727 } 15728 15729 bcn_tx_status_event = param_buf->fixed_param; 15730 *vdev_id = bcn_tx_status_event->vdev_id; 15731 *tx_status = bcn_tx_status_event->tx_status; 15732 15733 return QDF_STATUS_SUCCESS; 15734 } 15735 15736 #ifdef WLAN_SUPPORT_GREEN_AP 15737 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 15738 uint8_t *evt_buf, 15739 struct wlan_green_ap_egap_status_info *egap_status_info_params) 15740 { 15741 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 15742 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 15743 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 15744 15745 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 15746 if (!param_buf) { 15747 wmi_err("Invalid EGAP Info status event buffer"); 15748 return QDF_STATUS_E_INVAL; 15749 } 15750 15751 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 15752 param_buf->fixed_param; 15753 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 15754 param_buf->chainmask_list; 15755 15756 if (!egap_info_event || !chainmask_event) { 15757 wmi_err("Invalid EGAP Info event or chainmask event"); 15758 return QDF_STATUS_E_INVAL; 15759 } 15760 15761 egap_status_info_params->status = egap_info_event->status; 15762 egap_status_info_params->mac_id = chainmask_event->mac_id; 15763 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 15764 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 15765 15766 return QDF_STATUS_SUCCESS; 15767 } 15768 #endif 15769 15770 /* 15771 * extract_comb_phyerr_tlv() - extract comb phy error from event 15772 * @wmi_handle: wmi handle 15773 * @evt_buf: pointer to event buffer 15774 * @datalen: data length of event buffer 15775 * @buf_offset: Pointer to hold value of current event buffer offset 15776 * post extraction 15777 * @phyerr: Pointer to hold phyerr 15778 * 15779 * Return: QDF_STATUS 15780 */ 15781 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 15782 void *evt_buf, 15783 uint16_t datalen, 15784 uint16_t *buf_offset, 15785 wmi_host_phyerr_t *phyerr) 15786 { 15787 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 15788 wmi_comb_phyerr_rx_hdr *pe_hdr; 15789 15790 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 15791 if (!param_tlvs) { 15792 wmi_debug("Received null data from FW"); 15793 return QDF_STATUS_E_FAILURE; 15794 } 15795 15796 pe_hdr = param_tlvs->hdr; 15797 if (!pe_hdr) { 15798 wmi_debug("Received Data PE Header is NULL"); 15799 return QDF_STATUS_E_FAILURE; 15800 } 15801 15802 /* Ensure it's at least the size of the header */ 15803 if (datalen < sizeof(*pe_hdr)) { 15804 wmi_debug("Expected minimum size %zu, received %d", 15805 sizeof(*pe_hdr), datalen); 15806 return QDF_STATUS_E_FAILURE; 15807 } 15808 15809 phyerr->pdev_id = wmi_handle->ops-> 15810 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 15811 phyerr->tsf64 = pe_hdr->tsf_l32; 15812 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 15813 phyerr->bufp = param_tlvs->bufp; 15814 15815 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 15816 wmi_debug("Invalid buf_len %d, num_bufp %d", 15817 pe_hdr->buf_len, param_tlvs->num_bufp); 15818 return QDF_STATUS_E_FAILURE; 15819 } 15820 15821 phyerr->buf_len = pe_hdr->buf_len; 15822 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 15823 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 15824 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 15825 15826 return QDF_STATUS_SUCCESS; 15827 } 15828 15829 /** 15830 * extract_single_phyerr_tlv() - extract single phy error from event 15831 * @wmi_handle: wmi handle 15832 * @evt_buf: pointer to event buffer 15833 * @datalen: data length of event buffer 15834 * @buf_offset: Pointer to hold value of current event buffer offset 15835 * post extraction 15836 * @phyerr: Pointer to hold phyerr 15837 * 15838 * Return: QDF_STATUS 15839 */ 15840 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 15841 void *evt_buf, 15842 uint16_t datalen, 15843 uint16_t *buf_offset, 15844 wmi_host_phyerr_t *phyerr) 15845 { 15846 wmi_single_phyerr_rx_event *ev; 15847 uint16_t n = *buf_offset; 15848 uint8_t *data = (uint8_t *)evt_buf; 15849 15850 if (n < datalen) { 15851 if ((datalen - n) < sizeof(ev->hdr)) { 15852 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 15853 datalen, n, sizeof(ev->hdr)); 15854 return QDF_STATUS_E_FAILURE; 15855 } 15856 15857 /* 15858 * Obtain a pointer to the beginning of the current event. 15859 * data[0] is the beginning of the WMI payload. 15860 */ 15861 ev = (wmi_single_phyerr_rx_event *)&data[n]; 15862 15863 /* 15864 * Sanity check the buffer length of the event against 15865 * what we currently have. 15866 * 15867 * Since buf_len is 32 bits, we check if it overflows 15868 * a large 32 bit value. It's not 0x7fffffff because 15869 * we increase n by (buf_len + sizeof(hdr)), which would 15870 * in itself cause n to overflow. 15871 * 15872 * If "int" is 64 bits then this becomes a moot point. 15873 */ 15874 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 15875 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 15876 return QDF_STATUS_E_FAILURE; 15877 } 15878 15879 if ((n + ev->hdr.buf_len) > datalen) { 15880 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 15881 n, ev->hdr.buf_len, datalen); 15882 return QDF_STATUS_E_FAILURE; 15883 } 15884 15885 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 15886 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 15887 phyerr->bufp = &ev->bufp[0]; 15888 phyerr->buf_len = ev->hdr.buf_len; 15889 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 15890 15891 /* 15892 * Advance the buffer pointer to the next PHY error. 15893 * buflen is the length of this payload, so we need to 15894 * advance past the current header _AND_ the payload. 15895 */ 15896 n += sizeof(*ev) + ev->hdr.buf_len; 15897 } 15898 *buf_offset = n; 15899 15900 return QDF_STATUS_SUCCESS; 15901 } 15902 15903 /** 15904 * extract_esp_estimation_ev_param_tlv() - extract air time from event 15905 * @wmi_handle: wmi handle 15906 * @evt_buf: pointer to event buffer 15907 * @param: Pointer to hold esp event 15908 * 15909 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 15910 */ 15911 static QDF_STATUS 15912 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 15913 void *evt_buf, 15914 struct esp_estimation_event *param) 15915 { 15916 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 15917 wmi_esp_estimate_event_fixed_param *esp_event; 15918 15919 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 15920 if (!param_buf) { 15921 wmi_err("Invalid ESP Estimate Event buffer"); 15922 return QDF_STATUS_E_INVAL; 15923 } 15924 esp_event = param_buf->fixed_param; 15925 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 15926 15927 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 15928 wmi_handle, 15929 esp_event->pdev_id); 15930 15931 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 15932 return QDF_STATUS_E_FAILURE; 15933 15934 return QDF_STATUS_SUCCESS; 15935 } 15936 15937 /* 15938 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 15939 * updating bss color change within firmware when AP announces bss color change. 15940 * @wmi_handle: wmi handle 15941 * @vdev_id: vdev ID 15942 * @enable: enable bss color change within firmware 15943 * 15944 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 15945 * 15946 * Return: QDF_STATUS 15947 */ 15948 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 15949 uint32_t vdev_id, 15950 bool enable) 15951 { 15952 wmi_buf_t buf; 15953 wmi_bss_color_change_enable_fixed_param *cmd; 15954 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 15955 15956 buf = wmi_buf_alloc(wmi_handle, len); 15957 if (!buf) 15958 return QDF_STATUS_E_NOMEM; 15959 15960 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 15961 WMITLV_SET_HDR(&cmd->tlv_header, 15962 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 15963 WMITLV_GET_STRUCT_TLVLEN 15964 (wmi_bss_color_change_enable_fixed_param)); 15965 cmd->vdev_id = vdev_id; 15966 cmd->enable = enable; 15967 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 15968 if (wmi_unified_cmd_send(wmi_handle, buf, len, 15969 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 15970 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 15971 wmi_buf_free(buf); 15972 return QDF_STATUS_E_FAILURE; 15973 } 15974 15975 return QDF_STATUS_SUCCESS; 15976 } 15977 15978 /** 15979 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 15980 * configurations to firmware. 15981 * @wmi_handle: wmi handle 15982 * @cfg_param: obss detection configurations 15983 * 15984 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 15985 * 15986 * Return: QDF_STATUS 15987 */ 15988 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 15989 wmi_unified_t wmi_handle, 15990 struct wmi_obss_color_collision_cfg_param *cfg_param) 15991 { 15992 wmi_buf_t buf; 15993 wmi_obss_color_collision_det_config_fixed_param *cmd; 15994 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 15995 15996 buf = wmi_buf_alloc(wmi_handle, len); 15997 if (!buf) 15998 return QDF_STATUS_E_NOMEM; 15999 16000 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 16001 buf); 16002 WMITLV_SET_HDR(&cmd->tlv_header, 16003 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 16004 WMITLV_GET_STRUCT_TLVLEN 16005 (wmi_obss_color_collision_det_config_fixed_param)); 16006 cmd->vdev_id = cfg_param->vdev_id; 16007 cmd->flags = cfg_param->flags; 16008 cmd->current_bss_color = cfg_param->current_bss_color; 16009 cmd->detection_period_ms = cfg_param->detection_period_ms; 16010 cmd->scan_period_ms = cfg_param->scan_period_ms; 16011 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 16012 16013 switch (cfg_param->evt_type) { 16014 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 16015 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 16016 break; 16017 case OBSS_COLOR_COLLISION_DETECTION: 16018 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 16019 break; 16020 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 16021 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 16022 break; 16023 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 16024 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 16025 break; 16026 default: 16027 wmi_err("Invalid event type: %d", cfg_param->evt_type); 16028 wmi_buf_free(buf); 16029 return QDF_STATUS_E_FAILURE; 16030 } 16031 16032 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 16033 "detection_period_ms: %d scan_period_ms: %d " 16034 "free_slot_expiry_timer_ms: %d", 16035 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 16036 cmd->detection_period_ms, cmd->scan_period_ms, 16037 cmd->free_slot_expiry_time_ms); 16038 16039 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 16040 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16041 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 16042 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 16043 cfg_param->vdev_id); 16044 wmi_buf_free(buf); 16045 return QDF_STATUS_E_FAILURE; 16046 } 16047 16048 return QDF_STATUS_SUCCESS; 16049 } 16050 16051 /** 16052 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 16053 * received from firmware. 16054 * @evt_buf: pointer to event buffer 16055 * @info: Pointer to hold bss collision info 16056 * 16057 * Return: QDF_STATUS 16058 */ 16059 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 16060 struct wmi_obss_color_collision_info *info) 16061 { 16062 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 16063 wmi_obss_color_collision_evt_fixed_param *fix_param; 16064 16065 if (!info) { 16066 wmi_err("Invalid obss color buffer"); 16067 return QDF_STATUS_E_INVAL; 16068 } 16069 16070 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 16071 evt_buf; 16072 if (!param_buf) { 16073 wmi_err("Invalid evt_buf"); 16074 return QDF_STATUS_E_INVAL; 16075 } 16076 16077 fix_param = param_buf->fixed_param; 16078 info->vdev_id = fix_param->vdev_id; 16079 info->obss_color_bitmap_bit0to31 = 16080 fix_param->bss_color_bitmap_bit0to31; 16081 info->obss_color_bitmap_bit32to63 = 16082 fix_param->bss_color_bitmap_bit32to63; 16083 16084 switch (fix_param->evt_type) { 16085 case WMI_BSS_COLOR_COLLISION_DISABLE: 16086 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 16087 break; 16088 case WMI_BSS_COLOR_COLLISION_DETECTION: 16089 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 16090 break; 16091 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 16092 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 16093 break; 16094 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 16095 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 16096 break; 16097 default: 16098 wmi_err("Invalid event type: %d, vdev_id: %d", 16099 fix_param->evt_type, fix_param->vdev_id); 16100 return QDF_STATUS_E_FAILURE; 16101 } 16102 16103 return QDF_STATUS_SUCCESS; 16104 } 16105 16106 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 16107 { 16108 struct wmi_ops *ops = wmi_handle->ops; 16109 16110 ops->send_obss_color_collision_cfg_cmd = 16111 send_obss_color_collision_cfg_cmd_tlv; 16112 ops->extract_obss_color_collision_info = 16113 extract_obss_color_collision_info_tlv; 16114 } 16115 16116 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 16117 static QDF_STATUS 16118 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 16119 struct config_fils_params *param) 16120 { 16121 wmi_buf_t buf; 16122 wmi_enable_fils_cmd_fixed_param *cmd; 16123 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 16124 16125 buf = wmi_buf_alloc(wmi_handle, len); 16126 if (!buf) 16127 return QDF_STATUS_E_NOMEM; 16128 16129 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 16130 buf); 16131 WMITLV_SET_HDR(&cmd->tlv_header, 16132 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 16133 WMITLV_GET_STRUCT_TLVLEN 16134 (wmi_enable_fils_cmd_fixed_param)); 16135 cmd->vdev_id = param->vdev_id; 16136 cmd->fd_period = param->fd_period; 16137 if (param->send_prb_rsp_frame) 16138 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 16139 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 16140 cmd->vdev_id, cmd->fd_period, cmd->flags); 16141 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 16142 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16143 WMI_ENABLE_FILS_CMDID)) { 16144 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 16145 wmi_buf_free(buf); 16146 return QDF_STATUS_E_FAILURE; 16147 } 16148 16149 return QDF_STATUS_SUCCESS; 16150 } 16151 #endif 16152 16153 #ifdef WLAN_MWS_INFO_DEBUGFS 16154 /** 16155 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 16156 * 16157 * @wmi_handle: wmi handle 16158 * @vdev_id: vdev id 16159 * @cmd_id: Coex command id 16160 * 16161 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 16162 * 16163 * Return: QDF_STATUS 16164 */ 16165 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 16166 uint32_t vdev_id, 16167 uint32_t cmd_id) 16168 { 16169 wmi_buf_t buf; 16170 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 16171 uint16_t len = sizeof(*cmd); 16172 int ret; 16173 16174 buf = wmi_buf_alloc(wmi_handle, len); 16175 if (!buf) { 16176 wmi_err("Failed to allocate wmi buffer"); 16177 return QDF_STATUS_E_NOMEM; 16178 } 16179 16180 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 16181 WMITLV_SET_HDR(&cmd->tlv_header, 16182 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 16183 WMITLV_GET_STRUCT_TLVLEN 16184 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 16185 cmd->vdev_id = vdev_id; 16186 cmd->cmd_id = cmd_id; 16187 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 16188 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16189 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 16190 if (QDF_IS_STATUS_ERROR(ret)) { 16191 wmi_err("Failed to send set param command ret = %d", ret); 16192 wmi_buf_free(buf); 16193 } 16194 return ret; 16195 } 16196 #endif 16197 16198 #ifdef FEATURE_MEC_OFFLOAD 16199 static QDF_STATUS 16200 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 16201 struct set_mec_timer_params *param) 16202 { 16203 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 16204 wmi_buf_t buf; 16205 int32_t len = sizeof(*cmd); 16206 16207 buf = wmi_buf_alloc(wmi_handle, len); 16208 if (!buf) { 16209 wmi_err("wmi_buf_alloc failed"); 16210 return QDF_STATUS_E_FAILURE; 16211 } 16212 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 16213 wmi_buf_data(buf); 16214 WMITLV_SET_HDR(&cmd->tlv_header, 16215 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 16216 WMITLV_GET_STRUCT_TLVLEN( 16217 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 16218 cmd->pdev_id = param->pdev_id; 16219 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 16220 16221 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 16222 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16223 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 16224 wmi_err("Failed to set mec aging timer param"); 16225 wmi_buf_free(buf); 16226 return QDF_STATUS_E_FAILURE; 16227 } 16228 16229 return QDF_STATUS_SUCCESS; 16230 } 16231 #endif 16232 16233 #ifdef WIFI_POS_CONVERGED 16234 /** 16235 * extract_oem_response_param_tlv() - Extract oem response params 16236 * @wmi_handle: wmi handle 16237 * @resp_buf: response buffer 16238 * @oem_resp_param: pointer to hold oem response params 16239 * 16240 * Return: QDF_STATUS_SUCCESS on success or proper error code. 16241 */ 16242 static QDF_STATUS 16243 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 16244 struct wmi_oem_response_param *oem_resp_param) 16245 { 16246 uint64_t temp_addr; 16247 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 16248 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 16249 16250 if (!param_buf) { 16251 wmi_err("Invalid OEM response"); 16252 return QDF_STATUS_E_INVAL; 16253 } 16254 16255 if (param_buf->num_data) { 16256 oem_resp_param->num_data1 = param_buf->num_data; 16257 oem_resp_param->data_1 = param_buf->data; 16258 } 16259 16260 if (param_buf->num_data2) { 16261 oem_resp_param->num_data2 = param_buf->num_data2; 16262 oem_resp_param->data_2 = param_buf->data2; 16263 } 16264 16265 if (param_buf->indirect_data) { 16266 oem_resp_param->indirect_data.pdev_id = 16267 param_buf->indirect_data->pdev_id; 16268 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 16269 oem_resp_param->indirect_data.addr = 16270 param_buf->indirect_data->addr_lo + 16271 ((uint64_t)temp_addr << 32); 16272 oem_resp_param->indirect_data.len = 16273 param_buf->indirect_data->len; 16274 } 16275 16276 return QDF_STATUS_SUCCESS; 16277 } 16278 #endif /* WIFI_POS_CONVERGED */ 16279 16280 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 16281 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 16282 16283 static QDF_STATUS 16284 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16285 struct wifi_pos_pasn_peer_data *dst) 16286 { 16287 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 16288 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 16289 wmi_rtt_pasn_peer_create_req_param *buf; 16290 uint8_t security_mode, i; 16291 16292 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 16293 if (!param_buf) { 16294 wmi_err("Invalid peer_create req buffer"); 16295 return QDF_STATUS_E_INVAL; 16296 } 16297 16298 fixed_param = param_buf->fixed_param; 16299 16300 if (param_buf->num_rtt_pasn_peer_param > 16301 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 16302 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 16303 wmi_err("Invalid TLV size"); 16304 return QDF_STATUS_E_INVAL; 16305 } 16306 16307 if (!param_buf->num_rtt_pasn_peer_param || 16308 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 16309 wmi_err("Invalid num TLV:%d", 16310 param_buf->num_rtt_pasn_peer_param); 16311 return QDF_STATUS_E_INVAL; 16312 } 16313 16314 dst->vdev_id = fixed_param->vdev_id; 16315 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 16316 wmi_err("Invalid vdev id:%d", dst->vdev_id); 16317 return QDF_STATUS_E_INVAL; 16318 } 16319 16320 buf = param_buf->rtt_pasn_peer_param; 16321 if (!buf) { 16322 wmi_err("NULL peer param TLV"); 16323 return QDF_STATUS_E_INVAL; 16324 } 16325 16326 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 16327 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 16328 dst->peer_info[i].self_mac.bytes); 16329 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 16330 dst->peer_info[i].peer_mac.bytes); 16331 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 16332 buf->control_flag); 16333 if (security_mode) 16334 dst->peer_info[i].peer_type = 16335 WLAN_WIFI_POS_PASN_SECURE_PEER; 16336 else 16337 dst->peer_info[i].peer_type = 16338 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 16339 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 16340 dst->peer_info[i].is_ltf_keyseed_required = true; 16341 16342 dst->peer_info[i].force_self_mac_usage = 16343 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 16344 buf->control_flag); 16345 dst->num_peers++; 16346 buf++; 16347 } 16348 16349 return QDF_STATUS_SUCCESS; 16350 } 16351 16352 static QDF_STATUS 16353 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16354 struct wifi_pos_pasn_peer_data *dst) 16355 { 16356 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 16357 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 16358 wmi_rtt_pasn_peer_delete_param *buf; 16359 uint8_t i; 16360 16361 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 16362 if (!param_buf) { 16363 wmi_err("Invalid peer_delete evt buffer"); 16364 return QDF_STATUS_E_INVAL; 16365 } 16366 16367 fixed_param = param_buf->fixed_param; 16368 16369 if (param_buf->num_rtt_pasn_peer_param > 16370 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 16371 sizeof(wmi_rtt_pasn_peer_delete_param))) { 16372 wmi_err("Invalid TLV size"); 16373 return QDF_STATUS_E_INVAL; 16374 } 16375 16376 if (!param_buf->num_rtt_pasn_peer_param || 16377 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 16378 wmi_err("Invalid num TLV:%d", 16379 param_buf->num_rtt_pasn_peer_param); 16380 return QDF_STATUS_E_INVAL; 16381 } 16382 16383 dst->vdev_id = fixed_param->vdev_id; 16384 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 16385 wmi_err("Invalid vdev id:%d", dst->vdev_id); 16386 return QDF_STATUS_E_INVAL; 16387 } 16388 16389 buf = param_buf->rtt_pasn_peer_param; 16390 if (!buf) { 16391 wmi_err("NULL peer param TLV"); 16392 return QDF_STATUS_E_INVAL; 16393 } 16394 16395 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 16396 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 16397 dst->peer_info[i].peer_mac.bytes); 16398 dst->peer_info[i].control_flags = buf->control_flag; 16399 16400 dst->num_peers++; 16401 buf++; 16402 } 16403 16404 return QDF_STATUS_SUCCESS; 16405 } 16406 16407 static QDF_STATUS 16408 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 16409 struct wlan_pasn_auth_status *data) 16410 { 16411 QDF_STATUS status; 16412 wmi_buf_t buf; 16413 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 16414 uint8_t *buf_ptr; 16415 uint8_t i; 16416 size_t len = sizeof(*fixed_param) + 16417 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 16418 WMI_TLV_HDR_SIZE; 16419 16420 buf = wmi_buf_alloc(wmi_handle, len); 16421 if (!buf) { 16422 wmi_err("wmi_buf_alloc failed"); 16423 return QDF_STATUS_E_FAILURE; 16424 } 16425 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16426 fixed_param = 16427 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 16428 WMITLV_SET_HDR(&fixed_param->tlv_header, 16429 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 16430 WMITLV_GET_STRUCT_TLVLEN( 16431 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 16432 buf_ptr += sizeof(*fixed_param); 16433 16434 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 16435 (data->num_peers * 16436 sizeof(wmi_rtt_pasn_auth_status_param))); 16437 buf_ptr += WMI_TLV_HDR_SIZE; 16438 16439 for (i = 0; i < data->num_peers; i++) { 16440 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 16441 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 16442 16443 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 16444 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 16445 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 16446 16447 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 16448 &auth_status_tlv->peer_mac_addr); 16449 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 16450 &auth_status_tlv->source_mac_addr); 16451 auth_status_tlv->status = data->auth_status[i].status; 16452 16453 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 16454 } 16455 16456 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 16457 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16458 WMI_RTT_PASN_AUTH_STATUS_CMD); 16459 if (QDF_IS_STATUS_ERROR(status)) { 16460 wmi_err("Failed to send Auth status command ret = %d", status); 16461 wmi_buf_free(buf); 16462 } 16463 16464 return status; 16465 } 16466 16467 static QDF_STATUS 16468 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 16469 struct qdf_mac_addr *peer_mac) 16470 { 16471 QDF_STATUS status; 16472 wmi_buf_t buf; 16473 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 16474 size_t len = sizeof(*fixed_param); 16475 16476 buf = wmi_buf_alloc(wmi_handle, len); 16477 if (!buf) { 16478 wmi_err("wmi_buf_alloc failed"); 16479 return QDF_STATUS_E_FAILURE; 16480 } 16481 fixed_param = 16482 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 16483 WMITLV_SET_HDR(&fixed_param->tlv_header, 16484 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 16485 WMITLV_GET_STRUCT_TLVLEN( 16486 wmi_rtt_pasn_deauth_cmd_fixed_param)); 16487 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 16488 &fixed_param->peer_mac_addr); 16489 16490 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 16491 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16492 WMI_RTT_PASN_DEAUTH_CMD); 16493 if (QDF_IS_STATUS_ERROR(status)) { 16494 wmi_err("Failed to send pasn deauth command ret = %d", status); 16495 wmi_buf_free(buf); 16496 } 16497 16498 return status; 16499 } 16500 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 16501 16502 static QDF_STATUS 16503 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 16504 struct wlan_crypto_ltf_keyseed_data *data) 16505 { 16506 QDF_STATUS status; 16507 wmi_buf_t buf; 16508 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 16509 uint8_t *buf_ptr; 16510 size_t len = sizeof(*fixed_param) + data->key_seed_len + 16511 WMI_TLV_HDR_SIZE; 16512 16513 buf = wmi_buf_alloc(wmi_handle, len); 16514 if (!buf) { 16515 wmi_err("wmi_buf_alloc failed"); 16516 return QDF_STATUS_E_FAILURE; 16517 } 16518 16519 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16520 fixed_param = 16521 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 16522 WMITLV_SET_HDR(&fixed_param->tlv_header, 16523 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 16524 WMITLV_GET_STRUCT_TLVLEN( 16525 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 16526 16527 fixed_param->vdev_id = data->vdev_id; 16528 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 16529 &fixed_param->peer_macaddr); 16530 fixed_param->key_seed_len = data->key_seed_len; 16531 fixed_param->rsn_authmode = data->rsn_authmode; 16532 16533 buf_ptr += sizeof(*fixed_param); 16534 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 16535 (fixed_param->key_seed_len * sizeof(A_UINT8))); 16536 buf_ptr += WMI_TLV_HDR_SIZE; 16537 16538 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 16539 16540 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 16541 status = wmi_unified_cmd_send(wmi_handle, buf, len, 16542 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 16543 if (QDF_IS_STATUS_ERROR(status)) { 16544 wmi_err("Failed to send ltf keyseed command ret = %d", status); 16545 wmi_buf_free(buf); 16546 } 16547 16548 return status; 16549 } 16550 16551 /** 16552 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 16553 * @wmi_handle: wmi handle 16554 * @event_buf: pointer to event buffer 16555 * @cmd_status: status of HW mode change command 16556 * 16557 * Return QDF_STATUS_SUCCESS on success or proper error code. 16558 */ 16559 static QDF_STATUS 16560 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16561 uint32_t *cmd_status) 16562 { 16563 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 16564 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 16565 16566 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 16567 if (!param_buf) { 16568 wmi_err("Invalid mode change event buffer"); 16569 return QDF_STATUS_E_INVAL; 16570 } 16571 16572 fixed_param = param_buf->fixed_param; 16573 if (!fixed_param) { 16574 wmi_err("Invalid fixed param"); 16575 return QDF_STATUS_E_INVAL; 16576 } 16577 16578 *cmd_status = fixed_param->status; 16579 return QDF_STATUS_SUCCESS; 16580 } 16581 16582 #ifdef FEATURE_ANI_LEVEL_REQUEST 16583 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 16584 uint32_t *freqs, 16585 uint8_t num_freqs) 16586 { 16587 wmi_buf_t buf; 16588 wmi_get_channel_ani_cmd_fixed_param *cmd; 16589 QDF_STATUS ret; 16590 uint32_t len; 16591 A_UINT32 *chan_list; 16592 uint8_t i, *buf_ptr; 16593 16594 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 16595 WMI_TLV_HDR_SIZE + 16596 num_freqs * sizeof(A_UINT32); 16597 16598 buf = wmi_buf_alloc(wmi_handle, len); 16599 if (!buf) 16600 return QDF_STATUS_E_FAILURE; 16601 16602 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16603 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 16604 WMITLV_SET_HDR(&cmd->tlv_header, 16605 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 16606 WMITLV_GET_STRUCT_TLVLEN( 16607 wmi_get_channel_ani_cmd_fixed_param)); 16608 16609 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 16610 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 16611 (num_freqs * sizeof(A_UINT32))); 16612 16613 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 16614 for (i = 0; i < num_freqs; i++) { 16615 chan_list[i] = freqs[i]; 16616 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 16617 } 16618 16619 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16620 WMI_GET_CHANNEL_ANI_CMDID); 16621 16622 if (QDF_IS_STATUS_ERROR(ret)) { 16623 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 16624 wmi_buf_free(buf); 16625 } 16626 16627 return ret; 16628 } 16629 16630 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 16631 struct wmi_host_ani_level_event **info, 16632 uint32_t *num_freqs) 16633 { 16634 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 16635 wmi_get_channel_ani_event_fixed_param *fixed_param; 16636 wmi_channel_ani_info_tlv_param *tlv_params; 16637 uint8_t *buf_ptr, i; 16638 16639 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 16640 if (!param_buf) { 16641 wmi_err("Invalid ani level event buffer"); 16642 return QDF_STATUS_E_INVAL; 16643 } 16644 16645 fixed_param = 16646 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 16647 if (!fixed_param) { 16648 wmi_err("Invalid fixed param"); 16649 return QDF_STATUS_E_INVAL; 16650 } 16651 16652 buf_ptr = (uint8_t *)fixed_param; 16653 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 16654 buf_ptr += WMI_TLV_HDR_SIZE; 16655 16656 *num_freqs = param_buf->num_ani_info; 16657 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 16658 wmi_err("Invalid number of freqs received"); 16659 return QDF_STATUS_E_INVAL; 16660 } 16661 16662 *info = qdf_mem_malloc(*num_freqs * 16663 sizeof(struct wmi_host_ani_level_event)); 16664 if (!(*info)) 16665 return QDF_STATUS_E_NOMEM; 16666 16667 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 16668 for (i = 0; i < param_buf->num_ani_info; i++) { 16669 (*info)[i].ani_level = tlv_params->ani_level; 16670 (*info)[i].chan_freq = tlv_params->chan_freq; 16671 tlv_params++; 16672 } 16673 16674 return QDF_STATUS_SUCCESS; 16675 } 16676 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 16677 16678 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 16679 /** 16680 * convert_wtc_scan_mode() - Function to convert TLV specific 16681 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 16682 * @scan_mode: scan freq scheme coming from firmware 16683 * 16684 * Return: ROAM_TRIGGER_SCAN_MODE 16685 */ 16686 static enum roam_scan_freq_scheme 16687 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 16688 { 16689 switch (scan_mode) { 16690 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 16691 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 16692 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 16693 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 16694 case ROAM_TRIGGER_SCAN_MODE_FULL: 16695 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 16696 default: 16697 return ROAM_SCAN_FREQ_SCHEME_NONE; 16698 } 16699 } 16700 16701 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 16702 { 16703 switch (fw_trig_reason) { 16704 case WMI_ROAM_TRIGGER_REASON_NONE: 16705 return ROAM_TRIGGER_REASON_NONE; 16706 case WMI_ROAM_TRIGGER_REASON_PER: 16707 return ROAM_TRIGGER_REASON_PER; 16708 case WMI_ROAM_TRIGGER_REASON_BMISS: 16709 return ROAM_TRIGGER_REASON_BMISS; 16710 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 16711 return ROAM_TRIGGER_REASON_LOW_RSSI; 16712 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 16713 return ROAM_TRIGGER_REASON_HIGH_RSSI; 16714 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 16715 return ROAM_TRIGGER_REASON_PERIODIC; 16716 case WMI_ROAM_TRIGGER_REASON_MAWC: 16717 return ROAM_TRIGGER_REASON_MAWC; 16718 case WMI_ROAM_TRIGGER_REASON_DENSE: 16719 return ROAM_TRIGGER_REASON_DENSE; 16720 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 16721 return ROAM_TRIGGER_REASON_BACKGROUND; 16722 case WMI_ROAM_TRIGGER_REASON_FORCED: 16723 return ROAM_TRIGGER_REASON_FORCED; 16724 case WMI_ROAM_TRIGGER_REASON_BTM: 16725 return ROAM_TRIGGER_REASON_BTM; 16726 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 16727 return ROAM_TRIGGER_REASON_UNIT_TEST; 16728 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 16729 return ROAM_TRIGGER_REASON_BSS_LOAD; 16730 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 16731 return ROAM_TRIGGER_REASON_DEAUTH; 16732 case WMI_ROAM_TRIGGER_REASON_IDLE: 16733 return ROAM_TRIGGER_REASON_IDLE; 16734 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 16735 return ROAM_TRIGGER_REASON_STA_KICKOUT; 16736 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 16737 return ROAM_TRIGGER_REASON_ESS_RSSI; 16738 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 16739 return ROAM_TRIGGER_REASON_WTC_BTM; 16740 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 16741 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 16742 case WMI_ROAM_TRIGGER_REASON_BTC: 16743 return ROAM_TRIGGER_REASON_BTC; 16744 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 16745 return ROAM_TRIGGER_REASON_MAX; 16746 default: 16747 return ROAM_TRIGGER_REASON_NONE; 16748 } 16749 } 16750 16751 /** 16752 * extract_roam_11kv_candidate_info - Extract btm candidate info 16753 * @wmi_handle: wmi_handle 16754 * @evt_buf: Event buffer 16755 * @dst_info: Destination buffer 16756 * 16757 * Return: QDF_STATUS 16758 */ 16759 static QDF_STATUS 16760 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 16761 struct wmi_btm_req_candidate_info *dst_info, 16762 uint8_t btm_idx, uint16_t num_cand) 16763 { 16764 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 16765 wmi_roam_btm_request_candidate_info *src_data; 16766 uint8_t i; 16767 16768 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 16769 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 16770 !param_buf->num_roam_btm_request_candidate_info || 16771 (btm_idx + 16772 num_cand) > param_buf->num_roam_btm_request_candidate_info) 16773 return QDF_STATUS_SUCCESS; 16774 16775 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 16776 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 16777 num_cand = WLAN_MAX_BTM_CANDIDATE; 16778 for (i = 0; i < num_cand; i++) { 16779 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 16780 dst_info->candidate_bssid.bytes); 16781 dst_info->preference = src_data->preference; 16782 src_data++; 16783 dst_info++; 16784 } 16785 16786 return QDF_STATUS_SUCCESS; 16787 } 16788 16789 static enum roam_trigger_sub_reason 16790 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 16791 { 16792 switch (subreason) { 16793 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 16794 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 16795 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 16796 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 16797 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 16798 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 16799 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 16800 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 16801 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 16802 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 16803 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 16804 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 16805 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 16806 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 16807 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 16808 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 16809 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 16810 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 16811 default: 16812 break; 16813 } 16814 16815 return 0; 16816 } 16817 16818 /** 16819 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 16820 * from the WMI_ROAM_STATS_EVENTID 16821 * @wmi_handle: wmi handle 16822 * @evt_buf: Pointer to the event buffer 16823 * @trig: Pointer to destination structure to fill data 16824 * @idx: TLV id 16825 */ 16826 static QDF_STATUS 16827 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16828 struct wmi_roam_trigger_info *trig, uint8_t idx, 16829 uint8_t btm_idx) 16830 { 16831 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 16832 wmi_roam_trigger_reason *src_data = NULL; 16833 uint32_t trig_reason; 16834 16835 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 16836 if (!param_buf || !param_buf->roam_trigger_reason) 16837 return QDF_STATUS_E_FAILURE; 16838 16839 src_data = ¶m_buf->roam_trigger_reason[idx]; 16840 16841 trig->present = true; 16842 trig_reason = src_data->trigger_reason; 16843 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 16844 trig->trigger_sub_reason = 16845 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 16846 trig->current_rssi = src_data->current_rssi; 16847 trig->timestamp = src_data->timestamp; 16848 16849 switch (trig_reason) { 16850 case WMI_ROAM_TRIGGER_REASON_PER: 16851 case WMI_ROAM_TRIGGER_REASON_BMISS: 16852 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 16853 case WMI_ROAM_TRIGGER_REASON_MAWC: 16854 case WMI_ROAM_TRIGGER_REASON_DENSE: 16855 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 16856 case WMI_ROAM_TRIGGER_REASON_IDLE: 16857 case WMI_ROAM_TRIGGER_REASON_FORCED: 16858 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 16859 case WMI_ROAM_TRIGGER_REASON_BTC: 16860 return QDF_STATUS_SUCCESS; 16861 16862 case WMI_ROAM_TRIGGER_REASON_BTM: 16863 trig->btm_trig_data.btm_request_mode = 16864 src_data->btm_request_mode; 16865 trig->btm_trig_data.disassoc_timer = 16866 src_data->disassoc_imminent_timer; 16867 trig->btm_trig_data.validity_interval = 16868 src_data->validity_internal; 16869 trig->btm_trig_data.candidate_list_count = 16870 src_data->candidate_list_count; 16871 trig->btm_trig_data.btm_resp_status = 16872 src_data->btm_response_status_code; 16873 trig->btm_trig_data.btm_bss_termination_timeout = 16874 src_data->btm_bss_termination_timeout; 16875 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 16876 src_data->btm_mbo_assoc_retry_timeout; 16877 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 16878 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 16879 param_buf->num_roam_btm_request_candidate_info) 16880 extract_roam_11kv_candidate_info( 16881 wmi_handle, evt_buf, 16882 trig->btm_trig_data.btm_cand, 16883 btm_idx, 16884 src_data->candidate_list_count); 16885 16886 return QDF_STATUS_SUCCESS; 16887 16888 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 16889 trig->cu_trig_data.cu_load = src_data->cu_load; 16890 return QDF_STATUS_SUCCESS; 16891 16892 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 16893 trig->deauth_trig_data.type = src_data->deauth_type; 16894 trig->deauth_trig_data.reason = src_data->deauth_reason; 16895 return QDF_STATUS_SUCCESS; 16896 16897 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 16898 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 16899 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 16900 return QDF_STATUS_SUCCESS; 16901 16902 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 16903 trig->wtc_btm_trig_data.roaming_mode = 16904 src_data->vendor_specific1[0]; 16905 trig->wtc_btm_trig_data.vsie_trigger_reason = 16906 src_data->vendor_specific1[1]; 16907 trig->wtc_btm_trig_data.sub_code = 16908 src_data->vendor_specific1[2]; 16909 trig->wtc_btm_trig_data.wtc_mode = 16910 src_data->vendor_specific1[3]; 16911 trig->wtc_btm_trig_data.wtc_scan_mode = 16912 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 16913 trig->wtc_btm_trig_data.wtc_rssi_th = 16914 src_data->vendor_specific1[5]; 16915 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 16916 src_data->vendor_specific1[6]; 16917 16918 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 16919 src_data->vendor_specific2[0]; 16920 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 16921 src_data->vendor_specific2[1]; 16922 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 16923 src_data->vendor_specific2[2]; 16924 trig->wtc_btm_trig_data.duration = 16925 src_data->vendor_specific2[3]; 16926 16927 return QDF_STATUS_SUCCESS; 16928 default: 16929 return QDF_STATUS_SUCCESS; 16930 } 16931 16932 return QDF_STATUS_SUCCESS; 16933 } 16934 16935 /** 16936 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 16937 * from the WMI_ROAM_STATS_EVENTID 16938 * @wmi_handle: wmi handle 16939 * @evt_buf: Pointer to the event buffer 16940 * @dst: Pointer to destination structure to fill data 16941 * @ap_idx: TLV index for this roam scan 16942 * @num_cand: number of candidates list in the roam scan 16943 */ 16944 static QDF_STATUS 16945 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16946 struct wmi_roam_candidate_info *dst, 16947 uint8_t ap_idx, uint16_t num_cand) 16948 { 16949 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 16950 wmi_roam_ap_info *src = NULL; 16951 uint8_t i; 16952 16953 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 16954 if (!param_buf) { 16955 wmi_err("Param buf is NULL"); 16956 return QDF_STATUS_E_FAILURE; 16957 } 16958 16959 if (ap_idx >= param_buf->num_roam_ap_info) { 16960 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 16961 ap_idx, param_buf->num_roam_ap_info); 16962 return QDF_STATUS_E_FAILURE; 16963 } 16964 16965 src = ¶m_buf->roam_ap_info[ap_idx]; 16966 16967 for (i = 0; i < num_cand; i++) { 16968 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 16969 dst->type = src->candidate_type; 16970 dst->freq = src->channel; 16971 dst->etp = src->etp; 16972 dst->rssi = src->rssi; 16973 dst->rssi_score = src->rssi_score; 16974 dst->cu_load = src->cu_load; 16975 dst->cu_score = src->cu_score; 16976 dst->total_score = src->total_score; 16977 dst->timestamp = src->timestamp; 16978 dst->dl_reason = src->bl_reason; 16979 dst->dl_source = src->bl_source; 16980 dst->dl_timestamp = src->bl_timestamp; 16981 dst->dl_original_timeout = src->bl_original_timeout; 16982 16983 src++; 16984 dst++; 16985 } 16986 16987 return QDF_STATUS_SUCCESS; 16988 } 16989 16990 /** 16991 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 16992 * from the WMI_ROAM_STATS_EVENTID 16993 * @wmi_handle: wmi handle 16994 * @evt_buf: Pointer to the event buffer 16995 * @dst: Pointer to destination structure to fill data 16996 * @idx: TLV id 16997 * @chan_idx: Index of the channel tlv for the current roam trigger 16998 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 16999 */ 17000 static QDF_STATUS 17001 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17002 struct wmi_roam_scan_data *dst, uint8_t idx, 17003 uint8_t chan_idx, uint8_t ap_idx) 17004 { 17005 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17006 wmi_roam_scan_info *src_data = NULL; 17007 wmi_roam_scan_channel_info *src_chan = NULL; 17008 QDF_STATUS status; 17009 uint8_t i; 17010 17011 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17012 if (!param_buf || !param_buf->roam_scan_info || 17013 idx >= param_buf->num_roam_scan_info) 17014 return QDF_STATUS_E_FAILURE; 17015 17016 src_data = ¶m_buf->roam_scan_info[idx]; 17017 17018 dst->present = true; 17019 dst->type = src_data->roam_scan_type; 17020 dst->num_chan = src_data->roam_scan_channel_count; 17021 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 17022 dst->frame_info_count = src_data->frame_info_count; 17023 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 17024 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 17025 17026 /* Read the channel data only for dst->type is 0 (partial scan) */ 17027 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 17028 chan_idx < param_buf->num_roam_scan_chan_info) { 17029 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 17030 dst->num_chan = MAX_ROAM_SCAN_CHAN; 17031 17032 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 17033 for (i = 0; i < dst->num_chan; i++) { 17034 dst->chan_freq[i] = src_chan->channel; 17035 src_chan++; 17036 } 17037 } 17038 17039 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 17040 return QDF_STATUS_SUCCESS; 17041 17042 dst->num_ap = src_data->roam_ap_count; 17043 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 17044 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 17045 17046 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 17047 ap_idx, dst->num_ap); 17048 if (QDF_IS_STATUS_ERROR(status)) { 17049 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 17050 return status; 17051 } 17052 17053 return QDF_STATUS_SUCCESS; 17054 } 17055 17056 /** 17057 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 17058 * @wmi_roam_fail_reason: roam fail enum 17059 * 17060 * Return: Roaming failure reason codes 17061 */ 17062 static enum wlan_roam_failure_reason_code 17063 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 17064 { 17065 switch (wmi_roam_fail_reason) { 17066 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 17067 return ROAM_FAIL_REASON_NO_SCAN_START; 17068 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 17069 return ROAM_FAIL_REASON_NO_AP_FOUND; 17070 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 17071 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 17072 case WMI_ROAM_FAIL_REASON_HOST: 17073 return ROAM_FAIL_REASON_HOST; 17074 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 17075 return ROAM_FAIL_REASON_AUTH_SEND; 17076 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 17077 return ROAM_FAIL_REASON_AUTH_RECV; 17078 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 17079 return ROAM_FAIL_REASON_NO_AUTH_RESP; 17080 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 17081 return ROAM_FAIL_REASON_REASSOC_SEND; 17082 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 17083 return ROAM_FAIL_REASON_REASSOC_RECV; 17084 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 17085 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 17086 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 17087 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 17088 case WMI_ROAM_FAIL_REASON_MLME: 17089 return ROAM_FAIL_REASON_MLME; 17090 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 17091 return ROAM_FAIL_REASON_INTERNAL_ABORT; 17092 case WMI_ROAM_FAIL_REASON_SCAN_START: 17093 return ROAM_FAIL_REASON_SCAN_START; 17094 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 17095 return ROAM_FAIL_REASON_AUTH_NO_ACK; 17096 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 17097 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 17098 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 17099 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 17100 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 17101 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 17102 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 17103 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 17104 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 17105 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 17106 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 17107 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 17108 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 17109 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 17110 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 17111 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 17112 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 17113 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 17114 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 17115 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 17116 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 17117 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 17118 case WMI_ROAM_FAIL_REASON_DISCONNECT: 17119 return ROAM_FAIL_REASON_DISCONNECT; 17120 case WMI_ROAM_FAIL_REASON_SYNC: 17121 return ROAM_FAIL_REASON_SYNC; 17122 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 17123 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 17124 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 17125 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 17126 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 17127 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 17128 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 17129 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 17130 default: 17131 return ROAM_FAIL_REASON_UNKNOWN; 17132 } 17133 } 17134 17135 /** 17136 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 17137 * from the WMI_ROAM_STATS_EVENTID 17138 * @wmi_handle: wmi handle 17139 * @evt_buf: Pointer to the event buffer 17140 * @dst: Pointer to destination structure to fill data 17141 * @idx: TLV id 17142 */ 17143 static QDF_STATUS 17144 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17145 struct wmi_roam_result *dst, uint8_t idx) 17146 { 17147 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17148 wmi_roam_result *src_data = NULL; 17149 17150 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17151 if (!param_buf || !param_buf->roam_result || 17152 idx >= param_buf->num_roam_result) 17153 return QDF_STATUS_E_FAILURE; 17154 17155 src_data = ¶m_buf->roam_result[idx]; 17156 17157 dst->present = true; 17158 dst->status = src_data->roam_status; 17159 dst->timestamp = src_data->timestamp; 17160 dst->fail_reason = 17161 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 17162 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 17163 17164 return QDF_STATUS_SUCCESS; 17165 } 17166 17167 /** 17168 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 17169 * from the WMI_ROAM_STATS_EVENTID 17170 * @wmi_handle: wmi handle 17171 * @evt_buf: Pointer to the event buffer 17172 * @dst: Pointer to destination structure to fill data 17173 * @idx: TLV id 17174 * @rpt_idx: Neighbor report Channel index 17175 */ 17176 static QDF_STATUS 17177 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17178 struct wmi_neighbor_report_data *dst, 17179 uint8_t idx, uint8_t rpt_idx) 17180 { 17181 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 17182 wmi_roam_neighbor_report_info *src_data = NULL; 17183 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 17184 uint8_t i; 17185 17186 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 17187 if (!param_buf || !param_buf->roam_neighbor_report_info || 17188 !param_buf->num_roam_neighbor_report_info || 17189 idx >= param_buf->num_roam_neighbor_report_info) { 17190 wmi_debug("Invalid 1kv param buf"); 17191 return QDF_STATUS_E_FAILURE; 17192 } 17193 17194 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 17195 17196 dst->present = true; 17197 dst->req_type = src_data->request_type; 17198 dst->num_freq = src_data->neighbor_report_channel_count; 17199 dst->req_time = src_data->neighbor_report_request_timestamp; 17200 dst->resp_time = src_data->neighbor_report_response_timestamp; 17201 dst->btm_query_token = src_data->btm_query_token; 17202 dst->btm_query_reason = src_data->btm_query_reason_code; 17203 17204 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 17205 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 17206 return QDF_STATUS_SUCCESS; 17207 17208 if (!param_buf->roam_neighbor_report_chan_info) { 17209 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 17210 dst->num_freq); 17211 dst->num_freq = 0; 17212 /* return success as its optional tlv and we can print neighbor 17213 * report received info 17214 */ 17215 return QDF_STATUS_SUCCESS; 17216 } 17217 17218 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 17219 17220 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 17221 dst->num_freq = MAX_ROAM_SCAN_CHAN; 17222 17223 for (i = 0; i < dst->num_freq; i++) { 17224 dst->freq[i] = src_freq->channel; 17225 src_freq++; 17226 } 17227 17228 return QDF_STATUS_SUCCESS; 17229 } 17230 17231 /** 17232 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 17233 * @wmi_handle : handle to WMI. 17234 * @roam_param : pointer to hold roam set parameter 17235 * 17236 * Return: 0 on success and -ve on failure. 17237 */ 17238 static QDF_STATUS 17239 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 17240 struct vdev_set_params *roam_param) 17241 { 17242 QDF_STATUS ret; 17243 wmi_roam_set_param_cmd_fixed_param *cmd; 17244 wmi_buf_t buf; 17245 uint16_t len = sizeof(*cmd); 17246 17247 buf = wmi_buf_alloc(wmi_handle, len); 17248 if (!buf) 17249 return QDF_STATUS_E_NOMEM; 17250 17251 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 17252 WMITLV_SET_HDR(&cmd->tlv_header, 17253 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 17254 WMITLV_GET_STRUCT_TLVLEN 17255 (wmi_roam_set_param_cmd_fixed_param)); 17256 cmd->vdev_id = roam_param->vdev_id; 17257 cmd->param_id = roam_param->param_id; 17258 cmd->param_value = roam_param->param_value; 17259 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 17260 cmd->vdev_id, cmd->param_id, cmd->param_value); 17261 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 17262 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17263 WMI_ROAM_SET_PARAM_CMDID); 17264 if (QDF_IS_STATUS_ERROR(ret)) { 17265 wmi_err("Failed to send roam set param command, ret = %d", ret); 17266 wmi_buf_free(buf); 17267 } 17268 17269 return ret; 17270 } 17271 #else 17272 static inline QDF_STATUS 17273 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17274 struct wmi_roam_trigger_info *trig, uint8_t idx, 17275 uint8_t btm_idx) 17276 { 17277 return QDF_STATUS_E_NOSUPPORT; 17278 } 17279 17280 static inline QDF_STATUS 17281 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17282 struct wmi_roam_result *dst, uint8_t idx) 17283 { 17284 return QDF_STATUS_E_NOSUPPORT; 17285 } 17286 17287 static QDF_STATUS 17288 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17289 struct wmi_neighbor_report_data *dst, 17290 uint8_t idx, uint8_t rpt_idx) 17291 { 17292 return QDF_STATUS_E_NOSUPPORT; 17293 } 17294 17295 static QDF_STATUS 17296 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17297 struct wmi_roam_scan_data *dst, uint8_t idx, 17298 uint8_t chan_idx, uint8_t ap_idx) 17299 { 17300 return QDF_STATUS_E_NOSUPPORT; 17301 } 17302 #endif 17303 17304 #ifdef WLAN_FEATURE_PKT_CAPTURE 17305 static QDF_STATUS 17306 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 17307 struct mgmt_offload_event_params *params) 17308 { 17309 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 17310 wmi_mgmt_hdr *hdr; 17311 17312 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 17313 if (!param_tlvs) 17314 return QDF_STATUS_E_INVAL; 17315 17316 hdr = param_tlvs->fixed_param; 17317 if (!hdr) 17318 return QDF_STATUS_E_INVAL; 17319 17320 if (hdr->buf_len > param_tlvs->num_bufp) 17321 return QDF_STATUS_E_INVAL; 17322 17323 params->tsf_l32 = hdr->tsf_l32; 17324 params->chan_freq = hdr->chan_freq; 17325 params->rate_kbps = hdr->rate_kbps; 17326 params->rssi = hdr->rssi; 17327 params->buf_len = hdr->buf_len; 17328 params->tx_status = hdr->tx_status; 17329 params->buf = param_tlvs->bufp; 17330 params->tx_retry_cnt = hdr->tx_retry_cnt; 17331 return QDF_STATUS_SUCCESS; 17332 } 17333 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 17334 17335 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 17336 static QDF_STATUS 17337 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 17338 struct smu_event_params *params) 17339 { 17340 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 17341 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 17342 17343 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 17344 if (!param_buf) { 17345 wmi_err("Invalid smart monitor event"); 17346 return QDF_STATUS_E_INVAL; 17347 } 17348 17349 smu_event = param_buf->fixed_param; 17350 if (!smu_event) { 17351 wmi_err("smart monitor event fixed param is NULL"); 17352 return QDF_STATUS_E_INVAL; 17353 } 17354 17355 params->vdev_id = smu_event->vdev_id; 17356 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 17357 return QDF_STATUS_E_INVAL; 17358 17359 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 17360 17361 return QDF_STATUS_SUCCESS; 17362 } 17363 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 17364 17365 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 17366 /** 17367 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 17368 * 17369 * @wmi: wmi handle 17370 * @vdev_id: vdev id 17371 * @burst_mode: Indicates whether relation derived using FTM is needed for 17372 * each FTM frame or only aggregated result is required. 17373 * 17374 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 17375 * 17376 * Return: QDF_STATUS 17377 */ 17378 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 17379 uint32_t vdev_id, 17380 bool burst_mode) 17381 { 17382 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 17383 wmi_buf_t buf; 17384 int32_t len = sizeof(*cmd); 17385 17386 buf = wmi_buf_alloc(wmi, len); 17387 if (!buf) { 17388 wmi_err("wmi_buf_alloc failed"); 17389 return QDF_STATUS_E_NOMEM; 17390 } 17391 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 17392 WMITLV_SET_HDR(&cmd->tlv_header, 17393 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 17394 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 17395 cmd->vdev_id = vdev_id; 17396 cmd->agg_relation = burst_mode ? false : true; 17397 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 17398 wmi_err("Failed to send audio sync trigger cmd"); 17399 wmi_buf_free(buf); 17400 return QDF_STATUS_E_FAILURE; 17401 } 17402 17403 return QDF_STATUS_SUCCESS; 17404 } 17405 17406 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 17407 uint32_t vdev_id, 17408 uint64_t lpass_ts) 17409 { 17410 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 17411 wmi_buf_t buf; 17412 int32_t len = sizeof(*cmd); 17413 17414 buf = wmi_buf_alloc(wmi, len); 17415 if (!buf) { 17416 wmi_err("wmi_buf_alloc failed"); 17417 return QDF_STATUS_E_NOMEM; 17418 } 17419 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 17420 WMITLV_SET_HDR(&cmd->tlv_header, 17421 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 17422 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 17423 cmd->vdev_id = vdev_id; 17424 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 17425 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 17426 17427 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 17428 wmi_err("Failed to send audio qtime command"); 17429 wmi_buf_free(buf); 17430 return QDF_STATUS_E_FAILURE; 17431 } 17432 17433 return QDF_STATUS_SUCCESS; 17434 } 17435 17436 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 17437 wmi_unified_t wmi, void *buf, 17438 struct ftm_time_sync_start_stop_params *param) 17439 { 17440 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 17441 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 17442 17443 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 17444 if (!param_buf) { 17445 wmi_err("Invalid audio sync start stop event buffer"); 17446 return QDF_STATUS_E_FAILURE; 17447 } 17448 17449 resp_event = param_buf->fixed_param; 17450 if (!resp_event) { 17451 wmi_err("Invalid audio sync start stop fixed param buffer"); 17452 return QDF_STATUS_E_FAILURE; 17453 } 17454 17455 param->vdev_id = resp_event->vdev_id; 17456 param->timer_interval = resp_event->periodicity; 17457 param->num_reads = resp_event->reads_needed; 17458 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 17459 resp_event->qtimer_l32; 17460 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 17461 resp_event->mac_timer_l32; 17462 17463 wmi_debug("FTM time sync time_interval %d, num_reads %d", 17464 param->timer_interval, param->num_reads); 17465 17466 return QDF_STATUS_SUCCESS; 17467 } 17468 17469 static QDF_STATUS 17470 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 17471 struct ftm_time_sync_offset *param) 17472 { 17473 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 17474 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 17475 wmi_audio_sync_q_master_slave_times *q_pair; 17476 int iter; 17477 17478 param_buf = 17479 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 17480 if (!param_buf) { 17481 wmi_err("Invalid timesync ftm offset event buffer"); 17482 return QDF_STATUS_E_FAILURE; 17483 } 17484 17485 resp_event = param_buf->fixed_param; 17486 if (!resp_event) { 17487 wmi_err("Invalid timesync ftm offset fixed param buffer"); 17488 return QDF_STATUS_E_FAILURE; 17489 } 17490 17491 param->vdev_id = resp_event->vdev_id; 17492 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 17493 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 17494 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 17495 17496 q_pair = param_buf->audio_sync_q_master_slave_times; 17497 if (!q_pair) { 17498 wmi_err("Invalid q_master_slave_times buffer"); 17499 return QDF_STATUS_E_FAILURE; 17500 } 17501 17502 for (iter = 0; iter < param->num_qtime; iter++) { 17503 param->pairs[iter].qtime_initiator = ( 17504 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 17505 q_pair[iter].qmaster_l32; 17506 param->pairs[iter].qtime_target = ( 17507 (uint64_t)q_pair[iter].qslave_u32 << 32) | 17508 q_pair[iter].qslave_l32; 17509 } 17510 return QDF_STATUS_SUCCESS; 17511 } 17512 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 17513 17514 /** 17515 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 17516 * @wmi: wmi handle 17517 * @vdev_id: vdev id 17518 * 17519 * TSF_TSTAMP_READ_VALUE is the only operation supported 17520 * Return: QDF_STATUS_SUCCESS for success or erro code 17521 */ 17522 static QDF_STATUS 17523 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 17524 { 17525 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 17526 wmi_buf_t buf; 17527 int32_t len = sizeof(*cmd); 17528 17529 buf = wmi_buf_alloc(wmi, len); 17530 if (!buf) 17531 return QDF_STATUS_E_NOMEM; 17532 17533 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 17534 WMITLV_SET_HDR(&cmd->tlv_header, 17535 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 17536 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 17537 cmd->vdev_id = vdev_id; 17538 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 17539 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 17540 if (wmi_unified_cmd_send(wmi, buf, len, 17541 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 17542 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 17543 __func__); 17544 wmi_buf_free(buf); 17545 return QDF_STATUS_E_FAILURE; 17546 } 17547 17548 return QDF_STATUS_SUCCESS; 17549 } 17550 17551 /** 17552 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 17553 * @wmi_handle: wmi handle 17554 * @param evt_buf: pointer to event buffer 17555 * @wmi_host_tsf_event param: Pointer to struct to hold event info 17556 * 17557 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 17558 */ 17559 static QDF_STATUS 17560 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17561 struct wmi_host_tsf_event *param) 17562 { 17563 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 17564 wmi_vdev_tsf_report_event_fixed_param *evt; 17565 17566 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 17567 if (!param_buf) { 17568 wmi_err("Invalid tsf report event buffer"); 17569 return QDF_STATUS_E_INVAL; 17570 } 17571 17572 evt = param_buf->fixed_param; 17573 param->vdev_id = evt->vdev_id; 17574 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 17575 param->tsf_low = evt->tsf_low; 17576 param->tsf_high = evt->tsf_high; 17577 param->qtimer_low = evt->qtimer_low; 17578 param->qtimer_high = evt->qtimer_high; 17579 param->tsf_id = evt->tsf_id; 17580 param->tsf_id_valid = evt->tsf_id_valid; 17581 param->mac_id = evt->mac_id; 17582 param->mac_id_valid = evt->mac_id_valid; 17583 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 17584 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 17585 param->tqm_timer_low = evt->tqm_timer_low; 17586 param->tqm_timer_high = evt->tqm_timer_high; 17587 param->use_tqm_timer = evt->use_tqm_timer; 17588 17589 return QDF_STATUS_SUCCESS; 17590 } 17591 17592 /** 17593 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 17594 * status tlv 17595 * @wmi_handle: wmi handle 17596 * @param evt_buf: pointer to event buffer 17597 * @param param: Pointer to hold csa switch count status event param 17598 * 17599 * Return: QDF_STATUS_SUCCESS for success or error code 17600 */ 17601 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 17602 wmi_unified_t wmi_handle, 17603 void *evt_buf, 17604 struct pdev_csa_switch_count_status *param) 17605 { 17606 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 17607 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 17608 17609 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 17610 evt_buf; 17611 if (!param_buf) { 17612 wmi_err("Invalid CSA status event"); 17613 return QDF_STATUS_E_INVAL; 17614 } 17615 17616 csa_status = param_buf->fixed_param; 17617 17618 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 17619 wmi_handle, 17620 csa_status->pdev_id); 17621 param->current_switch_count = csa_status->current_switch_count; 17622 param->num_vdevs = csa_status->num_vdevs; 17623 param->vdev_ids = param_buf->vdev_ids; 17624 17625 return QDF_STATUS_SUCCESS; 17626 } 17627 17628 #ifdef CONFIG_AFC_SUPPORT 17629 /** 17630 * send_afc_cmd_tlv() - Sends the AFC indication to FW 17631 * @wmi_handle: wmi handle 17632 * @pdev_id: Pdev id 17633 * @param: Pointer to hold AFC indication. 17634 * 17635 * Return: QDF_STATUS_SUCCESS for success or error code 17636 */ 17637 static 17638 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 17639 uint8_t pdev_id, 17640 struct reg_afc_resp_rx_ind_info *param) 17641 { 17642 wmi_buf_t buf; 17643 wmi_afc_cmd_fixed_param *cmd; 17644 uint32_t len; 17645 uint8_t *buf_ptr; 17646 QDF_STATUS ret; 17647 17648 len = sizeof(wmi_afc_cmd_fixed_param); 17649 buf = wmi_buf_alloc(wmi_handle, len); 17650 if (!buf) 17651 return QDF_STATUS_E_NOMEM; 17652 17653 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17654 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 17655 17656 WMITLV_SET_HDR(&cmd->tlv_header, 17657 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 17658 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 17659 17660 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17661 wmi_handle, 17662 pdev_id); 17663 cmd->cmd_type = param->cmd_type; 17664 cmd->serv_resp_format = param->serv_resp_format; 17665 17666 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 17667 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 17668 if (QDF_IS_STATUS_ERROR(ret)) { 17669 wmi_err("Failed to send WMI_AFC_CMDID"); 17670 wmi_buf_free(buf); 17671 return QDF_STATUS_E_FAILURE; 17672 } 17673 17674 return QDF_STATUS_SUCCESS; 17675 } 17676 #endif 17677 17678 /** 17679 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 17680 * @wmi_handle: wmi handle 17681 * @param: Pointer to hold TX power info 17682 * 17683 * Return: QDF_STATUS_SUCCESS for success or error code 17684 */ 17685 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 17686 uint8_t vdev_id, 17687 struct reg_tpc_power_info *param) 17688 { 17689 wmi_buf_t buf; 17690 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 17691 wmi_vdev_ch_power_info *ch_power_info; 17692 uint8_t *buf_ptr; 17693 uint16_t idx; 17694 uint32_t len; 17695 QDF_STATUS ret; 17696 17697 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 17698 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 17699 17700 buf = wmi_buf_alloc(wmi_handle, len); 17701 if (!buf) 17702 return QDF_STATUS_E_NOMEM; 17703 17704 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17705 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 17706 17707 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 17708 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 17709 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 17710 17711 tpc_power_info_param->vdev_id = vdev_id; 17712 tpc_power_info_param->psd_power = param->is_psd_power; 17713 tpc_power_info_param->eirp_power = param->eirp_power; 17714 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 17715 wmi_debug("eirp_power = %d is_psd_power = %d power_type_6ghz = %d", 17716 tpc_power_info_param->eirp_power, 17717 tpc_power_info_param->psd_power, 17718 tpc_power_info_param->power_type_6ghz); 17719 17720 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 17721 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 17722 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 17723 17724 buf_ptr += WMI_TLV_HDR_SIZE; 17725 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 17726 17727 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 17728 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 17729 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 17730 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 17731 ch_power_info[idx].chan_cfreq = 17732 param->chan_power_info[idx].chan_cfreq; 17733 ch_power_info[idx].tx_power = 17734 param->chan_power_info[idx].tx_power; 17735 wmi_debug("chan_cfreq = %d tx_power = %d", 17736 ch_power_info[idx].chan_cfreq, 17737 ch_power_info[idx].tx_power); 17738 buf_ptr += sizeof(wmi_vdev_ch_power_info); 17739 } 17740 17741 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 17742 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17743 WMI_VDEV_SET_TPC_POWER_CMDID); 17744 if (QDF_IS_STATUS_ERROR(ret)) 17745 wmi_buf_free(buf); 17746 17747 17748 return ret; 17749 } 17750 17751 /** 17752 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 17753 * @wmi_handle: wmi handle 17754 * @evt_buf: event buffer 17755 * @param: dpd status info 17756 * 17757 * Return: QDF_STATUS_SUCCESS for success or error code 17758 */ 17759 static QDF_STATUS 17760 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 17761 void *evt_buf, 17762 struct wmi_host_pdev_get_dpd_status_event *param) 17763 { 17764 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 17765 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 17766 17767 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 17768 if (!param_buf) { 17769 wmi_err("Invalid get dpd_status event"); 17770 return QDF_STATUS_E_INVAL; 17771 } 17772 17773 dpd_status = param_buf->fixed_param; 17774 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 17775 (wmi_handle, dpd_status->pdev_id); 17776 param->dpd_status = dpd_status->dpd_status; 17777 17778 return QDF_STATUS_SUCCESS; 17779 } 17780 17781 static int 17782 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 17783 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 17784 { 17785 if (status->halphy_cal_valid_bmap && valid_bit) 17786 return (status->halphy_cal_status && valid_bit); 17787 17788 return 0; 17789 } 17790 17791 static QDF_STATUS 17792 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 17793 void *evt_buf, 17794 struct wmi_host_pdev_get_halphy_cal_status_event *param) 17795 { 17796 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 17797 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 17798 17799 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 17800 if (!param_buf) { 17801 wmi_err("Invalid get halphy cal status event"); 17802 return QDF_STATUS_E_INVAL; 17803 } 17804 17805 halphy_cal_status = param_buf->fixed_param; 17806 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 17807 (wmi_handle, halphy_cal_status->pdev_id); 17808 param->halphy_cal_adc_status = 17809 convert_halphy_status(halphy_cal_status, 17810 WMI_HALPHY_CAL_ADC_BMAP); 17811 param->halphy_cal_bwfilter_status = 17812 convert_halphy_status(halphy_cal_status, 17813 WMI_HALPHY_CAL_BWFILTER_BMAP); 17814 param->halphy_cal_pdet_and_pal_status = 17815 convert_halphy_status(halphy_cal_status, 17816 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 17817 param->halphy_cal_rxdco_status = 17818 convert_halphy_status(halphy_cal_status, 17819 WMI_HALPHY_CAL_RXDCO_BMAP); 17820 param->halphy_cal_comb_txiq_rxiq_status = 17821 convert_halphy_status(halphy_cal_status, 17822 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 17823 param->halphy_cal_ibf_status = 17824 convert_halphy_status(halphy_cal_status, 17825 WMI_HALPHY_CAL_IBF_BMAP); 17826 param->halphy_cal_pa_droop_status = 17827 convert_halphy_status(halphy_cal_status, 17828 WMI_HALPHY_CAL_PA_DROOP_BMAP); 17829 param->halphy_cal_dac_status = 17830 convert_halphy_status(halphy_cal_status, 17831 WMI_HALPHY_CAL_DAC_BMAP); 17832 param->halphy_cal_ani_status = 17833 convert_halphy_status(halphy_cal_status, 17834 WMI_HALPHY_CAL_ANI_BMAP); 17835 param->halphy_cal_noise_floor_status = 17836 convert_halphy_status(halphy_cal_status, 17837 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 17838 17839 return QDF_STATUS_SUCCESS; 17840 } 17841 17842 /** 17843 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 17844 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 17845 * 17846 * Return: host_set_halphy_cal_status 17847 */ 17848 static enum wmi_host_set_halphy_cal_status 17849 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 17850 { 17851 if (fw_status == 0) 17852 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 17853 else if (fw_status == 1) 17854 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 17855 17856 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 17857 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 17858 } 17859 17860 /** 17861 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 17862 * @wmi_handle: wmi handle 17863 * @evt_buf: event buffer 17864 * @param: set halphy cal status info 17865 * 17866 * Return: QDF_STATUS_SUCCESS for success or error code 17867 */ 17868 static QDF_STATUS 17869 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 17870 void *evt_buf, 17871 struct wmi_host_pdev_set_halphy_cal_event *param) 17872 { 17873 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 17874 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 17875 17876 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 17877 if (!param_buf) { 17878 wmi_err("Invalid set halphy_status event"); 17879 return QDF_STATUS_E_INVAL; 17880 } 17881 17882 set_halphy_status = param_buf->fixed_param; 17883 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 17884 (wmi_handle, set_halphy_status->pdev_id); 17885 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 17886 17887 return QDF_STATUS_SUCCESS; 17888 } 17889 17890 /** 17891 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 17892 * @wmi_handle: wmi handle 17893 * @evt_buf: pointer to event buffer 17894 * @len: length of the event buffer 17895 * @param: Pointer to hold install key complete event param 17896 * 17897 * Return: QDF_STATUS_SUCCESS for success or error code 17898 */ 17899 static QDF_STATUS 17900 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 17901 void *evt_buf, uint32_t len, 17902 struct wmi_install_key_comp_event *param) 17903 { 17904 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 17905 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 17906 17907 if (len < sizeof(*param_buf)) { 17908 wmi_err("invalid event buf len %d", len); 17909 return QDF_STATUS_E_INVAL; 17910 } 17911 17912 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17913 if (!param_buf) { 17914 wmi_err("received null buf from target"); 17915 return QDF_STATUS_E_INVAL; 17916 } 17917 17918 key_fp = param_buf->fixed_param; 17919 if (!key_fp) { 17920 wmi_err("received null event data from target"); 17921 return QDF_STATUS_E_INVAL; 17922 } 17923 17924 param->vdev_id = key_fp->vdev_id; 17925 param->key_ix = key_fp->key_ix; 17926 param->key_flags = key_fp->key_flags; 17927 param->status = key_fp->status; 17928 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 17929 param->peer_macaddr); 17930 17931 return QDF_STATUS_SUCCESS; 17932 } 17933 17934 static QDF_STATUS 17935 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 17936 struct wmi_host_send_set_halphy_cal_info *param) 17937 { 17938 wmi_buf_t buf; 17939 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 17940 QDF_STATUS ret; 17941 uint32_t len; 17942 17943 len = sizeof(*cmd); 17944 17945 buf = wmi_buf_alloc(wmi_handle, len); 17946 if (!buf) 17947 return QDF_STATUS_E_FAILURE; 17948 17949 cmd = (void *)wmi_buf_data(buf); 17950 17951 WMITLV_SET_HDR(&cmd->tlv_header, 17952 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 17953 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 17954 17955 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 17956 param->pdev_id); 17957 cmd->online_halphy_cals_bmap = param->value; 17958 cmd->home_scan_channel = param->chan_sel; 17959 17960 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17961 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 17962 if (QDF_IS_STATUS_ERROR(ret)) { 17963 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 17964 wmi_buf_free(buf); 17965 } 17966 17967 return ret; 17968 } 17969 17970 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 17971 /** 17972 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 17973 * @wmi: wmi handle 17974 * @params: set MAC address command params 17975 * 17976 * Return: QDF_STATUS_SUCCESS for success or error code 17977 */ 17978 static QDF_STATUS 17979 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 17980 struct set_mac_addr_params *params) 17981 { 17982 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 17983 wmi_buf_t buf; 17984 int32_t len = sizeof(*cmd); 17985 17986 buf = wmi_buf_alloc(wmi, len); 17987 if (!buf) 17988 return QDF_STATUS_E_NOMEM; 17989 17990 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 17991 WMITLV_SET_HDR( 17992 &cmd->tlv_header, 17993 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 17994 WMITLV_GET_STRUCT_TLVLEN 17995 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 17996 cmd->vdev_id = params->vdev_id; 17997 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 17998 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 17999 18000 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 18001 QDF_MAC_ADDR_FMT, cmd->vdev_id, 18002 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 18003 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 18004 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 18005 if (wmi_unified_cmd_send(wmi, buf, len, 18006 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 18007 wmi_buf_free(buf); 18008 return QDF_STATUS_E_FAILURE; 18009 } 18010 18011 return QDF_STATUS_SUCCESS; 18012 } 18013 18014 /** 18015 * extract_update_mac_address_event_tlv() - extract update MAC address event 18016 * @wmi_handle: WMI handle 18017 * @evt_buf: event buffer 18018 * @vdev_id: VDEV ID 18019 * @status: FW status of the set MAC address operation 18020 * 18021 * Return: QDF_STATUS 18022 */ 18023 static QDF_STATUS extract_update_mac_address_event_tlv( 18024 wmi_unified_t wmi_handle, void *evt_buf, 18025 uint8_t *vdev_id, uint8_t *status) 18026 { 18027 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 18028 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 18029 18030 param_buf = 18031 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 18032 18033 event = param_buf->fixed_param; 18034 18035 *vdev_id = event->vdev_id; 18036 *status = event->status; 18037 18038 return QDF_STATUS_SUCCESS; 18039 } 18040 #endif 18041 18042 #ifdef WLAN_FEATURE_11BE_MLO 18043 /** 18044 * extract_quiet_offload_event_tlv() - extract quiet offload event 18045 * @wmi_handle: WMI handle 18046 * @evt_buf: event buffer 18047 * @mld_mac: mld mac address 18048 * @link_mac: link mac address 18049 * @link_id: link id 18050 * @quiet_status: quiet is started or stopped 18051 * 18052 * Return: QDF_STATUS 18053 */ 18054 static QDF_STATUS extract_quiet_offload_event_tlv( 18055 wmi_unified_t wmi_handle, void *evt_buf, 18056 struct vdev_sta_quiet_event *quiet_event) 18057 { 18058 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 18059 wmi_quiet_event_fixed_param *event; 18060 18061 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 18062 18063 event = param_buf->fixed_param; 18064 18065 if (!(event->mld_mac_address_present && event->linkid_present) && 18066 !event->link_mac_address_present) { 18067 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 18068 event->mld_mac_address_present, 18069 event->linkid_present, 18070 event->link_mac_address_present); 18071 return QDF_STATUS_E_INVAL; 18072 } 18073 18074 if (event->mld_mac_address_present) 18075 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 18076 quiet_event->mld_mac.bytes); 18077 if (event->link_mac_address_present) 18078 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 18079 quiet_event->link_mac.bytes); 18080 if (event->linkid_present) 18081 quiet_event->link_id = event->linkid; 18082 quiet_event->quiet_status = (event->quiet_status == 18083 WMI_QUIET_EVENT_START); 18084 18085 return QDF_STATUS_SUCCESS; 18086 } 18087 #endif 18088 18089 /** 18090 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 18091 * @wmi_handle: wmi handle 18092 * @params: RxFilter params 18093 * 18094 * Return: QDF_STATUS_SUCCESS for success or error code 18095 */ 18096 static QDF_STATUS 18097 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 18098 struct vdev_pn_mgmt_rxfilter_params *params) 18099 { 18100 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 18101 wmi_buf_t buf; 18102 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 18103 18104 if (!is_service_enabled_tlv(wmi_handle, 18105 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 18106 wmi_err("Rx PN Replay Check not supported by target"); 18107 return QDF_STATUS_E_NOSUPPORT; 18108 } 18109 18110 buf = wmi_buf_alloc(wmi_handle, len); 18111 if (!buf) { 18112 wmi_err("wmi buf alloc failed"); 18113 return QDF_STATUS_E_NOMEM; 18114 } 18115 18116 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 18117 WMITLV_SET_HDR( 18118 &cmd->tlv_header, 18119 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 18120 WMITLV_GET_STRUCT_TLVLEN 18121 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 18122 18123 cmd->vdev_id = params->vdev_id; 18124 cmd->pn_rx_filter = params->pn_rxfilter; 18125 18126 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18127 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 18128 wmi_err("Failed to send WMI command"); 18129 wmi_buf_free(buf); 18130 return QDF_STATUS_E_FAILURE; 18131 } 18132 18133 return QDF_STATUS_SUCCESS; 18134 } 18135 18136 static QDF_STATUS 18137 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18138 uint8_t *pdev_id, uint8_t *software_image, 18139 uint8_t *chip_info, 18140 uint32_t *pktlog_json_version) 18141 { 18142 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 18143 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 18144 18145 param_buf = 18146 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 18147 18148 event = param_buf->fixed_param; 18149 18150 if ((event->software_image[0] == '\0') || 18151 (event->chip_info[0] == '\0')) { 18152 *pdev_id = event->pdev_id; 18153 return QDF_STATUS_E_INVAL; 18154 } 18155 18156 qdf_mem_copy(software_image, event->software_image, 40); 18157 qdf_mem_copy(chip_info, event->chip_info, 40); 18158 *pktlog_json_version = event->pktlog_defs_json_version; 18159 *pdev_id = event->pdev_id; 18160 return QDF_STATUS_SUCCESS; 18161 } 18162 18163 /** 18164 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 18165 * @wmi_handle: wmi handle 18166 * @evt_buf: pointer to event buffer 18167 * @pdev stats: Pointer to hold pdev telemetry stats 18168 * 18169 * Return: QDF_STATUS_SUCCESS for success or error code 18170 */ 18171 static QDF_STATUS 18172 extract_pdev_telemetry_stats_tlv( 18173 wmi_unified_t wmi_handle, void *evt_buf, 18174 struct wmi_host_pdev_telemetry_stats *pdev_stats) 18175 { 18176 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 18177 wmi_pdev_telemetry_stats *ev; 18178 18179 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 18180 18181 if (param_buf->pdev_telemetry_stats) { 18182 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 18183 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 18184 ev->avg_chan_lat_per_ac, 18185 sizeof(ev->avg_chan_lat_per_ac)); 18186 pdev_stats->estimated_air_time_per_ac = 18187 ev->estimated_air_time_per_ac; 18188 } 18189 18190 return QDF_STATUS_SUCCESS; 18191 } 18192 18193 struct wmi_ops tlv_ops = { 18194 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 18195 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 18196 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 18197 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 18198 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 18199 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 18200 .send_peer_param_cmd = send_peer_param_cmd_tlv, 18201 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 18202 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 18203 .send_peer_create_cmd = send_peer_create_cmd_tlv, 18204 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 18205 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 18206 .send_peer_rx_reorder_queue_setup_cmd = 18207 send_peer_rx_reorder_queue_setup_cmd_tlv, 18208 .send_peer_rx_reorder_queue_remove_cmd = 18209 send_peer_rx_reorder_queue_remove_cmd_tlv, 18210 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 18211 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 18212 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 18213 .send_suspend_cmd = send_suspend_cmd_tlv, 18214 .send_resume_cmd = send_resume_cmd_tlv, 18215 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 18216 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 18217 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 18218 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 18219 .send_dbglog_cmd = send_dbglog_cmd_tlv, 18220 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 18221 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 18222 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 18223 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 18224 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 18225 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 18226 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 18227 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 18228 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 18229 .send_scan_start_cmd = send_scan_start_cmd_tlv, 18230 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 18231 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 18232 .send_mgmt_cmd = send_mgmt_cmd_tlv, 18233 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 18234 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 18235 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 18236 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 18237 .send_set_sta_uapsd_auto_trig_cmd = 18238 send_set_sta_uapsd_auto_trig_cmd_tlv, 18239 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 18240 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 18241 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 18242 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 18243 .send_lro_config_cmd = send_lro_config_cmd_tlv, 18244 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 18245 .send_probe_rsp_tmpl_send_cmd = 18246 send_probe_rsp_tmpl_send_cmd_tlv, 18247 .send_p2p_go_set_beacon_ie_cmd = 18248 send_p2p_go_set_beacon_ie_cmd_tlv, 18249 .send_setup_install_key_cmd = 18250 send_setup_install_key_cmd_tlv, 18251 .send_scan_probe_setoui_cmd = 18252 send_scan_probe_setoui_cmd_tlv, 18253 #ifdef IPA_OFFLOAD 18254 .send_ipa_offload_control_cmd = 18255 send_ipa_offload_control_cmd_tlv, 18256 #endif 18257 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 18258 .send_pno_start_cmd = send_pno_start_cmd_tlv, 18259 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 18260 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 18261 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 18262 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 18263 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 18264 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 18265 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 18266 .send_unified_ll_stats_get_sta_cmd = 18267 send_unified_ll_stats_get_sta_cmd_tlv, 18268 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 18269 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 18270 .send_congestion_cmd = send_congestion_cmd_tlv, 18271 .send_snr_request_cmd = send_snr_request_cmd_tlv, 18272 .send_snr_cmd = send_snr_cmd_tlv, 18273 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 18274 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 18275 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 18276 #endif 18277 #ifdef WLAN_SUPPORT_GREEN_AP 18278 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 18279 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 18280 .extract_green_ap_egap_status_info = 18281 extract_green_ap_egap_status_info_tlv, 18282 #endif 18283 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 18284 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 18285 #ifdef FEATURE_OEM_DATA 18286 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 18287 #endif 18288 #ifdef WLAN_FEATURE_CIF_CFR 18289 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 18290 #endif 18291 .send_dfs_phyerr_filter_offload_en_cmd = 18292 send_dfs_phyerr_filter_offload_en_cmd_tlv, 18293 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 18294 .send_process_dhcpserver_offload_cmd = 18295 send_process_dhcpserver_offload_cmd_tlv, 18296 .send_pdev_set_regdomain_cmd = 18297 send_pdev_set_regdomain_cmd_tlv, 18298 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 18299 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 18300 .save_fw_version_cmd = save_fw_version_cmd_tlv, 18301 .check_and_update_fw_version = 18302 check_and_update_fw_version_cmd_tlv, 18303 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 18304 .send_enable_specific_fw_logs_cmd = 18305 send_enable_specific_fw_logs_cmd_tlv, 18306 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 18307 .send_unit_test_cmd = send_unit_test_cmd_tlv, 18308 #ifdef FEATURE_WLAN_APF 18309 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 18310 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 18311 .send_apf_write_work_memory_cmd = 18312 wmi_send_apf_write_work_memory_cmd_tlv, 18313 .send_apf_read_work_memory_cmd = 18314 wmi_send_apf_read_work_memory_cmd_tlv, 18315 .extract_apf_read_memory_resp_event = 18316 wmi_extract_apf_read_memory_resp_event_tlv, 18317 #endif /* FEATURE_WLAN_APF */ 18318 .init_cmd_send = init_cmd_send_tlv, 18319 .send_vdev_set_custom_aggr_size_cmd = 18320 send_vdev_set_custom_aggr_size_cmd_tlv, 18321 .send_vdev_set_qdepth_thresh_cmd = 18322 send_vdev_set_qdepth_thresh_cmd_tlv, 18323 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 18324 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 18325 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 18326 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 18327 .send_periodic_chan_stats_config_cmd = 18328 send_periodic_chan_stats_config_cmd_tlv, 18329 #ifdef WLAN_IOT_SIM_SUPPORT 18330 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 18331 #endif 18332 .send_vdev_spectral_configure_cmd = 18333 send_vdev_spectral_configure_cmd_tlv, 18334 .send_vdev_spectral_enable_cmd = 18335 send_vdev_spectral_enable_cmd_tlv, 18336 #ifdef WLAN_CONV_SPECTRAL_ENABLE 18337 .extract_pdev_sscan_fw_cmd_fixed_param = 18338 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 18339 .extract_pdev_sscan_fft_bin_index = 18340 extract_pdev_sscan_fft_bin_index_tlv, 18341 .extract_pdev_spectral_session_chan_info = 18342 extract_pdev_spectral_session_chan_info_tlv, 18343 .extract_pdev_spectral_session_detector_info = 18344 extract_pdev_spectral_session_detector_info_tlv, 18345 .extract_spectral_caps_fixed_param = 18346 extract_spectral_caps_fixed_param_tlv, 18347 .extract_spectral_scan_bw_caps = 18348 extract_spectral_scan_bw_caps_tlv, 18349 .extract_spectral_fft_size_caps = 18350 extract_spectral_fft_size_caps_tlv, 18351 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 18352 .send_thermal_mitigation_param_cmd = 18353 send_thermal_mitigation_param_cmd_tlv, 18354 .send_process_update_edca_param_cmd = 18355 send_process_update_edca_param_cmd_tlv, 18356 .send_bss_color_change_enable_cmd = 18357 send_bss_color_change_enable_cmd_tlv, 18358 .send_coex_config_cmd = send_coex_config_cmd_tlv, 18359 .send_set_country_cmd = send_set_country_cmd_tlv, 18360 .send_addba_send_cmd = send_addba_send_cmd_tlv, 18361 .send_delba_send_cmd = send_delba_send_cmd_tlv, 18362 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 18363 .get_target_cap_from_service_ready = extract_service_ready_tlv, 18364 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 18365 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 18366 .extract_host_mem_req = extract_host_mem_req_tlv, 18367 .save_service_bitmap = save_service_bitmap_tlv, 18368 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 18369 .is_service_enabled = is_service_enabled_tlv, 18370 .save_fw_version = save_fw_version_in_service_ready_tlv, 18371 .ready_extract_init_status = ready_extract_init_status_tlv, 18372 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 18373 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 18374 .extract_ready_event_params = extract_ready_event_params_tlv, 18375 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 18376 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 18377 .extract_frame_pn_params = extract_frame_pn_params_tlv, 18378 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 18379 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 18380 #ifdef FEATURE_WLAN_SCAN_PNO 18381 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 18382 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 18383 #endif 18384 .extract_unit_test = extract_unit_test_tlv, 18385 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 18386 .extract_bcn_stats = extract_bcn_stats_tlv, 18387 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 18388 .extract_chan_stats = extract_chan_stats_tlv, 18389 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 18390 .extract_profile_ctx = extract_profile_ctx_tlv, 18391 .extract_profile_data = extract_profile_data_tlv, 18392 .send_fw_test_cmd = send_fw_test_cmd_tlv, 18393 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 18394 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 18395 .extract_service_ready_ext = extract_service_ready_ext_tlv, 18396 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 18397 .extract_dbs_or_sbs_service_ready_ext2 = 18398 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 18399 .extract_hw_mode_cap_service_ready_ext = 18400 extract_hw_mode_cap_service_ready_ext_tlv, 18401 .extract_mac_phy_cap_service_ready_ext = 18402 extract_mac_phy_cap_service_ready_ext_tlv, 18403 .extract_mac_phy_cap_service_ready_ext2 = 18404 extract_mac_phy_cap_service_ready_ext2_tlv, 18405 .extract_reg_cap_service_ready_ext = 18406 extract_reg_cap_service_ready_ext_tlv, 18407 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 18408 .extract_dbr_ring_cap_service_ready_ext = 18409 extract_dbr_ring_cap_service_ready_ext_tlv, 18410 .extract_dbr_ring_cap_service_ready_ext2 = 18411 extract_dbr_ring_cap_service_ready_ext2_tlv, 18412 .extract_scan_radio_cap_service_ready_ext2 = 18413 extract_scan_radio_cap_service_ready_ext2_tlv, 18414 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 18415 .extract_sar_cap_service_ready_ext = 18416 extract_sar_cap_service_ready_ext_tlv, 18417 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 18418 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 18419 .extract_fips_event_data = extract_fips_event_data_tlv, 18420 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 18421 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 18422 #endif 18423 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18424 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 18425 #endif 18426 #ifdef WLAN_FEATURE_DISA 18427 .extract_encrypt_decrypt_resp_event = 18428 extract_encrypt_decrypt_resp_event_tlv, 18429 #endif 18430 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 18431 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 18432 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 18433 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 18434 #endif 18435 .extract_get_pn_data = extract_get_pn_data_tlv, 18436 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 18437 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 18438 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 18439 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 18440 #ifdef WLAN_FEATURE_DISA 18441 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 18442 #endif 18443 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 18444 .send_wlan_profile_hist_intvl_cmd = 18445 send_wlan_profile_hist_intvl_cmd_tlv, 18446 .is_management_record = is_management_record_tlv, 18447 .is_diag_event = is_diag_event_tlv, 18448 #ifdef WLAN_FEATURE_ACTION_OUI 18449 .send_action_oui_cmd = send_action_oui_cmd_tlv, 18450 #endif 18451 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 18452 #ifdef QCA_SUPPORT_AGILE_DFS 18453 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 18454 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 18455 #endif 18456 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 18457 .extract_reg_chan_list_update_event = 18458 extract_reg_chan_list_update_event_tlv, 18459 #ifdef CONFIG_BAND_6GHZ 18460 .extract_reg_chan_list_ext_update_event = 18461 extract_reg_chan_list_ext_update_event_tlv, 18462 #ifdef CONFIG_AFC_SUPPORT 18463 .extract_afc_event = extract_afc_event_tlv, 18464 #endif 18465 #endif 18466 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 18467 .extract_num_rf_characterization_entries = 18468 extract_num_rf_characterization_entries_tlv, 18469 .extract_rf_characterization_entries = 18470 extract_rf_characterization_entries_tlv, 18471 #endif 18472 .extract_chainmask_tables = 18473 extract_chainmask_tables_tlv, 18474 .extract_thermal_stats = extract_thermal_stats_tlv, 18475 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 18476 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 18477 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 18478 #ifdef DFS_COMPONENT_ENABLE 18479 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 18480 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 18481 .extract_dfs_radar_detection_event = 18482 extract_dfs_radar_detection_event_tlv, 18483 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 18484 #endif 18485 .convert_pdev_id_host_to_target = 18486 convert_host_pdev_id_to_target_pdev_id_legacy, 18487 .convert_pdev_id_target_to_host = 18488 convert_target_pdev_id_to_host_pdev_id_legacy, 18489 18490 .convert_host_pdev_id_to_target = 18491 convert_host_pdev_id_to_target_pdev_id, 18492 .convert_target_pdev_id_to_host = 18493 convert_target_pdev_id_to_host_pdev_id, 18494 18495 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 18496 18497 .convert_phy_id_host_to_target = 18498 convert_host_phy_id_to_target_phy_id_legacy, 18499 .convert_phy_id_target_to_host = 18500 convert_target_phy_id_to_host_phy_id_legacy, 18501 18502 .convert_host_phy_id_to_target = 18503 convert_host_phy_id_to_target_phy_id, 18504 .convert_target_phy_id_to_host = 18505 convert_target_phy_id_to_host_phy_id, 18506 18507 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 18508 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 18509 .extract_reg_11d_new_country_event = 18510 extract_reg_11d_new_country_event_tlv, 18511 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 18512 .extract_reg_ch_avoid_event = 18513 extract_reg_ch_avoid_event_tlv, 18514 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 18515 .extract_obss_detection_info = extract_obss_detection_info_tlv, 18516 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 18517 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 18518 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 18519 .wmi_check_command_params = wmitlv_check_command_tlv_params, 18520 .extract_comb_phyerr = extract_comb_phyerr_tlv, 18521 .extract_single_phyerr = extract_single_phyerr_tlv, 18522 #ifdef QCA_SUPPORT_CP_STATS 18523 .extract_cca_stats = extract_cca_stats_tlv, 18524 #endif 18525 .extract_esp_estimation_ev_param = 18526 extract_esp_estimation_ev_param_tlv, 18527 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 18528 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 18529 #ifdef OBSS_PD 18530 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 18531 .send_obss_spatial_reuse_set_def_thresh = 18532 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 18533 .send_self_srg_bss_color_bitmap_set = 18534 send_self_srg_bss_color_bitmap_set_cmd_tlv, 18535 .send_self_srg_partial_bssid_bitmap_set = 18536 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 18537 .send_self_srg_obss_color_enable_bitmap = 18538 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 18539 .send_self_srg_obss_bssid_enable_bitmap = 18540 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 18541 .send_self_non_srg_obss_color_enable_bitmap = 18542 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 18543 .send_self_non_srg_obss_bssid_enable_bitmap = 18544 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 18545 #endif 18546 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 18547 .extract_ctl_failsafe_check_ev_param = 18548 extract_ctl_failsafe_check_ev_param_tlv, 18549 #ifdef WIFI_POS_CONVERGED 18550 .extract_oem_response_param = extract_oem_response_param_tlv, 18551 #endif /* WIFI_POS_CONVERGED */ 18552 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18553 .extract_pasn_peer_create_req_event = 18554 extract_pasn_peer_create_req_event_tlv, 18555 .extract_pasn_peer_delete_req_event = 18556 extract_pasn_peer_delete_req_event_tlv, 18557 .send_rtt_pasn_auth_status_cmd = 18558 send_rtt_pasn_auth_status_cmd_tlv, 18559 .send_rtt_pasn_deauth_cmd = 18560 send_rtt_pasn_deauth_cmd_tlv, 18561 #endif 18562 #ifdef WLAN_MWS_INFO_DEBUGFS 18563 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 18564 #endif 18565 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 18566 #ifdef FEATURE_ANI_LEVEL_REQUEST 18567 .send_ani_level_cmd = send_ani_level_cmd_tlv, 18568 .extract_ani_level = extract_ani_level_tlv, 18569 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 18570 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 18571 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 18572 .extract_roam_result_stats = extract_roam_result_stats_tlv, 18573 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 18574 #ifdef WLAN_FEATURE_PKT_CAPTURE 18575 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 18576 #endif 18577 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 18578 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 18579 #endif 18580 18581 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 18582 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 18583 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 18584 .extract_time_sync_ftm_start_stop_event = 18585 extract_time_sync_ftm_start_stop_event_tlv, 18586 .extract_time_sync_ftm_offset_event = 18587 extract_time_sync_ftm_offset_event_tlv, 18588 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 18589 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 18590 .send_injector_config_cmd = send_injector_config_cmd_tlv, 18591 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 18592 #ifdef FEATURE_MEC_OFFLOAD 18593 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 18594 #endif 18595 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 18596 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 18597 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 18598 .extract_cp_stats_more_pending = 18599 extract_cp_stats_more_pending_tlv, 18600 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 18601 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 18602 .extract_pdev_csa_switch_count_status = 18603 extract_pdev_csa_switch_count_status_tlv, 18604 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 18605 #ifdef CONFIG_AFC_SUPPORT 18606 .send_afc_cmd = send_afc_cmd_tlv, 18607 #endif 18608 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 18609 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 18610 .send_vdev_set_ltf_key_seed_cmd = 18611 send_vdev_set_ltf_key_seed_cmd_tlv, 18612 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 18613 .send_set_halphy_cal = send_set_halphy_cal_tlv, 18614 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 18615 #ifdef WLAN_MGMT_RX_REO_SUPPORT 18616 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 18617 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 18618 .send_mgmt_rx_reo_filter_config_cmd = 18619 send_mgmt_rx_reo_filter_config_cmd_tlv, 18620 #endif 18621 18622 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 18623 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 18624 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 18625 18626 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 18627 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 18628 .extract_update_mac_address_event = 18629 extract_update_mac_address_event_tlv, 18630 #endif 18631 18632 #ifdef WLAN_FEATURE_11BE_MLO 18633 .extract_quiet_offload_event = 18634 extract_quiet_offload_event_tlv, 18635 #endif 18636 18637 #ifdef WLAN_SUPPORT_PPEDS 18638 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 18639 #endif /* WLAN_SUPPORT_PPEDS */ 18640 18641 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 18642 .extract_pktlog_decode_info_event = 18643 extract_pktlog_decode_info_event_tlv, 18644 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 18645 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 18646 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 18647 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 18648 #endif 18649 }; 18650 18651 #ifdef WLAN_FEATURE_11BE_MLO 18652 static void populate_tlv_events_id_mlo(uint32_t *event_ids) 18653 { 18654 event_ids[wmi_mlo_setup_complete_event_id] = 18655 WMI_MLO_SETUP_COMPLETE_EVENTID; 18656 event_ids[wmi_mlo_teardown_complete_event_id] = 18657 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 18658 event_ids[wmi_mlo_link_set_active_resp_eventid] = 18659 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 18660 event_ids[wmi_vdev_quiet_offload_eventid] = 18661 WMI_QUIET_HANDLING_EVENTID; 18662 } 18663 #else /* WLAN_FEATURE_11BE_MLO */ 18664 static inline void populate_tlv_events_id_mlo(uint32_t *event_ids) 18665 { 18666 } 18667 #endif /* WLAN_FEATURE_11BE_MLO */ 18668 18669 /** 18670 * populate_tlv_event_id() - populates wmi event ids 18671 * 18672 * @param event_ids: Pointer to hold event ids 18673 * Return: None 18674 */ 18675 static void populate_tlv_events_id(uint32_t *event_ids) 18676 { 18677 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 18678 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 18679 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 18680 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 18681 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 18682 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 18683 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 18684 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 18685 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 18686 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 18687 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 18688 event_ids[wmi_service_ready_ext_event_id] = 18689 WMI_SERVICE_READY_EXT_EVENTID; 18690 event_ids[wmi_service_ready_ext2_event_id] = 18691 WMI_SERVICE_READY_EXT2_EVENTID; 18692 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 18693 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 18694 event_ids[wmi_vdev_install_key_complete_event_id] = 18695 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 18696 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 18697 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 18698 18699 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 18700 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 18701 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 18702 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 18703 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 18704 event_ids[wmi_peer_estimated_linkspeed_event_id] = 18705 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 18706 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 18707 event_ids[wmi_peer_create_conf_event_id] = 18708 WMI_PEER_CREATE_CONF_EVENTID; 18709 event_ids[wmi_peer_delete_response_event_id] = 18710 WMI_PEER_DELETE_RESP_EVENTID; 18711 event_ids[wmi_peer_delete_all_response_event_id] = 18712 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 18713 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 18714 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 18715 event_ids[wmi_tbttoffset_update_event_id] = 18716 WMI_TBTTOFFSET_UPDATE_EVENTID; 18717 event_ids[wmi_ext_tbttoffset_update_event_id] = 18718 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 18719 event_ids[wmi_offload_bcn_tx_status_event_id] = 18720 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 18721 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 18722 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 18723 event_ids[wmi_mgmt_tx_completion_event_id] = 18724 WMI_MGMT_TX_COMPLETION_EVENTID; 18725 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 18726 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 18727 event_ids[wmi_tx_delba_complete_event_id] = 18728 WMI_TX_DELBA_COMPLETE_EVENTID; 18729 event_ids[wmi_tx_addba_complete_event_id] = 18730 WMI_TX_ADDBA_COMPLETE_EVENTID; 18731 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 18732 18733 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 18734 18735 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 18736 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 18737 18738 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 18739 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 18740 18741 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 18742 18743 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 18744 event_ids[wmi_p2p_lo_stop_event_id] = 18745 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 18746 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 18747 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 18748 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 18749 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 18750 event_ids[wmi_d0_wow_disable_ack_event_id] = 18751 WMI_D0_WOW_DISABLE_ACK_EVENTID; 18752 event_ids[wmi_wow_initial_wakeup_event_id] = 18753 WMI_WOW_INITIAL_WAKEUP_EVENTID; 18754 18755 event_ids[wmi_rtt_meas_report_event_id] = 18756 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 18757 event_ids[wmi_tsf_meas_report_event_id] = 18758 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 18759 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 18760 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 18761 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 18762 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 18763 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 18764 event_ids[wmi_diag_event_id_log_supported_event_id] = 18765 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 18766 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 18767 event_ids[wmi_nlo_scan_complete_event_id] = 18768 WMI_NLO_SCAN_COMPLETE_EVENTID; 18769 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 18770 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 18771 18772 event_ids[wmi_gtk_offload_status_event_id] = 18773 WMI_GTK_OFFLOAD_STATUS_EVENTID; 18774 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 18775 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 18776 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 18777 18778 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 18779 18780 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 18781 18782 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 18783 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 18784 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 18785 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 18786 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 18787 event_ids[wmi_wlan_profile_data_event_id] = 18788 WMI_WLAN_PROFILE_DATA_EVENTID; 18789 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 18790 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 18791 event_ids[wmi_vdev_get_keepalive_event_id] = 18792 WMI_VDEV_GET_KEEPALIVE_EVENTID; 18793 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 18794 18795 event_ids[wmi_diag_container_event_id] = 18796 WMI_DIAG_DATA_CONTAINER_EVENTID; 18797 18798 event_ids[wmi_host_auto_shutdown_event_id] = 18799 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 18800 18801 event_ids[wmi_update_whal_mib_stats_event_id] = 18802 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 18803 18804 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 18805 event_ids[wmi_update_vdev_rate_stats_event_id] = 18806 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 18807 18808 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 18809 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 18810 18811 /** Set OCB Sched Response, deprecated */ 18812 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 18813 18814 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 18815 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 18816 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 18817 18818 /* GPIO Event */ 18819 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 18820 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 18821 18822 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 18823 event_ids[wmi_rfkill_state_change_event_id] = 18824 WMI_RFKILL_STATE_CHANGE_EVENTID; 18825 18826 /* TDLS Event */ 18827 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 18828 18829 event_ids[wmi_batch_scan_enabled_event_id] = 18830 WMI_BATCH_SCAN_ENABLED_EVENTID; 18831 event_ids[wmi_batch_scan_result_event_id] = 18832 WMI_BATCH_SCAN_RESULT_EVENTID; 18833 /* OEM Event */ 18834 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 18835 event_ids[wmi_oem_meas_report_event_id] = 18836 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 18837 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 18838 18839 /* NAN Event */ 18840 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 18841 18842 /* LPI Event */ 18843 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 18844 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 18845 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 18846 18847 /* ExtScan events */ 18848 event_ids[wmi_extscan_start_stop_event_id] = 18849 WMI_EXTSCAN_START_STOP_EVENTID; 18850 event_ids[wmi_extscan_operation_event_id] = 18851 WMI_EXTSCAN_OPERATION_EVENTID; 18852 event_ids[wmi_extscan_table_usage_event_id] = 18853 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 18854 event_ids[wmi_extscan_cached_results_event_id] = 18855 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 18856 event_ids[wmi_extscan_wlan_change_results_event_id] = 18857 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 18858 event_ids[wmi_extscan_hotlist_match_event_id] = 18859 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 18860 event_ids[wmi_extscan_capabilities_event_id] = 18861 WMI_EXTSCAN_CAPABILITIES_EVENTID; 18862 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 18863 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 18864 18865 /* mDNS offload events */ 18866 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 18867 18868 /* SAP Authentication offload events */ 18869 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 18870 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 18871 18872 /** Out-of-context-of-bss (OCB) events */ 18873 event_ids[wmi_ocb_set_config_resp_event_id] = 18874 WMI_OCB_SET_CONFIG_RESP_EVENTID; 18875 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 18876 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 18877 event_ids[wmi_dcc_get_stats_resp_event_id] = 18878 WMI_DCC_GET_STATS_RESP_EVENTID; 18879 event_ids[wmi_dcc_update_ndl_resp_event_id] = 18880 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 18881 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 18882 /* System-On-Chip events */ 18883 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 18884 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 18885 event_ids[wmi_soc_hw_mode_transition_event_id] = 18886 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 18887 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 18888 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 18889 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 18890 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 18891 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 18892 #endif 18893 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 18894 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 18895 event_ids[wmi_vdev_ocac_complete_event_id] = 18896 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 18897 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 18898 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 18899 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 18900 #ifdef CONFIG_AFC_SUPPORT 18901 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 18902 #endif 18903 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 18904 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 18905 event_ids[wmi_peer_sta_ps_statechg_event_id] = 18906 WMI_PEER_STA_PS_STATECHG_EVENTID; 18907 event_ids[wmi_pdev_channel_hopping_event_id] = 18908 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 18909 event_ids[wmi_offchan_data_tx_completion_event] = 18910 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 18911 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 18912 event_ids[wmi_dfs_radar_detection_event_id] = 18913 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 18914 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 18915 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 18916 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 18917 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 18918 event_ids[wmi_service_available_event_id] = 18919 WMI_SERVICE_AVAILABLE_EVENTID; 18920 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 18921 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 18922 /* NDP events */ 18923 event_ids[wmi_ndp_initiator_rsp_event_id] = 18924 WMI_NDP_INITIATOR_RSP_EVENTID; 18925 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 18926 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 18927 event_ids[wmi_ndp_responder_rsp_event_id] = 18928 WMI_NDP_RESPONDER_RSP_EVENTID; 18929 event_ids[wmi_ndp_end_indication_event_id] = 18930 WMI_NDP_END_INDICATION_EVENTID; 18931 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 18932 event_ids[wmi_ndl_schedule_update_event_id] = 18933 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 18934 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 18935 18936 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 18937 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 18938 event_ids[wmi_pdev_chip_power_stats_event_id] = 18939 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 18940 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 18941 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 18942 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 18943 event_ids[wmi_apf_capability_info_event_id] = 18944 WMI_BPF_CAPABILIY_INFO_EVENTID; 18945 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 18946 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 18947 event_ids[wmi_report_rx_aggr_failure_event_id] = 18948 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 18949 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 18950 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 18951 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 18952 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 18953 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 18954 event_ids[wmi_pdev_hw_mode_transition_event_id] = 18955 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 18956 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 18957 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 18958 event_ids[wmi_coex_bt_activity_event_id] = 18959 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 18960 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 18961 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 18962 event_ids[wmi_radio_tx_power_level_stats_event_id] = 18963 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 18964 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 18965 event_ids[wmi_dma_buf_release_event_id] = 18966 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 18967 event_ids[wmi_sap_obss_detection_report_event_id] = 18968 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 18969 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 18970 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 18971 event_ids[wmi_obss_color_collision_report_event_id] = 18972 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 18973 event_ids[wmi_pdev_div_rssi_antid_event_id] = 18974 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 18975 #ifdef WLAN_SUPPORT_TWT 18976 event_ids[wmi_twt_enable_complete_event_id] = 18977 WMI_TWT_ENABLE_COMPLETE_EVENTID; 18978 event_ids[wmi_twt_disable_complete_event_id] = 18979 WMI_TWT_DISABLE_COMPLETE_EVENTID; 18980 event_ids[wmi_twt_add_dialog_complete_event_id] = 18981 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 18982 event_ids[wmi_twt_del_dialog_complete_event_id] = 18983 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 18984 event_ids[wmi_twt_pause_dialog_complete_event_id] = 18985 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 18986 event_ids[wmi_twt_resume_dialog_complete_event_id] = 18987 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 18988 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 18989 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 18990 event_ids[wmi_twt_session_stats_event_id] = 18991 WMI_TWT_SESSION_STATS_EVENTID; 18992 event_ids[wmi_twt_notify_event_id] = 18993 WMI_TWT_NOTIFY_EVENTID; 18994 event_ids[wmi_twt_ack_complete_event_id] = 18995 WMI_TWT_ACK_EVENTID; 18996 #endif 18997 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 18998 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 18999 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 19000 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 19001 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 19002 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 19003 event_ids[wmi_pdev_interop_issues_ap_event_id] = 19004 WMI_PDEV_RAP_INFO_EVENTID; 19005 #endif 19006 #ifdef AST_HKV1_WORKAROUND 19007 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 19008 #endif 19009 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 19010 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 19011 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 19012 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 19013 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 19014 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 19015 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 19016 event_ids[wmi_pdev_cold_boot_cal_event_id] = 19017 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 19018 #ifdef WLAN_MWS_INFO_DEBUGFS 19019 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 19020 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 19021 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 19022 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 19023 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 19024 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 19025 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 19026 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 19027 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 19028 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 19029 #endif 19030 event_ids[wmi_coex_report_antenna_isolation_event_id] = 19031 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 19032 event_ids[wmi_peer_ratecode_list_event_id] = 19033 WMI_PEER_RATECODE_LIST_EVENTID; 19034 event_ids[wmi_chan_rf_characterization_info_event_id] = 19035 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 19036 event_ids[wmi_roam_auth_offload_event_id] = 19037 WMI_ROAM_PREAUTH_START_EVENTID; 19038 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 19039 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 19040 event_ids[wmi_motion_det_base_line_host_eventid] = 19041 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 19042 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 19043 event_ids[wmi_peer_tx_pn_response_event_id] = 19044 WMI_PEER_TX_PN_RESPONSE_EVENTID; 19045 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 19046 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 19047 event_ids[wmi_mgmt_offload_data_event_id] = 19048 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 19049 event_ids[wmi_nan_dmesg_event_id] = 19050 WMI_NAN_DMESG_EVENTID; 19051 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 19052 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 19053 event_ids[wmi_roam_pmkid_request_event_id] = 19054 WMI_ROAM_PMKID_REQUEST_EVENTID; 19055 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 19056 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 19057 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 19058 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 19059 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 19060 #endif 19061 event_ids[wmi_roam_scan_chan_list_id] = 19062 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 19063 event_ids[wmi_muedca_params_config_eventid] = 19064 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 19065 event_ids[wmi_pdev_sscan_fw_param_eventid] = 19066 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 19067 event_ids[wmi_roam_cap_report_event_id] = 19068 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 19069 event_ids[wmi_vdev_bcn_latency_event_id] = 19070 WMI_VDEV_BCN_LATENCY_EVENTID; 19071 event_ids[wmi_vdev_disconnect_event_id] = 19072 WMI_VDEV_DISCONNECT_EVENTID; 19073 event_ids[wmi_peer_create_conf_event_id] = 19074 WMI_PEER_CREATE_CONF_EVENTID; 19075 event_ids[wmi_pdev_cp_fwstats_eventid] = 19076 WMI_CTRL_PATH_STATS_EVENTID; 19077 event_ids[wmi_vdev_send_big_data_p2_eventid] = 19078 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 19079 event_ids[wmi_pdev_get_dpd_status_event_id] = 19080 WMI_PDEV_GET_DPD_STATUS_EVENTID; 19081 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 19082 event_ids[wmi_vdev_smart_monitor_event_id] = 19083 WMI_VDEV_SMART_MONITOR_EVENTID; 19084 #endif 19085 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 19086 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 19087 event_ids[wmi_pdev_set_halphy_cal_event_id] = 19088 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 19089 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 19090 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 19091 #ifdef WLAN_MGMT_RX_REO_SUPPORT 19092 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 19093 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 19094 #endif 19095 populate_tlv_events_id_mlo(event_ids); 19096 event_ids[wmi_roam_frame_event_id] = 19097 WMI_ROAM_FRAME_EVENTID; 19098 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19099 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 19100 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 19101 #endif 19102 #ifdef WLAN_FEATURE_MCC_QUOTA 19103 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 19104 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 19105 #endif 19106 event_ids[wmi_peer_rx_pn_response_event_id] = 19107 WMI_PEER_RX_PN_RESPONSE_EVENTID; 19108 event_ids[wmi_extract_pktlog_decode_info_eventid] = 19109 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 19110 #ifdef QCA_RSSI_DB2DBM 19111 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 19112 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 19113 #endif 19114 #ifdef MULTI_CLIENT_LL_SUPPORT 19115 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 19116 #endif 19117 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 19118 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 19119 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 19120 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 19121 WMI_RTT_PASN_PEER_DELETE_EVENTID; 19122 #endif 19123 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 19124 event_ids[wmi_get_roam_vendor_control_param_event_id] = 19125 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 19126 #endif 19127 } 19128 19129 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 19130 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 19131 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 19132 { 19133 wmi_service[wmi_service_get_station_in_ll_stats_req] = 19134 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 19135 } 19136 #else 19137 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 19138 { 19139 } 19140 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 19141 #else 19142 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 19143 { 19144 } 19145 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 19146 19147 #ifdef WLAN_FEATURE_11BE_MLO 19148 static void populate_tlv_service_mlo(uint32_t *wmi_service) 19149 { 19150 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 19151 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 19152 } 19153 #else /* WLAN_FEATURE_11BE_MLO */ 19154 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 19155 { 19156 } 19157 #endif /* WLAN_FEATURE_11BE_MLO */ 19158 19159 /** 19160 * populate_tlv_service() - populates wmi services 19161 * 19162 * @param wmi_service: Pointer to hold wmi_service 19163 * Return: None 19164 */ 19165 static void populate_tlv_service(uint32_t *wmi_service) 19166 { 19167 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 19168 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 19169 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 19170 wmi_service[wmi_service_roam_scan_offload] = 19171 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 19172 wmi_service[wmi_service_bcn_miss_offload] = 19173 WMI_SERVICE_BCN_MISS_OFFLOAD; 19174 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 19175 wmi_service[wmi_service_sta_advanced_pwrsave] = 19176 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 19177 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 19178 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 19179 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 19180 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 19181 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 19182 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 19183 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 19184 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 19185 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 19186 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 19187 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 19188 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 19189 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 19190 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 19191 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 19192 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 19193 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 19194 wmi_service[wmi_service_packet_power_save] = 19195 WMI_SERVICE_PACKET_POWER_SAVE; 19196 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 19197 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 19198 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 19199 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 19200 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 19201 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 19202 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 19203 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 19204 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 19205 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 19206 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 19207 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 19208 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 19209 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 19210 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 19211 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 19212 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 19213 wmi_service[wmi_service_mcc_bcn_interval_change] = 19214 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 19215 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 19216 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 19217 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 19218 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 19219 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 19220 wmi_service[wmi_service_lte_ant_share_support] = 19221 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 19222 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 19223 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 19224 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 19225 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 19226 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 19227 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 19228 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 19229 wmi_service[wmi_service_bcn_txrate_override] = 19230 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 19231 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 19232 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 19233 wmi_service[wmi_service_estimate_linkspeed] = 19234 WMI_SERVICE_ESTIMATE_LINKSPEED; 19235 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 19236 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 19237 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 19238 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 19239 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 19240 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 19241 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 19242 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 19243 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 19244 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 19245 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 19246 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 19247 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 19248 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 19249 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 19250 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 19251 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 19252 wmi_service[wmi_service_sap_auth_offload] = 19253 WMI_SERVICE_SAP_AUTH_OFFLOAD; 19254 wmi_service[wmi_service_dual_band_simultaneous_support] = 19255 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 19256 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 19257 wmi_service[wmi_service_ap_arpns_offload] = 19258 WMI_SERVICE_AP_ARPNS_OFFLOAD; 19259 wmi_service[wmi_service_per_band_chainmask_support] = 19260 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 19261 wmi_service[wmi_service_packet_filter_offload] = 19262 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 19263 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 19264 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 19265 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 19266 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 19267 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 19268 wmi_service[wmi_service_multiple_vdev_restart] = 19269 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 19270 wmi_service[wmi_service_smart_antenna_sw_support] = 19271 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 19272 wmi_service[wmi_service_smart_antenna_hw_support] = 19273 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 19274 19275 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 19276 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 19277 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 19278 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 19279 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 19280 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 19281 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 19282 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 19283 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 19284 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 19285 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 19286 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 19287 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 19288 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 19289 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 19290 wmi_service[wmi_service_periodic_chan_stat_support] = 19291 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 19292 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 19293 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 19294 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 19295 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 19296 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 19297 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 19298 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 19299 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 19300 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 19301 wmi_service[wmi_service_unified_wow_capability] = 19302 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 19303 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 19304 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 19305 wmi_service[wmi_service_sync_delete_cmds] = 19306 WMI_SERVICE_SYNC_DELETE_CMDS; 19307 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 19308 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 19309 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 19310 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 19311 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 19312 wmi_service[wmi_service_deprecated_replace] = 19313 WMI_SERVICE_DEPRECATED_REPLACE; 19314 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 19315 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 19316 wmi_service[wmi_service_enhanced_mcast_filter] = 19317 WMI_SERVICE_ENHANCED_MCAST_FILTER; 19318 wmi_service[wmi_service_half_rate_quarter_rate_support] = 19319 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 19320 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 19321 wmi_service[wmi_service_p2p_listen_offload_support] = 19322 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 19323 wmi_service[wmi_service_mark_first_wakeup_packet] = 19324 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 19325 wmi_service[wmi_service_multiple_mcast_filter_set] = 19326 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 19327 wmi_service[wmi_service_host_managed_rx_reorder] = 19328 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 19329 wmi_service[wmi_service_flash_rdwr_support] = 19330 WMI_SERVICE_FLASH_RDWR_SUPPORT; 19331 wmi_service[wmi_service_wlan_stats_report] = 19332 WMI_SERVICE_WLAN_STATS_REPORT; 19333 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 19334 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 19335 wmi_service[wmi_service_dfs_phyerr_offload] = 19336 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 19337 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 19338 wmi_service[wmi_service_fw_mem_dump_support] = 19339 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 19340 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 19341 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 19342 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 19343 wmi_service[wmi_service_hw_data_filtering] = 19344 WMI_SERVICE_HW_DATA_FILTERING; 19345 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 19346 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 19347 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 19348 wmi_service[wmi_service_extended_nss_support] = 19349 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 19350 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 19351 wmi_service[wmi_service_bcn_offload_start_stop_support] = 19352 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 19353 wmi_service[wmi_service_offchan_data_tid_support] = 19354 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 19355 wmi_service[wmi_service_support_dma] = 19356 WMI_SERVICE_SUPPORT_DIRECT_DMA; 19357 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 19358 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 19359 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 19360 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 19361 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 19362 wmi_service[wmi_service_11k_neighbour_report_support] = 19363 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 19364 wmi_service[wmi_service_ap_obss_detection_offload] = 19365 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 19366 wmi_service[wmi_service_bss_color_offload] = 19367 WMI_SERVICE_BSS_COLOR_OFFLOAD; 19368 wmi_service[wmi_service_gmac_offload_support] = 19369 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 19370 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 19371 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 19372 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 19373 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 19374 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 19375 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 19376 wmi_service[wmi_service_listen_interval_offload_support] = 19377 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 19378 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 19379 wmi_service[wmi_service_obss_spatial_reuse] = 19380 WMI_SERVICE_OBSS_SPATIAL_REUSE; 19381 wmi_service[wmi_service_per_vdev_chain_support] = 19382 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 19383 wmi_service[wmi_service_new_htt_msg_format] = 19384 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 19385 wmi_service[wmi_service_peer_unmap_cnf_support] = 19386 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 19387 wmi_service[wmi_service_beacon_reception_stats] = 19388 WMI_SERVICE_BEACON_RECEPTION_STATS; 19389 wmi_service[wmi_service_vdev_latency_config] = 19390 WMI_SERVICE_VDEV_LATENCY_CONFIG; 19391 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 19392 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 19393 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 19394 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 19395 wmi_service[wmi_service_nan_disable_support] = 19396 WMI_SERVICE_NAN_DISABLE_SUPPORT; 19397 wmi_service[wmi_service_sta_plus_sta_support] = 19398 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 19399 wmi_service[wmi_service_hw_db2dbm_support] = 19400 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 19401 wmi_service[wmi_service_wlm_stats_support] = 19402 WMI_SERVICE_WLM_STATS_REQUEST; 19403 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 19404 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 19405 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 19406 wmi_service[wmi_service_cfr_capture_support] = 19407 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 19408 wmi_service[wmi_service_bcast_twt_support] = 19409 WMI_SERVICE_BROADCAST_TWT; 19410 wmi_service[wmi_service_wpa3_ft_sae_support] = 19411 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 19412 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 19413 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 19414 wmi_service[wmi_service_ft_fils] = 19415 WMI_SERVICE_WPA3_FT_FILS; 19416 wmi_service[wmi_service_adaptive_11r_support] = 19417 WMI_SERVICE_ADAPTIVE_11R_ROAM; 19418 wmi_service[wmi_service_tx_compl_tsf64] = 19419 WMI_SERVICE_TX_COMPL_TSF64; 19420 wmi_service[wmi_service_data_stall_recovery_support] = 19421 WMI_SERVICE_DSM_ROAM_FILTER; 19422 wmi_service[wmi_service_vdev_delete_all_peer] = 19423 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 19424 wmi_service[wmi_service_three_way_coex_config_legacy] = 19425 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 19426 wmi_service[wmi_service_rx_fse_support] = 19427 WMI_SERVICE_RX_FSE_SUPPORT; 19428 wmi_service[wmi_service_sae_roam_support] = 19429 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 19430 wmi_service[wmi_service_owe_roam_support] = 19431 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 19432 wmi_service[wmi_service_6ghz_support] = 19433 WMI_SERVICE_6GHZ_SUPPORT; 19434 wmi_service[wmi_service_bw_165mhz_support] = 19435 WMI_SERVICE_BW_165MHZ_SUPPORT; 19436 wmi_service[wmi_service_bw_restricted_80p80_support] = 19437 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 19438 wmi_service[wmi_service_packet_capture_support] = 19439 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 19440 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 19441 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 19442 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 19443 wmi_service[wmi_service_multiple_vdev_restart_ext] = 19444 WMI_SERVICE_UNAVAILABLE; 19445 wmi_service[wmi_service_time_sync_ftm] = 19446 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 19447 wmi_service[wmi_service_nss_ratio_to_host_support] = 19448 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 19449 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 19450 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 19451 wmi_service[wmi_beacon_protection_support] = 19452 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 19453 wmi_service[wmi_service_sta_nan_ndi_four_port] = 19454 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 19455 wmi_service[wmi_service_host_scan_stop_vdev_all] = 19456 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 19457 wmi_service[wmi_support_extend_address] = 19458 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 19459 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 19460 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 19461 wmi_service[wmi_service_suiteb_roam_support] = 19462 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 19463 wmi_service[wmi_service_no_interband_mcc_support] = 19464 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 19465 wmi_service[wmi_service_dual_sta_roam_support] = 19466 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 19467 wmi_service[wmi_service_peer_create_conf] = 19468 WMI_SERVICE_PEER_CREATE_CONF; 19469 wmi_service[wmi_service_configure_roam_trigger_param_support] = 19470 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 19471 wmi_service[wmi_service_5dot9_ghz_support] = 19472 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 19473 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 19474 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 19475 wmi_service[wmi_service_cfr_capture_count_support] = 19476 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 19477 wmi_service[wmi_service_ocv_support] = 19478 WMI_SERVICE_OCV_SUPPORT; 19479 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 19480 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 19481 wmi_service[wmi_service_thermal_multi_client_support] = 19482 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 19483 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 19484 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 19485 wmi_service[wmi_service_fse_cmem_alloc_support] = 19486 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 19487 wmi_service[wmi_service_scan_conf_per_ch_support] = 19488 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 19489 wmi_service[wmi_service_csa_beacon_template] = 19490 WMI_SERVICE_CSA_BEACON_TEMPLATE; 19491 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 19492 wmi_service[wmi_service_rtt_11az_ntb_support] = 19493 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 19494 wmi_service[wmi_service_rtt_11az_tb_support] = 19495 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 19496 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 19497 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 19498 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 19499 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 19500 #endif 19501 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 19502 wmi_service[wmi_service_igmp_offload_support] = 19503 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 19504 #endif 19505 19506 #ifdef FEATURE_WLAN_TDLS 19507 #ifdef WLAN_FEATURE_11AX 19508 wmi_service[wmi_service_tdls_ax_support] = 19509 WMI_SERVICE_11AX_TDLS_SUPPORT; 19510 wmi_service[wmi_service_tdls_6g_support] = 19511 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 19512 #endif 19513 wmi_service[wmi_service_tdls_wideband_support] = 19514 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 19515 #endif 19516 19517 #ifdef WLAN_SUPPORT_TWT 19518 wmi_service[wmi_service_twt_bcast_req_support] = 19519 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 19520 wmi_service[wmi_service_twt_bcast_resp_support] = 19521 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 19522 wmi_service[wmi_service_twt_nudge] = 19523 WMI_SERVICE_TWT_NUDGE; 19524 wmi_service[wmi_service_all_twt] = 19525 WMI_SERVICE_TWT_ALL_DIALOG_ID; 19526 wmi_service[wmi_service_twt_statistics] = 19527 WMI_SERVICE_TWT_STATS; 19528 #endif 19529 wmi_service[wmi_service_spectral_scan_disabled] = 19530 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 19531 wmi_service[wmi_service_sae_eapol_offload_support] = 19532 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 19533 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 19534 19535 wmi_service[wmi_service_wapi_concurrency_supported] = 19536 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 19537 wmi_service[wmi_service_sap_connected_d3_wow] = 19538 WMI_SERVICE_SAP_CONNECTED_D3WOW; 19539 wmi_service[wmi_service_go_connected_d3_wow] = 19540 WMI_SERVICE_SAP_CONNECTED_D3WOW; 19541 wmi_service[wmi_service_ext_tpc_reg_support] = 19542 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 19543 wmi_service[wmi_service_ndi_txbf_support] = 19544 WMI_SERVICE_NDI_TXBF_SUPPORT; 19545 wmi_service[wmi_service_reg_cc_ext_event_support] = 19546 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 19547 #if defined(CONFIG_BAND_6GHZ) 19548 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 19549 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 19550 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 19551 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 19552 #endif 19553 wmi_service[wmi_service_dcs_awgn_int_support] = 19554 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 19555 wmi_populate_service_11be(wmi_service); 19556 19557 #ifdef WLAN_FEATURE_BIG_DATA_STATS 19558 wmi_service[wmi_service_big_data_support] = 19559 WMI_SERVICE_BIG_DATA_SUPPORT; 19560 #endif 19561 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 19562 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 19563 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 19564 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 19565 wmi_service[wmi_service_halphy_cal_status] = 19566 WMI_SERVICE_HALPHY_CAL_STATUS; 19567 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 19568 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 19569 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 19570 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 19571 wmi_service[wmi_service_ema_multiple_group_supported] = 19572 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 19573 wmi_service[wmi_service_large_beacon_supported] = 19574 WMI_SERVICE_LARGE_BEACON_SUPPORT; 19575 wmi_service[wmi_service_aoa_for_rcc_supported] = 19576 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 19577 #ifdef WLAN_FEATURE_P2P_P2P_STA 19578 wmi_service[wmi_service_p2p_p2p_cc_support] = 19579 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 19580 #endif 19581 #ifdef THERMAL_STATS_SUPPORT 19582 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 19583 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 19584 #endif 19585 wmi_service[wmi_service_hw_mode_policy_offload_support] = 19586 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 19587 wmi_service[wmi_service_mgmt_rx_reo_supported] = 19588 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 19589 wmi_service[wmi_service_phy_dma_byte_swap_support] = 19590 WMI_SERVICE_UNAVAILABLE; 19591 wmi_service[wmi_service_spectral_session_info_support] = 19592 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 19593 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 19594 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19595 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 19596 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 19597 #endif 19598 wmi_service[wmi_service_probe_all_bw_support] = 19599 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 19600 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 19601 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 19602 #ifdef QCA_UNDECODED_METADATA_SUPPORT 19603 wmi_service[wmi_service_fp_phy_err_filter_support] = 19604 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 19605 #endif 19606 populate_tlv_service_mlo(wmi_service); 19607 wmi_service[wmi_service_pdev_rate_config_support] = 19608 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 19609 wmi_service[wmi_service_multi_peer_group_cmd_support] = 19610 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 19611 #ifdef WLAN_FEATURE_11BE 19612 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 19613 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 19614 #endif 19615 wmi_service[wmi_service_pn_replay_check_support] = 19616 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 19617 #ifdef QCA_RSSI_DB2DBM 19618 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 19619 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 19620 #endif 19621 wmi_service[wmi_service_pktlog_decode_info_support] = 19622 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 19623 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19624 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 19625 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 19626 #endif 19627 #ifdef MULTI_CLIENT_LL_SUPPORT 19628 wmi_service[wmi_service_configure_multi_client_ll_support] = 19629 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 19630 #endif 19631 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 19632 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 19633 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 19634 #endif 19635 } 19636 19637 /** 19638 * wmi_ocb_ut_attach() - Attach OCB test framework 19639 * @wmi_handle: wmi handle 19640 * 19641 * Return: None 19642 */ 19643 #ifdef WLAN_OCB_UT 19644 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 19645 #else 19646 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 19647 { 19648 return; 19649 } 19650 #endif 19651 19652 /** 19653 * wmi_tlv_attach() - Attach TLV APIs 19654 * 19655 * Return: None 19656 */ 19657 void wmi_tlv_attach(wmi_unified_t wmi_handle) 19658 { 19659 wmi_handle->ops = &tlv_ops; 19660 wmi_ocb_ut_attach(wmi_handle); 19661 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 19662 #ifdef WMI_INTERFACE_EVENT_LOGGING 19663 /* Skip saving WMI_CMD_HDR and TLV HDR */ 19664 wmi_handle->soc->buf_offset_command = 8; 19665 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 19666 wmi_handle->soc->buf_offset_event = 4; 19667 #endif 19668 populate_tlv_events_id(wmi_handle->wmi_events); 19669 populate_tlv_service(wmi_handle->services); 19670 wmi_wds_attach_tlv(wmi_handle); 19671 wmi_twt_attach_tlv(wmi_handle); 19672 wmi_extscan_attach_tlv(wmi_handle); 19673 wmi_smart_ant_attach_tlv(wmi_handle); 19674 wmi_dbr_attach_tlv(wmi_handle); 19675 wmi_atf_attach_tlv(wmi_handle); 19676 wmi_ap_attach_tlv(wmi_handle); 19677 wmi_bcn_attach_tlv(wmi_handle); 19678 wmi_ocb_attach_tlv(wmi_handle); 19679 wmi_nan_attach_tlv(wmi_handle); 19680 wmi_p2p_attach_tlv(wmi_handle); 19681 wmi_interop_issues_ap_attach_tlv(wmi_handle); 19682 wmi_dcs_attach_tlv(wmi_handle); 19683 wmi_roam_attach_tlv(wmi_handle); 19684 wmi_concurrency_attach_tlv(wmi_handle); 19685 wmi_pmo_attach_tlv(wmi_handle); 19686 wmi_sta_attach_tlv(wmi_handle); 19687 wmi_11ax_bss_color_attach_tlv(wmi_handle); 19688 wmi_fwol_attach_tlv(wmi_handle); 19689 wmi_vdev_attach_tlv(wmi_handle); 19690 wmi_cfr_attach_tlv(wmi_handle); 19691 wmi_cp_stats_attach_tlv(wmi_handle); 19692 wmi_gpio_attach_tlv(wmi_handle); 19693 wmi_11be_attach_tlv(wmi_handle); 19694 } 19695 qdf_export_symbol(wmi_tlv_attach); 19696 19697 /** 19698 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 19699 * 19700 * Return: None 19701 */ 19702 void wmi_tlv_init(void) 19703 { 19704 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 19705 } 19706