1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "wmi_unified_api.h" 21 #include "wmi.h" 22 #include "wmi_version.h" 23 #include "wmi_unified_priv.h" 24 #include "wmi_version_allowlist.h" 25 #include "wifi_pos_public_struct.h" 26 #include <qdf_module.h> 27 #include <wlan_defs.h> 28 #include <wlan_cmn.h> 29 #include <htc_services.h> 30 #ifdef FEATURE_WLAN_APF 31 #include "wmi_unified_apf_tlv.h" 32 #endif 33 #ifdef WLAN_FEATURE_ACTION_OUI 34 #include "wmi_unified_action_oui_tlv.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #include "wmi_unified_twt_api.h" 45 #include "wmi_unified_wds_api.h" 46 47 #ifdef WLAN_POLICY_MGR_ENABLE 48 #include "wlan_policy_mgr_public_struct.h" 49 #endif 50 51 #ifdef WMI_SMART_ANT_SUPPORT 52 #include "wmi_unified_smart_ant_api.h" 53 #endif 54 55 #ifdef WMI_DBR_SUPPORT 56 #include "wmi_unified_dbr_api.h" 57 #endif 58 59 #ifdef WMI_ATF_SUPPORT 60 #include "wmi_unified_atf_api.h" 61 #endif 62 63 #ifdef WMI_AP_SUPPORT 64 #include "wmi_unified_ap_api.h" 65 #endif 66 67 #include <wmi_unified_vdev_api.h> 68 #include <wmi_unified_vdev_tlv.h> 69 #include <wmi_unified_11be_tlv.h> 70 71 /* 72 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 73 * then channel_list may fill the upper 12 bits with channel flags, 74 * while using only the lower 20 bits for channel frequency. 75 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 76 * then channel_list only holds the frequency value. 77 */ 78 #define CHAN_LIST_FLAG_MASK_POS 20 79 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 80 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 81 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 82 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 83 84 /* HTC service ids for WMI for multi-radio */ 85 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 86 WMI_CONTROL_SVC_WMAC1, 87 WMI_CONTROL_SVC_WMAC2}; 88 89 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 90 /*Populate peer_param array whose index as host id and 91 *value as target id 92 */ 93 static const uint32_t peer_param_tlv[] = { 94 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 95 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 96 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 97 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 98 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 99 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 100 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 101 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 102 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 103 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 104 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 105 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 106 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 107 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 108 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 109 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 110 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 111 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_ALLOWLIST, 112 [WMI_HOST_PEER_SET_MAX_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 113 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 114 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 115 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 116 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 117 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 118 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 119 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 120 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 121 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 122 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 123 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 124 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 125 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 126 [WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP] = 127 WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP, 128 }; 129 130 /** 131 * Populate pdev_param_value whose index is host param and value is target 132 * param 133 */ 134 static const uint32_t pdev_param_tlv[] = { 135 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 136 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 137 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 138 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 139 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 140 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 141 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 142 [wmi_pdev_param_resmgr_offchan_mode] = 143 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 144 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 145 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 146 [wmi_pdev_param_non_agg_sw_retry_th] = 147 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 148 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 149 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 150 [wmi_pdev_param_ac_aggrsize_scaling] = 151 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 152 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 153 [wmi_pdev_param_ltr_ac_latency_be] = 154 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 155 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 156 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 157 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 158 [wmi_pdev_param_ltr_ac_latency_timeout] = 159 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 160 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 161 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 162 [wmi_pdev_param_ltr_tx_activity_timeout] = 163 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 164 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 165 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 166 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 167 [wmi_pdev_param_pcielp_txbuf_watermark] = 168 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 169 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 170 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 171 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 172 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 173 [wmi_pdev_param_pdev_stats_update_period] = 174 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 175 [wmi_pdev_param_vdev_stats_update_period] = 176 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 177 [wmi_pdev_param_peer_stats_update_period] = 178 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 179 [wmi_pdev_param_bcnflt_stats_update_period] = 180 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 181 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 182 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 183 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 184 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 185 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 186 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 187 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 188 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 189 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 190 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 191 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 192 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 193 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 194 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 195 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 196 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 197 [wmi_pdev_param_low_power_rf_enable] = 198 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 199 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 200 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 201 [wmi_pdev_param_power_collapse_enable] = 202 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 203 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 204 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 205 [wmi_pdev_param_audio_over_wlan_latency] = 206 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 207 [wmi_pdev_param_audio_over_wlan_enable] = 208 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 209 [wmi_pdev_param_whal_mib_stats_update_enable] = 210 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 211 [wmi_pdev_param_vdev_rate_stats_update_period] = 212 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 213 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 214 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 215 [wmi_pdev_param_adaptive_early_rx_enable] = 216 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 217 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 218 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 219 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 220 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 221 [wmi_pdev_param_early_rx_fix_sleep_slop] = 222 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 223 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 224 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 225 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 226 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 227 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 228 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 229 [wmi_pdev_param_bto_fix_bcn_timeout] = 230 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 231 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 232 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 233 [wmi_pdev_param_ce_bto_combo_ce_value] = 234 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 235 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 236 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 237 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 238 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 239 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 240 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 241 [wmi_pdev_param_soft_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 242 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 243 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 244 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 245 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 246 [wmi_pdev_peer_sta_ps_statechg_enable] = 247 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 248 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 249 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 250 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 251 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 252 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 253 [wmi_pdev_param_set_mcast_bcast_echo] = 254 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 255 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 256 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 257 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 258 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 259 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 260 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 261 [wmi_pdev_param_enable_per_tid_amsdu] = 262 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 263 [wmi_pdev_param_enable_per_tid_ampdu] = 264 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 265 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 266 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 267 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 268 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 269 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 270 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 271 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 272 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 273 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 274 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 275 [wmi_pdev_param_atf_obss_noise_sch] = 276 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 277 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 278 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 279 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 280 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 281 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 282 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 283 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 284 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 285 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 286 [wmi_pdev_param_set_disable_reset_cmdid] = 287 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 288 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 289 [wmi_pdev_param_txbf_sound_period_cmdid] = 290 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 291 [wmi_pdev_param_set_burst_mode_cmdid] = 292 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 293 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 294 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 295 [wmi_pdev_param_set_promisc_mode_cmdid] = 296 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 297 [wmi_pdev_param_set_ppdu_duration_cmdid] = 298 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 299 [wmi_pdev_param_remove_mcast2ucast_buffer] = 300 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 301 [wmi_pdev_param_set_mcast2ucast_buffer] = 302 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 303 [wmi_pdev_param_set_mcast2ucast_mode] = 304 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 305 [wmi_pdev_param_smart_antenna_default_antenna] = 306 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 307 [wmi_pdev_param_fast_channel_reset] = 308 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 309 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 310 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 311 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 312 [wmi_pdev_param_antenna_gain_half_db] = 313 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 314 [wmi_pdev_param_esp_indication_period] = 315 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 316 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 317 [wmi_pdev_param_esp_airtime_fraction] = 318 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 319 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 320 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 321 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 322 /* Trigger interval for all trigger types. */ 323 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 324 [wmi_pdev_param_sub_channel_marking] = 325 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 326 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 327 [wmi_pdev_param_equal_ru_allocation_enable] = 328 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 329 [wmi_pdev_param_per_peer_prd_cfr_enable] = 330 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 331 [wmi_pdev_param_nav_override_config] = 332 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 333 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 334 [wmi_pdev_param_set_prb_rsp_ttl] = 335 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 336 [wmi_pdev_param_set_mu_ppdu_duration] = 337 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 338 [wmi_pdev_param_set_tbtt_ctrl] = 339 WMI_PDEV_PARAM_SET_TBTT_CTRL, 340 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 341 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 342 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 343 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 344 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 345 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 346 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 347 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 348 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 349 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 350 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 351 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 352 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 353 [wmi_pdev_param_set_mesh_params] = WMI_PDEV_PARAM_SET_MESH_PARAMS, 354 [wmi_pdev_param_mpd_userpd_ssr] = WMI_PDEV_PARAM_MPD_USERPD_SSR, 355 [wmi_pdev_param_low_latency_mode] = 356 WMI_PDEV_PARAM_LOW_LATENCY_SCHED_MODE, 357 [wmi_pdev_param_scan_radio_tx_on_dfs] = 358 WMI_PDEV_PARAM_SCAN_RADIO_TX_ON_DFS, 359 [wmi_pdev_param_en_probe_all_bw] = 360 WMI_PDEV_PARAM_EN_PROBE_ALL_BW, 361 [wmi_pdev_param_obss_min_duration_check_for_sr] = 362 WMI_PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR, 363 [wmi_pdev_param_truncate_sr] = WMI_PDEV_PARAM_TRUNCATE_SR, 364 [wmi_pdev_param_ctrl_frame_obss_pd_threshold] = 365 WMI_PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD, 366 [wmi_pdev_param_rate_upper_cap] = WMI_PDEV_PARAM_RATE_UPPER_CAP, 367 [wmi_pdev_param_rate_retry_mcs_drop] = 368 WMI_PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH, 369 [wmi_pdev_param_mcs_probe_intvl] = 370 WMI_PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL, 371 [wmi_pdev_param_nss_probe_intvl] = 372 WMI_PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL, 373 [wmi_pdev_param_dtim_synth] = WMI_PDEV_PARAM_DTIM_SYNTH, 374 [wmi_pdev_param_1ch_dtim_optimized_chain_selection] = 375 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION, 376 [wmi_pdev_param_tx_sch_delay] = WMI_PDEV_PARAM_TX_SCH_DELAY, 377 [wmi_pdev_param_en_update_scram_seed] = 378 WMI_PDEV_PARAM_EN_UPDATE_SCRAM_SEED, 379 [wmi_pdev_param_secondary_retry_enable] = 380 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE, 381 [wmi_pdev_param_set_sap_xlna_bypass] = 382 WMI_PDEV_PARAM_SET_SAP_XLNA_BYPASS, 383 [wmi_pdev_param_set_dfs_chan_ageout_time] = 384 WMI_PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME, 385 [wmi_pdev_param_pdev_stats_tx_xretry_ext] = 386 WMI_PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT, 387 [wmi_pdev_param_smart_chainmask_scheme] = 388 WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME, 389 [wmi_pdev_param_alternative_chainmask_scheme] = 390 WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME, 391 [wmi_pdev_param_enable_rts_sifs_bursting] = 392 WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING, 393 [wmi_pdev_param_max_mpdus_in_ampdu] = WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU, 394 [wmi_pdev_param_set_iot_pattern] = WMI_PDEV_PARAM_SET_IOT_PATTERN, 395 [wmi_pdev_param_mwscoex_scc_chavd_delay] = 396 WMI_PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY, 397 [wmi_pdev_param_mwscoex_pcc_chavd_delay] = 398 WMI_PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY, 399 [wmi_pdev_param_mwscoex_set_5gnr_pwr_limit] = 400 WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT, 401 [wmi_pdev_param_mwscoex_4g_allow_quick_ftdm] = 402 WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM, 403 [wmi_pdev_param_fast_pwr_transition] = 404 WMI_PDEV_PARAM_FAST_PWR_TRANSITION, 405 [wmi_pdev_auto_detect_power_failure] = 406 WMI_PDEV_AUTO_DETECT_POWER_FAILURE, 407 [wmi_pdev_param_gcmp_support_enable] = 408 WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE, 409 [wmi_pdev_param_abg_mode_tx_chain_num] = 410 WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM, 411 [wmi_pdev_param_peer_stats_info_enable] = 412 WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE, 413 [wmi_pdev_param_enable_cck_txfir_override] = 414 WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE, 415 [wmi_pdev_param_twt_ac_config] = WMI_PDEV_PARAM_TWT_AC_CONFIG, 416 [wmi_pdev_param_pcie_hw_ilp] = WMI_PDEV_PARAM_PCIE_HW_ILP, 417 [wmi_pdev_param_disable_hw_assist] = WMI_PDEV_PARAM_DISABLE_HW_ASSIST, 418 [wmi_pdev_param_ant_div_usrcfg] = WMI_PDEV_PARAM_ANT_DIV_USRCFG, 419 [wmi_pdev_param_ctrl_retry_limit] = WMI_PDEV_PARAM_CTRL_RETRY_LIMIT, 420 [wmi_pdev_param_propagation_delay] = WMI_PDEV_PARAM_PROPAGATION_DELAY, 421 [wmi_pdev_param_ena_ant_div] = WMI_PDEV_PARAM_ENA_ANT_DIV, 422 [wmi_pdev_param_force_chain_ant] = WMI_PDEV_PARAM_FORCE_CHAIN_ANT, 423 [wmi_pdev_param_ant_div_selftest] = WMI_PDEV_PARAM_ANT_DIV_SELFTEST, 424 [wmi_pdev_param_ant_div_selftest_intvl] = 425 WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL, 426 [wmi_pdev_param_1ch_dtim_optimized_chain_selection] = 427 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION, 428 [wmi_pdev_param_data_stall_detect_enable] = 429 WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE, 430 [wmi_pdev_param_max_mpdus_in_ampdu] = 431 WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU, 432 [wmi_pdev_param_stats_observation_period] = 433 WMI_PDEV_PARAM_STATS_OBSERVATION_PERIOD, 434 [wmi_pdev_param_cts2self_for_p2p_go_config] = 435 WMI_PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG, 436 [wmi_pdev_param_txpower_reason_sar] = WMI_PDEV_PARAM_TXPOWER_REASON_SAR, 437 }; 438 439 /** 440 * Populate vdev_param_value_tlv array whose index is host param 441 * and value is target param 442 */ 443 static const uint32_t vdev_param_tlv[] = { 444 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 445 [wmi_vdev_param_fragmentation_threshold] = 446 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 447 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 448 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 449 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 450 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 451 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 452 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 453 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 454 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 455 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 456 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 457 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 458 [wmi_vdev_oc_scheduler_air_time_limit] = 459 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 460 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 461 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 462 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 463 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 464 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 465 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 466 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 467 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 468 [wmi_vdev_param_disable_htprotection] = 469 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 470 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 471 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 472 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 473 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 474 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 475 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 476 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 477 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 478 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 479 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 480 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 481 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 482 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 483 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 484 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 485 [wmi_vdev_param_unknown_dest_indicate] = 486 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 487 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 488 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 489 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 490 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 491 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 492 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 493 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 494 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 495 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 496 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 497 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 498 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 499 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 500 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 501 [wmi_vdev_param_early_rx_adjust_enable] = 502 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 503 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 504 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 505 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 506 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 507 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 508 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 509 [wmi_vdev_param_early_rx_adjust_pause] = 510 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 511 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 512 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 513 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 514 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 515 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 516 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 517 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 518 [wmi_vdev_param_early_rx_drift_sample] = 519 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 520 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 521 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 522 [wmi_vdev_param_ebt_resync_timeout] = 523 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 524 [wmi_vdev_param_aggr_trig_event_enable] = 525 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 526 [wmi_vdev_param_is_ibss_power_save_allowed] = 527 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 528 [wmi_vdev_param_is_power_collapse_allowed] = 529 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 530 [wmi_vdev_param_is_awake_on_txrx_enabled] = 531 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 532 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 533 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 534 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 535 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 536 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 537 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 538 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 539 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 540 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 541 [wmi_vdev_param_stats_avg_factor] = 542 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 543 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 544 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 545 [wmi_vdev_param_mcc_rtscts_protection_enable] = 546 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 547 [wmi_vdev_param_mcc_broadcast_probe_enable] = 548 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 549 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 550 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 551 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 552 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 553 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 554 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 555 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 556 [wmi_vdev_param_set_he_sounding_mode] = 557 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 558 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 559 #ifdef WLAN_FEATURE_11BE 560 [wmi_vdev_param_set_ehtop] = WMI_VDEV_PARAM_EHTOPS_0_31, 561 [wmi_vdev_param_set_eht_mu_mode] = WMI_VDEV_PARAM_SET_EHT_MU_MODE, 562 [wmi_vdev_param_set_eht_puncturing_mode] = 563 WMI_VDEV_PARAM_SET_EHT_PUNCTURING_MODE, 564 [wmi_vdev_param_set_eht_ltf] = WMI_VDEV_PARAM_EHT_LTF, 565 [wmi_vdev_param_set_ul_eht_ltf] = WMI_VDEV_PARAM_UL_EHT_LTF, 566 [wmi_vdev_param_set_eht_dcm] = WMI_VDEV_PARAM_EHT_DCM, 567 [wmi_vdev_param_set_eht_range_ext] = WMI_VDEV_PARAM_EHT_RANGE_EXT, 568 [wmi_vdev_param_set_non_data_eht_range_ext] = 569 WMI_VDEV_PARAM_NON_DATA_EHT_RANGE_EXT, 570 #endif 571 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 572 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 573 [wmi_vdev_param_atf_ssid_sched_policy] = 574 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 575 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 576 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 577 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 578 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 579 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 580 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 581 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 582 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 583 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 584 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 585 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 586 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 587 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 588 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 589 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 590 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 591 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 592 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 593 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 594 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 595 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 596 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 597 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 598 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 599 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 600 [wmi_vdev_param_mcast_rc_stale_period] = 601 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 602 [wmi_vdev_param_enable_multi_group_key] = 603 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 604 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 605 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 606 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 607 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 608 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 609 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 610 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 611 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 612 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 613 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 614 [wmi_vdev_param_nan_config_features] = 615 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 616 [wmi_vdev_param_enable_disable_rtt_responder_role] = 617 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, 618 [wmi_vdev_param_enable_disable_rtt_initiator_role] = 619 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE, 620 [wmi_vdev_param_mcast_steer] = WMI_VDEV_PARAM_MCAST_STEERING, 621 #ifdef MULTI_CLIENT_LL_SUPPORT 622 [wmi_vdev_param_set_normal_latency_flags_config] = 623 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 624 [wmi_vdev_param_set_xr_latency_flags_config] = 625 WMI_VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION, 626 [wmi_vdev_param_set_low_latency_flags_config] = 627 WMI_VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION, 628 [wmi_vdev_param_set_ultra_low_latency_flags_config] = 629 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION, 630 [wmi_vdev_param_set_normal_latency_ul_dl_config] = 631 WMI_VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION, 632 [wmi_vdev_param_set_xr_latency_ul_dl_config] = 633 WMI_VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION, 634 [wmi_vdev_param_set_low_latency_ul_dl_config] = 635 WMI_VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION, 636 [wmi_vdev_param_set_ultra_low_latency_ul_dl_config] = 637 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION, 638 [wmi_vdev_param_set_default_ll_config] = 639 WMI_VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION, 640 [wmi_vdev_param_set_multi_client_ll_feature_config] = 641 WMI_VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION, 642 #endif 643 [wmi_vdev_param_set_traffic_config] = 644 WMI_VDEV_PARAM_VDEV_TRAFFIC_CONFIG, 645 [wmi_vdev_param_he_range_ext] = WMI_VDEV_PARAM_HE_RANGE_EXT, 646 [wmi_vdev_param_non_data_he_range_ext] = 647 WMI_VDEV_PARAM_NON_DATA_HE_RANGE_EXT, 648 [wmi_vdev_param_ndp_inactivity_timeout] = 649 WMI_VDEV_PARAM_NDP_INACTIVITY_TIMEOUT, 650 [wmi_vdev_param_ndp_keepalive_timeout] = 651 WMI_VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT, 652 [wmi_vdev_param_final_bmiss_time_sec] = 653 WMI_VDEV_PARAM_FINAL_BMISS_TIME_SEC, 654 [wmi_vdev_param_final_bmiss_time_wow_sec] = 655 WMI_VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC, 656 [wmi_vdev_param_ap_keepalive_max_idle_inactive_secs] = 657 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 658 [wmi_vdev_param_per_band_mgmt_tx_rate] = 659 WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE, 660 [wmi_vdev_param_max_li_of_moddtim] = 661 WMI_VDEV_PARAM_MAX_LI_OF_MODDTIM, 662 [wmi_vdev_param_moddtim_cnt] = WMI_VDEV_PARAM_MODDTIM_CNT, 663 [wmi_vdev_param_max_li_of_moddtim_ms] = 664 WMI_VDEV_PARAM_MAX_LI_OF_MODDTIM_MS, 665 [wmi_vdev_param_dyndtim_cnt] = WMI_VDEV_PARAM_DYNDTIM_CNT, 666 [wmi_vdev_param_wmm_txop_enable] = WMI_VDEV_PARAM_WMM_TXOP_ENABLE, 667 [wmi_vdev_param_enable_bcast_probe_response] = 668 WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, 669 [wmi_vdev_param_fils_max_channel_guard_time] = 670 WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, 671 [wmi_vdev_param_probe_delay] = WMI_VDEV_PARAM_PROBE_DELAY, 672 [wmi_vdev_param_repeat_probe_time] = WMI_VDEV_PARAM_REPEAT_PROBE_TIME, 673 [wmi_vdev_param_enable_disable_oce_features] = 674 WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES, 675 [wmi_vdev_param_enable_disable_nan_config_features] = 676 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 677 [wmi_vdev_param_rsn_capability] = WMI_VDEV_PARAM_RSN_CAPABILITY, 678 [wmi_vdev_param_smps_intolerant] = WMI_VDEV_PARAM_SMPS_INTOLERANT, 679 [wmi_vdev_param_abg_mode_tx_chain_num] = WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM, 680 [wmi_vdev_param_nth_beacon_to_host] = WMI_VDEV_PARAM_NTH_BEACON_TO_HOST, 681 [wmi_vdev_param_prohibit_data_mgmt] = WMI_VDEV_PARAM_PROHIBIT_DATA_MGMT, 682 [wmi_vdev_param_skip_roam_eapol_4way_handshake] = WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE, 683 [wmi_vdev_param_skip_sae_roam_4way_handshake] = WMI_VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE, 684 [wmi_vdev_param_roam_11kv_ctrl] = WMI_VDEV_PARAM_ROAM_11KV_CTRL, 685 [wmi_vdev_param_disable_noa_p2p_go] = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO, 686 [wmi_vdev_param_packet_capture_mode] = WMI_VDEV_PARAM_PACKET_CAPTURE_MODE, 687 [wmi_vdev_param_smart_monitor_config] = WMI_VDEV_PARAM_SMART_MONITOR_CONFIG, 688 [wmi_vdev_param_force_dtim_cnt] = WMI_VDEV_PARAM_FORCE_DTIM_CNT, 689 [wmi_vdev_param_sho_config] = WMI_VDEV_PARAM_SHO_CONFIG, 690 [wmi_vdev_param_gtx_enable] = WMI_VDEV_PARAM_GTX_ENABLE, 691 [wmi_vdev_param_mu_edca_fw_update_en] = WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN, 692 [wmi_vdev_param_enable_disable_rtt_initiator_random_mac] = 693 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC, 694 [wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster] = 695 WMI_VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER, 696 [wmi_vdev_param_txpower_scale_decr_db] = WMI_VDEV_PARAM_TXPOWER_SCALE_DECR_DB, 697 [wmi_vdev_param_txpower_scale] = WMI_VDEV_PARAM_TXPOWER_SCALE, 698 [wmi_vdev_param_agg_sw_retry_th] = WMI_VDEV_PARAM_AGG_SW_RETRY_TH, 699 [wmi_vdev_param_obsspd] = WMI_VDEV_PARAM_OBSSPD, 700 [wmi_vdev_param_multi_client_ll_feature_configuration] = 701 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 702 [wmi_vdev_param_normal_latency_flags_configuration] = 703 WMI_VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION, 704 [wmi_vdev_param_xr_latency_flags_configuration] = 705 WMI_VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION, 706 [wmi_vdev_param_low_latency_flags_configuration] = 707 WMI_VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION, 708 [wmi_vdev_param_ultra_low_latency_flags_configuration] = 709 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION, 710 [wmi_vdev_param_normal_latency_ul_dl_configuration] = 711 WMI_VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION, 712 [wmi_vdev_param_xr_latency_ul_dl_configuration] = 713 WMI_VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION, 714 [wmi_vdev_param_low_latency_ul_dl_configuration] = 715 WMI_VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION, 716 [wmi_vdev_param_ultra_low_latency_ul_dl_configuration] = 717 WMI_VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION, 718 [wmi_vdev_param_default_latency_level_configuration] = 719 WMI_VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION, 720 [wmi_vdev_param_amsdu_aggregation_size_optimization] = 721 WMI_VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION, 722 [wmi_vdev_param_non_agg_sw_retry_th] = 723 WMI_VDEV_PARAM_NON_AGG_SW_RETRY_TH, 724 }; 725 #endif 726 727 #ifndef WMI_PKTLOG_EVENT_CBF 728 #define WMI_PKTLOG_EVENT_CBF 0x100 729 #endif 730 731 /** 732 * Populate the pktlog event tlv array, where 733 * the values are the FW WMI events, which host 734 * uses to communicate with FW for pktlog 735 */ 736 737 static const uint32_t pktlog_event_tlv[] = { 738 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 739 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 740 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 741 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 742 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 743 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 744 WMI_PKTLOG_EVENT_SMART_ANTENNA, 745 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 746 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 747 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 748 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 749 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 750 #ifdef BE_PKTLOG_SUPPORT 751 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 752 #endif 753 }; 754 755 /** 756 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 757 * host to target defines. 758 * @wmi_handle: pointer to wmi_handle 759 * @param pdev_id: host pdev_id to be converted. 760 * Return: target pdev_id after conversion. 761 */ 762 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 763 uint32_t pdev_id) 764 { 765 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 766 if (!wmi_handle->soc->is_pdev_is_map_enable) { 767 switch (pdev_id) { 768 case WMI_HOST_PDEV_ID_0: 769 return WMI_PDEV_ID_1ST; 770 case WMI_HOST_PDEV_ID_1: 771 return WMI_PDEV_ID_2ND; 772 case WMI_HOST_PDEV_ID_2: 773 return WMI_PDEV_ID_3RD; 774 } 775 } else { 776 return wmi_handle->cmd_pdev_id_map[pdev_id]; 777 } 778 } else { 779 return WMI_PDEV_ID_SOC; 780 } 781 782 QDF_ASSERT(0); 783 784 return WMI_PDEV_ID_SOC; 785 } 786 787 /** 788 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 789 * target to host defines. 790 * @wmi_handle: pointer to wmi_handle 791 * @param pdev_id: target pdev_id to be converted. 792 * Return: host pdev_id after conversion. 793 */ 794 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 795 uint32_t pdev_id) 796 { 797 798 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 799 if (!wmi_handle->soc->is_pdev_is_map_enable) { 800 switch (pdev_id) { 801 case WMI_PDEV_ID_1ST: 802 return WMI_HOST_PDEV_ID_0; 803 case WMI_PDEV_ID_2ND: 804 return WMI_HOST_PDEV_ID_1; 805 case WMI_PDEV_ID_3RD: 806 return WMI_HOST_PDEV_ID_2; 807 } 808 } else { 809 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 810 } 811 } else if (pdev_id == WMI_PDEV_ID_SOC) { 812 return WMI_HOST_PDEV_ID_SOC; 813 } else { 814 wmi_err("Invalid pdev_id"); 815 } 816 817 return WMI_HOST_PDEV_ID_INVALID; 818 } 819 820 /** 821 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 822 * host to target defines. 823 * @wmi_handle: pointer to wmi_handle 824 * @param phy_id: host pdev_id to be converted. 825 * Return: target phy_id after conversion. 826 */ 827 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 828 uint32_t phy_id) 829 { 830 if (!wmi_handle->soc->is_phy_id_map_enable || 831 phy_id >= WMI_MAX_RADIOS) { 832 return phy_id; 833 } 834 835 return wmi_handle->cmd_phy_id_map[phy_id]; 836 } 837 838 /** 839 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 840 * target to host defines. 841 * @wmi_handle: pointer to wmi_handle 842 * @param phy_id: target phy_id to be converted. 843 * Return: host phy_id after conversion. 844 */ 845 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 846 uint32_t phy_id) 847 { 848 if (!wmi_handle->soc->is_phy_id_map_enable || 849 phy_id >= WMI_MAX_RADIOS) { 850 return phy_id; 851 } 852 853 return wmi_handle->evt_phy_id_map[phy_id]; 854 } 855 856 /** 857 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 858 * 859 * Return None. 860 */ 861 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 862 uint32_t *pdev_id_map, 863 uint8_t size) 864 { 865 int i = 0; 866 867 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 868 for (i = 0; i < size; i++) { 869 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 870 wmi_handle->evt_pdev_id_map[i] = 871 WMI_HOST_PDEV_ID_INVALID; 872 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 873 wmi_handle->evt_phy_id_map[i] = 874 WMI_HOST_PDEV_ID_INVALID; 875 } 876 877 for (i = 0; i < size; i++) { 878 if (wmi_handle->cmd_pdev_id_map[i] != 879 WMI_HOST_PDEV_ID_INVALID) { 880 wmi_handle->evt_pdev_id_map 881 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 882 } 883 if (wmi_handle->cmd_phy_id_map[i] != 884 WMI_HOST_PDEV_ID_INVALID) { 885 wmi_handle->evt_phy_id_map 886 [wmi_handle->cmd_phy_id_map[i]] = i; 887 } 888 } 889 wmi_handle->soc->is_pdev_is_map_enable = true; 890 wmi_handle->soc->is_phy_id_map_enable = true; 891 } else { 892 wmi_handle->soc->is_pdev_is_map_enable = false; 893 wmi_handle->soc->is_phy_id_map_enable = false; 894 } 895 896 wmi_handle->ops->convert_pdev_id_host_to_target = 897 convert_host_pdev_id_to_target_pdev_id; 898 wmi_handle->ops->convert_pdev_id_target_to_host = 899 convert_target_pdev_id_to_host_pdev_id; 900 901 /* phy_id convert function assignments */ 902 wmi_handle->ops->convert_phy_id_host_to_target = 903 convert_host_phy_id_to_target_phy_id; 904 wmi_handle->ops->convert_phy_id_target_to_host = 905 convert_target_phy_id_to_host_phy_id; 906 } 907 908 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 909 * buffer. 910 * @wmi_handle: pointer to wmi_handle 911 * @cmd: pointer target vdev create command buffer 912 * @param: pointer host params for vdev create 913 * 914 * Return: None 915 */ 916 static inline void copy_vdev_create_pdev_id( 917 struct wmi_unified *wmi_handle, 918 wmi_vdev_create_cmd_fixed_param * cmd, 919 struct vdev_create_params *param) 920 { 921 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 922 wmi_handle, 923 param->pdev_id); 924 } 925 926 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 927 { 928 uint16_t mtrace_message_id; 929 930 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 931 (QDF_WMI_MTRACE_GRP_ID(message_id) << 932 QDF_WMI_MTRACE_CMD_NUM_BITS); 933 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 934 mtrace_message_id, vdev_id, data); 935 } 936 qdf_export_symbol(wmi_mtrace); 937 938 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 939 wmi_buf_t buf, 940 uint32_t buflen, uint32_t cmd_id, 941 bool is_qmi_send_support) 942 { 943 if (!is_qmi_send_support) 944 goto send_over_wmi; 945 946 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 947 goto send_over_wmi; 948 949 if (wmi_is_target_suspend_acked(wmi_handle)) { 950 if (QDF_IS_STATUS_SUCCESS( 951 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 952 buflen, cmd_id))) 953 return QDF_STATUS_SUCCESS; 954 } 955 956 send_over_wmi: 957 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 958 959 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 960 } 961 962 /** 963 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 964 * @wmi_handle: wmi handle 965 * @param: pointer to hold vdev create parameter 966 * @macaddr: vdev mac address 967 * 968 * Return: QDF_STATUS_SUCCESS for success or error code 969 */ 970 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 971 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 972 struct vdev_create_params *param) 973 { 974 wmi_vdev_create_cmd_fixed_param *cmd; 975 wmi_buf_t buf; 976 int32_t len = sizeof(*cmd); 977 QDF_STATUS ret; 978 int num_bands = 2; 979 uint8_t *buf_ptr; 980 wmi_vdev_txrx_streams *txrx_streams; 981 982 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 983 len += vdev_create_mlo_params_size(param); 984 985 buf = wmi_buf_alloc(wmi_handle, len); 986 if (!buf) 987 return QDF_STATUS_E_NOMEM; 988 989 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 990 WMITLV_SET_HDR(&cmd->tlv_header, 991 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 992 WMITLV_GET_STRUCT_TLVLEN 993 (wmi_vdev_create_cmd_fixed_param)); 994 cmd->vdev_id = param->vdev_id; 995 cmd->vdev_type = param->type; 996 cmd->vdev_subtype = param->subtype; 997 cmd->flags = param->mbssid_flags; 998 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 999 cmd->vdevid_trans = param->vdevid_trans; 1000 cmd->num_cfg_txrx_streams = num_bands; 1001 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 1002 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 1003 cmd->vdev_stats_id = param->vdev_stats_id; 1004 #endif 1005 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 1006 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 1007 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 1008 param->vdev_id, cmd->pdev_id, 1009 QDF_MAC_ADDR_REF(macaddr)); 1010 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 1011 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1012 (num_bands * sizeof(wmi_vdev_txrx_streams))); 1013 buf_ptr += WMI_TLV_HDR_SIZE; 1014 1015 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1016 param->type, param->subtype, 1017 param->nss_2g, param->nss_5g); 1018 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1019 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1020 txrx_streams->supported_tx_streams = param->nss_2g; 1021 txrx_streams->supported_rx_streams = param->nss_2g; 1022 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1023 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1024 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1025 1026 txrx_streams++; 1027 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1028 txrx_streams->supported_tx_streams = param->nss_5g; 1029 txrx_streams->supported_rx_streams = param->nss_5g; 1030 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1031 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1032 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1033 1034 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1035 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1036 1037 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1038 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1039 if (QDF_IS_STATUS_ERROR(ret)) { 1040 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1041 wmi_buf_free(buf); 1042 } 1043 1044 return ret; 1045 } 1046 1047 /** 1048 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1049 * @wmi_handle: wmi handle 1050 * @if_id: vdev id 1051 * 1052 * Return: QDF_STATUS_SUCCESS for success or error code 1053 */ 1054 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1055 uint8_t if_id) 1056 { 1057 wmi_vdev_delete_cmd_fixed_param *cmd; 1058 wmi_buf_t buf; 1059 QDF_STATUS ret; 1060 1061 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1062 if (!buf) 1063 return QDF_STATUS_E_NOMEM; 1064 1065 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1066 WMITLV_SET_HDR(&cmd->tlv_header, 1067 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1068 WMITLV_GET_STRUCT_TLVLEN 1069 (wmi_vdev_delete_cmd_fixed_param)); 1070 cmd->vdev_id = if_id; 1071 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1072 ret = wmi_unified_cmd_send(wmi_handle, buf, 1073 sizeof(wmi_vdev_delete_cmd_fixed_param), 1074 WMI_VDEV_DELETE_CMDID); 1075 if (QDF_IS_STATUS_ERROR(ret)) { 1076 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1077 wmi_buf_free(buf); 1078 } 1079 wmi_debug("vdev id = %d", if_id); 1080 1081 return ret; 1082 } 1083 1084 /** 1085 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1086 * @wmi_handle: wmi handle 1087 * @vdev_id: vdev id 1088 * @nss_chains_user_cfg: user configured nss chain params 1089 * 1090 * Return: QDF_STATUS_SUCCESS for success or error code 1091 */ 1092 static QDF_STATUS 1093 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1094 uint8_t vdev_id, 1095 struct vdev_nss_chains *user_cfg) 1096 { 1097 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1098 wmi_buf_t buf; 1099 QDF_STATUS ret; 1100 1101 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1102 if (!buf) 1103 return QDF_STATUS_E_NOMEM; 1104 1105 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1106 WMITLV_SET_HDR(&cmd->tlv_header, 1107 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1108 WMITLV_GET_STRUCT_TLVLEN 1109 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1110 cmd->vdev_id = vdev_id; 1111 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1112 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1113 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1114 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1115 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1116 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1117 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1118 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1119 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1120 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1121 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1122 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1123 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1124 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1125 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1126 1127 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1128 ret = wmi_unified_cmd_send(wmi_handle, buf, 1129 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1130 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1131 if (QDF_IS_STATUS_ERROR(ret)) { 1132 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1133 wmi_buf_free(buf); 1134 } 1135 wmi_debug("vdev_id %d", vdev_id); 1136 1137 return ret; 1138 } 1139 1140 /** 1141 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1142 * @wmi: wmi handle 1143 * @vdev_id: vdev id 1144 * 1145 * Return: QDF_STATUS_SUCCESS for success or error code 1146 */ 1147 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1148 uint8_t vdev_id) 1149 { 1150 wmi_vdev_stop_cmd_fixed_param *cmd; 1151 wmi_buf_t buf; 1152 int32_t len = sizeof(*cmd); 1153 1154 buf = wmi_buf_alloc(wmi, len); 1155 if (!buf) 1156 return QDF_STATUS_E_NOMEM; 1157 1158 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 1159 WMITLV_SET_HDR(&cmd->tlv_header, 1160 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1161 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1162 cmd->vdev_id = vdev_id; 1163 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1164 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1165 wmi_err("Failed to send vdev stop command"); 1166 wmi_buf_free(buf); 1167 return QDF_STATUS_E_FAILURE; 1168 } 1169 wmi_debug("vdev id = %d", vdev_id); 1170 1171 return 0; 1172 } 1173 1174 /** 1175 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1176 * @wmi: wmi handle 1177 * @vdev_id: vdev id 1178 * 1179 * Return: QDF_STATUS_SUCCESS for success or error code 1180 */ 1181 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1182 { 1183 wmi_vdev_down_cmd_fixed_param *cmd; 1184 wmi_buf_t buf; 1185 int32_t len = sizeof(*cmd); 1186 1187 buf = wmi_buf_alloc(wmi, len); 1188 if (!buf) 1189 return QDF_STATUS_E_NOMEM; 1190 1191 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1192 WMITLV_SET_HDR(&cmd->tlv_header, 1193 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1194 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1195 cmd->vdev_id = vdev_id; 1196 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1197 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1198 wmi_err("Failed to send vdev down"); 1199 wmi_buf_free(buf); 1200 return QDF_STATUS_E_FAILURE; 1201 } 1202 wmi_debug("vdev_id %d", vdev_id); 1203 1204 return 0; 1205 } 1206 1207 static inline void copy_channel_info( 1208 wmi_vdev_start_request_cmd_fixed_param * cmd, 1209 wmi_channel *chan, 1210 struct vdev_start_params *req) 1211 { 1212 chan->mhz = req->channel.mhz; 1213 1214 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1215 1216 chan->band_center_freq1 = req->channel.cfreq1; 1217 chan->band_center_freq2 = req->channel.cfreq2; 1218 1219 if (req->channel.half_rate) 1220 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1221 else if (req->channel.quarter_rate) 1222 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1223 1224 if (req->channel.dfs_set) { 1225 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1226 cmd->disable_hw_ack = req->disable_hw_ack; 1227 } 1228 1229 if (req->channel.dfs_set_cfreq2) 1230 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1231 1232 if (req->channel.is_stadfs_en) 1233 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1234 1235 /* According to firmware both reg power and max tx power 1236 * on set channel power is used and set it to max reg 1237 * power from regulatory. 1238 */ 1239 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1240 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1241 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1242 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1243 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1244 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1245 1246 } 1247 1248 /** 1249 * vdev_start_cmd_fill_11be() - 11be information filling in vdev_start 1250 * @cmd: wmi cmd 1251 * @req: vdev start params 1252 * 1253 * Return: QDF status 1254 */ 1255 #ifdef WLAN_FEATURE_11BE 1256 static void 1257 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1258 struct vdev_start_params *req) 1259 { 1260 cmd->eht_ops = req->eht_ops; 1261 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1262 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1263 req->eht_ops, req->channel.puncture_bitmap, 1264 cmd->puncture_20mhz_bitmap); 1265 } 1266 #else 1267 static void 1268 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1269 struct vdev_start_params *req) 1270 { 1271 } 1272 #endif 1273 1274 /** 1275 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1276 * @wmi_handle: wmi handle 1277 * @req: vdev start params 1278 * 1279 * Return: QDF status 1280 */ 1281 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1282 struct vdev_start_params *req) 1283 { 1284 wmi_vdev_start_request_cmd_fixed_param *cmd; 1285 wmi_buf_t buf; 1286 wmi_channel *chan; 1287 int32_t len, ret; 1288 uint8_t *buf_ptr; 1289 1290 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1291 if (!req->is_restart) 1292 len += vdev_start_mlo_params_size(req); 1293 buf = wmi_buf_alloc(wmi_handle, len); 1294 if (!buf) 1295 return QDF_STATUS_E_NOMEM; 1296 1297 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1298 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1299 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1300 WMITLV_SET_HDR(&cmd->tlv_header, 1301 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1302 WMITLV_GET_STRUCT_TLVLEN 1303 (wmi_vdev_start_request_cmd_fixed_param)); 1304 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1305 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1306 cmd->vdev_id = req->vdev_id; 1307 1308 /* Fill channel info */ 1309 copy_channel_info(cmd, chan, req); 1310 cmd->beacon_interval = req->beacon_interval; 1311 cmd->dtim_period = req->dtim_period; 1312 1313 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1314 if (req->bcn_tx_rate_code) 1315 wmi_enable_bcn_ratecode(&cmd->flags); 1316 1317 if (!req->is_restart) { 1318 if (req->pmf_enabled) 1319 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1320 1321 cmd->mbss_capability_flags = req->mbssid_flags; 1322 cmd->vdevid_trans = req->vdevid_trans; 1323 } 1324 1325 /* Copy the SSID */ 1326 if (req->ssid.length) { 1327 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1328 cmd->ssid.ssid_len = req->ssid.length; 1329 else 1330 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1331 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1332 cmd->ssid.ssid_len); 1333 } 1334 1335 if (req->hidden_ssid) 1336 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1337 1338 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1339 cmd->num_noa_descriptors = req->num_noa_descriptors; 1340 cmd->preferred_rx_streams = req->preferred_rx_streams; 1341 cmd->preferred_tx_streams = req->preferred_tx_streams; 1342 cmd->cac_duration_ms = req->cac_duration_ms; 1343 cmd->regdomain = req->regdomain; 1344 cmd->he_ops = req->he_ops; 1345 1346 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1347 sizeof(wmi_channel)); 1348 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1349 cmd->num_noa_descriptors * 1350 sizeof(wmi_p2p_noa_descriptor)); 1351 if (!req->is_restart) { 1352 buf_ptr += WMI_TLV_HDR_SIZE + 1353 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1354 1355 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1356 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1357 } 1358 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1359 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1360 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1361 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1362 "req->dis_hw_ack: %d ", req->vdev_id, 1363 chan->mhz, req->channel.phy_mode, chan->info, 1364 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1365 chan->band_center_freq1, chan->band_center_freq2, 1366 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1367 req->preferred_tx_streams, req->preferred_rx_streams, 1368 req->ldpc_rx_enabled, req->cac_duration_ms, 1369 req->regdomain, req->he_ops, 1370 req->disable_hw_ack); 1371 1372 vdev_start_cmd_fill_11be(cmd, req); 1373 1374 if (req->is_restart) { 1375 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1376 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1377 WMI_VDEV_RESTART_REQUEST_CMDID); 1378 } else { 1379 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1380 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1381 WMI_VDEV_START_REQUEST_CMDID); 1382 } 1383 if (ret) { 1384 wmi_err("Failed to send vdev start command"); 1385 wmi_buf_free(buf); 1386 return QDF_STATUS_E_FAILURE; 1387 } 1388 1389 return QDF_STATUS_SUCCESS; 1390 } 1391 1392 /** 1393 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1394 * @wmi: wmi handle 1395 * @peer_addr: peer mac address 1396 * @param: pointer to hold peer flush tid parameter 1397 * 1398 * Return: 0 for success or error code 1399 */ 1400 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1401 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1402 struct peer_flush_params *param) 1403 { 1404 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1405 wmi_buf_t buf; 1406 int32_t len = sizeof(*cmd); 1407 1408 buf = wmi_buf_alloc(wmi, len); 1409 if (!buf) 1410 return QDF_STATUS_E_NOMEM; 1411 1412 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1413 WMITLV_SET_HDR(&cmd->tlv_header, 1414 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1415 WMITLV_GET_STRUCT_TLVLEN 1416 (wmi_peer_flush_tids_cmd_fixed_param)); 1417 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1418 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1419 cmd->vdev_id = param->vdev_id; 1420 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1421 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1422 param->peer_tid_bitmap); 1423 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1424 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1425 wmi_err("Failed to send flush tid command"); 1426 wmi_buf_free(buf); 1427 return QDF_STATUS_E_FAILURE; 1428 } 1429 1430 return 0; 1431 } 1432 1433 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1434 /** 1435 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1436 * @policy: The target i/f flush policy value 1437 * 1438 * Return: WMI layer flush policy 1439 */ 1440 static wmi_peer_flush_policy 1441 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1442 { 1443 switch (policy) { 1444 case PEER_TXQ_FLUSH_POLICY_NONE: 1445 return WMI_NO_FLUSH; 1446 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1447 return WMI_TWT_FLUSH; 1448 default: 1449 return WMI_MAX_FLUSH_POLICY; 1450 } 1451 } 1452 1453 /** 1454 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1455 * @wmi: wmi handle 1456 * @para: Peer txq flush configuration 1457 * 1458 * Return: QDF status 1459 */ 1460 static QDF_STATUS 1461 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1462 struct peer_txq_flush_config_params *param) 1463 { 1464 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1465 wmi_buf_t buf; 1466 int32_t len = sizeof(*cmd); 1467 1468 buf = wmi_buf_alloc(wmi, len); 1469 if (!buf) 1470 return QDF_STATUS_E_NOMEM; 1471 1472 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1473 1474 WMITLV_SET_HDR(&cmd->tlv_header, 1475 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1476 WMITLV_GET_STRUCT_TLVLEN 1477 (wmi_peer_flush_policy_cmd_fixed_param)); 1478 1479 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1480 cmd->peer_tid_bitmap = param->tid_mask; 1481 cmd->vdev_id = param->vdev_id; 1482 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1483 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1484 wmi_buf_free(buf); 1485 wmi_err("Invalid policy"); 1486 return QDF_STATUS_E_INVAL; 1487 } 1488 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1489 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1490 param->tid_mask, param->policy); 1491 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1492 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1493 wmi_err("Failed to send flush policy command"); 1494 wmi_buf_free(buf); 1495 return QDF_STATUS_E_FAILURE; 1496 } 1497 1498 return QDF_STATUS_SUCCESS; 1499 } 1500 #endif 1501 /** 1502 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1503 * @wmi: wmi handle 1504 * @peer_addr: peer mac addr 1505 * @param: peer delete parameters 1506 * 1507 * Return: QDF_STATUS_SUCCESS for success or error code 1508 */ 1509 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1510 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1511 struct peer_delete_cmd_params *param) 1512 { 1513 wmi_peer_delete_cmd_fixed_param *cmd; 1514 wmi_buf_t buf; 1515 int32_t len = sizeof(*cmd); 1516 uint8_t *buf_ptr; 1517 1518 len += peer_delete_mlo_params_size(param); 1519 buf = wmi_buf_alloc(wmi, len); 1520 if (!buf) 1521 return QDF_STATUS_E_NOMEM; 1522 1523 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1524 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1525 WMITLV_SET_HDR(&cmd->tlv_header, 1526 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1527 WMITLV_GET_STRUCT_TLVLEN 1528 (wmi_peer_delete_cmd_fixed_param)); 1529 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1530 cmd->vdev_id = param->vdev_id; 1531 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1532 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1533 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1534 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1535 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1536 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1537 wmi_err("Failed to send peer delete command"); 1538 wmi_buf_free(buf); 1539 return QDF_STATUS_E_FAILURE; 1540 } 1541 return 0; 1542 } 1543 1544 static void 1545 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1546 { 1547 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1548 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1549 WMI_PEER_TYPE_DEFAULT); 1550 1551 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1552 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1553 WMI_PEER_TYPE_BSS); 1554 1555 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1556 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1557 WMI_PEER_TYPE_TDLS); 1558 1559 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1560 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1561 WMI_PEER_TYPE_NAN_DATA); 1562 1563 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1564 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1565 WMI_PEER_TYPE_PASN); 1566 } 1567 1568 /** 1569 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1570 * @wmi: wmi handle 1571 * @param: pointer to hold peer delete all parameter 1572 * 1573 * Return: QDF_STATUS_SUCCESS for success or error code 1574 */ 1575 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1576 wmi_unified_t wmi, 1577 struct peer_delete_all_params *param) 1578 { 1579 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1580 wmi_buf_t buf; 1581 int32_t len = sizeof(*cmd); 1582 1583 buf = wmi_buf_alloc(wmi, len); 1584 if (!buf) 1585 return QDF_STATUS_E_NOMEM; 1586 1587 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1588 WMITLV_SET_HDR( 1589 &cmd->tlv_header, 1590 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1591 WMITLV_GET_STRUCT_TLVLEN 1592 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1593 cmd->vdev_id = param->vdev_id; 1594 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1595 cmd->peer_type_bitmap); 1596 1597 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1598 param->peer_type_bitmap); 1599 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1600 if (wmi_unified_cmd_send(wmi, buf, len, 1601 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1602 wmi_err("Failed to send peer del all command"); 1603 wmi_buf_free(buf); 1604 return QDF_STATUS_E_FAILURE; 1605 } 1606 1607 return QDF_STATUS_SUCCESS; 1608 } 1609 1610 /** 1611 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1612 * to target id. 1613 * @peer_param_id: host param id. 1614 * 1615 * Return: Target param id. 1616 */ 1617 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1618 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1619 uint32_t peer_param_id) 1620 { 1621 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1622 return peer_param_tlv[peer_param_id]; 1623 return WMI_UNAVAILABLE_PARAM; 1624 } 1625 #else 1626 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1627 uint32_t peer_param_id) 1628 { 1629 return peer_param_id; 1630 } 1631 #endif 1632 1633 /** 1634 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1635 * wmi_channel_width 1636 * @bw: wmi_host_channel_width channel width 1637 * 1638 * Return: wmi_channel_width 1639 */ 1640 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1641 wmi_host_channel_width bw) 1642 { 1643 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1644 1645 switch (bw) { 1646 case WMI_HOST_CHAN_WIDTH_20: 1647 target_bw = WMI_CHAN_WIDTH_20; 1648 break; 1649 case WMI_HOST_CHAN_WIDTH_40: 1650 target_bw = WMI_CHAN_WIDTH_40; 1651 break; 1652 case WMI_HOST_CHAN_WIDTH_80: 1653 target_bw = WMI_CHAN_WIDTH_80; 1654 break; 1655 case WMI_HOST_CHAN_WIDTH_160: 1656 target_bw = WMI_CHAN_WIDTH_160; 1657 break; 1658 case WMI_HOST_CHAN_WIDTH_80P80: 1659 target_bw = WMI_CHAN_WIDTH_80P80; 1660 break; 1661 case WMI_HOST_CHAN_WIDTH_5: 1662 target_bw = WMI_CHAN_WIDTH_5; 1663 break; 1664 case WMI_HOST_CHAN_WIDTH_10: 1665 target_bw = WMI_CHAN_WIDTH_10; 1666 break; 1667 case WMI_HOST_CHAN_WIDTH_165: 1668 target_bw = WMI_CHAN_WIDTH_165; 1669 break; 1670 case WMI_HOST_CHAN_WIDTH_160P160: 1671 target_bw = WMI_CHAN_WIDTH_160P160; 1672 break; 1673 case WMI_HOST_CHAN_WIDTH_320: 1674 target_bw = WMI_CHAN_WIDTH_320; 1675 break; 1676 default: 1677 break; 1678 } 1679 1680 return target_bw; 1681 } 1682 1683 /** 1684 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1685 * param value to target 1686 * @param_id: target param id 1687 * @param_value: host param value 1688 * 1689 * @Return: target param value 1690 */ 1691 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1692 uint32_t param_id, uint32_t param_value) 1693 { 1694 uint32_t fw_param_value = 0; 1695 wmi_host_channel_width bw; 1696 uint16_t punc; 1697 1698 switch (param_id) { 1699 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1700 bw = QDF_GET_BITS(param_value, 0, 8); 1701 punc = QDF_GET_BITS(param_value, 8, 16); 1702 QDF_SET_BITS(fw_param_value, 0, 8, 1703 wmi_host_chan_bw_to_target_chan_bw(bw)); 1704 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1705 break; 1706 default: 1707 fw_param_value = param_value; 1708 break; 1709 } 1710 1711 return fw_param_value; 1712 } 1713 1714 #ifdef WLAN_SUPPORT_PPEDS 1715 /** 1716 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1717 * @wmi: wmi handle 1718 * @param: pointer to hold PPE DS config 1719 * 1720 * Return: QDF_STATUS_SUCCESS for success or error code 1721 */ 1722 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1723 struct peer_ppe_ds_param *param) 1724 { 1725 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1726 wmi_buf_t buf; 1727 int32_t err; 1728 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1729 1730 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1731 if (!buf) 1732 return QDF_STATUS_E_NOMEM; 1733 1734 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1735 WMITLV_SET_HDR(&cmd->tlv_header, 1736 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1737 WMITLV_GET_STRUCT_TLVLEN 1738 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1739 1740 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1741 1742 if (param->ppe_routing_enabled) 1743 cmd->ppe_routing_enable = param->use_ppe ? 1744 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1745 else 1746 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1747 1748 cmd->service_code = param->service_code; 1749 cmd->priority_valid = param->priority_valid; 1750 cmd->src_info = param->src_info; 1751 cmd->vdev_id = param->vdev_id; 1752 1753 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1754 "ppe_routing_enable: %u service_code: %u\n" 1755 "priority_valid:%d src_info:%u", 1756 param->vdev_id, 1757 QDF_MAC_ADDR_REF(param->peer_macaddr), 1758 param->ppe_routing_enabled, 1759 param->service_code, 1760 param->priority_valid, 1761 param->src_info); 1762 1763 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1764 err = wmi_unified_cmd_send(wmi, buf, 1765 len, 1766 WMI_PEER_CONFIG_PPE_DS_CMDID); 1767 if (err) { 1768 wmi_err("Failed to send ppeds config cmd"); 1769 wmi_buf_free(buf); 1770 return QDF_STATUS_E_FAILURE; 1771 } 1772 1773 return 0; 1774 } 1775 #endif /* WLAN_SUPPORT_PPEDS */ 1776 1777 /** 1778 * send_peer_param_cmd_tlv() - set peer parameter in fw 1779 * @wmi: wmi handle 1780 * @peer_addr: peer mac address 1781 * @param : pointer to hold peer set parameter 1782 * 1783 * Return: QDF_STATUS_SUCCESS for success or error code 1784 */ 1785 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1786 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1787 struct peer_set_params *param) 1788 { 1789 wmi_peer_set_param_cmd_fixed_param *cmd; 1790 wmi_buf_t buf; 1791 int32_t err; 1792 uint32_t param_id; 1793 uint32_t param_value; 1794 1795 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1796 if (param_id == WMI_UNAVAILABLE_PARAM) { 1797 wmi_err("Unavailable param %d", param->param_id); 1798 return QDF_STATUS_E_NOSUPPORT; 1799 } 1800 param_value = convert_host_peer_param_value_to_target_value_tlv( 1801 param_id, param->param_value); 1802 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1803 if (!buf) 1804 return QDF_STATUS_E_NOMEM; 1805 1806 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1807 WMITLV_SET_HDR(&cmd->tlv_header, 1808 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1809 WMITLV_GET_STRUCT_TLVLEN 1810 (wmi_peer_set_param_cmd_fixed_param)); 1811 cmd->vdev_id = param->vdev_id; 1812 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1813 cmd->param_id = param_id; 1814 cmd->param_value = param_value; 1815 1816 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1817 cmd->vdev_id, 1818 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1819 cmd->param_value); 1820 1821 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1822 err = wmi_unified_cmd_send(wmi, buf, 1823 sizeof(wmi_peer_set_param_cmd_fixed_param), 1824 WMI_PEER_SET_PARAM_CMDID); 1825 if (err) { 1826 wmi_err("Failed to send set_param cmd"); 1827 wmi_buf_free(buf); 1828 return QDF_STATUS_E_FAILURE; 1829 } 1830 1831 return 0; 1832 } 1833 1834 /** 1835 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1836 * @wmi: wmi handle 1837 * @bssid: bssid 1838 * @vdev_up_params: pointer to hold vdev up parameter 1839 * 1840 * Return: QDF_STATUS_SUCCESS for success or error code 1841 */ 1842 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1843 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1844 struct vdev_up_params *params) 1845 { 1846 wmi_vdev_up_cmd_fixed_param *cmd; 1847 wmi_buf_t buf; 1848 int32_t len = sizeof(*cmd); 1849 1850 wmi_debug("VDEV_UP"); 1851 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1852 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1853 buf = wmi_buf_alloc(wmi, len); 1854 if (!buf) 1855 return QDF_STATUS_E_NOMEM; 1856 1857 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1858 WMITLV_SET_HDR(&cmd->tlv_header, 1859 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1860 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1861 cmd->vdev_id = params->vdev_id; 1862 cmd->vdev_assoc_id = params->assoc_id; 1863 cmd->profile_idx = params->profile_idx; 1864 cmd->profile_num = params->profile_num; 1865 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1866 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1867 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1868 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1869 wmi_err("Failed to send vdev up command"); 1870 wmi_buf_free(buf); 1871 return QDF_STATUS_E_FAILURE; 1872 } 1873 1874 return 0; 1875 } 1876 1877 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1878 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1879 { 1880 /* Host sets the peer_type as 0 for the peer create command sent to FW 1881 * other than PASN peer create command. 1882 */ 1883 if (peer_type == WLAN_PEER_RTT_PASN) 1884 return WMI_PEER_TYPE_PASN; 1885 1886 return peer_type; 1887 } 1888 #else 1889 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1890 { 1891 return peer_type; 1892 } 1893 #endif 1894 /** 1895 * send_peer_create_cmd_tlv() - send peer create command to fw 1896 * @wmi: wmi handle 1897 * @peer_addr: peer mac address 1898 * @peer_type: peer type 1899 * @vdev_id: vdev id 1900 * 1901 * Return: QDF_STATUS_SUCCESS for success or error code 1902 */ 1903 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1904 struct peer_create_params *param) 1905 { 1906 wmi_peer_create_cmd_fixed_param *cmd; 1907 wmi_buf_t buf; 1908 uint8_t *buf_ptr; 1909 int32_t len = sizeof(*cmd); 1910 1911 len += peer_create_mlo_params_size(param); 1912 buf = wmi_buf_alloc(wmi, len); 1913 if (!buf) 1914 return QDF_STATUS_E_NOMEM; 1915 1916 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1917 WMITLV_SET_HDR(&cmd->tlv_header, 1918 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1919 WMITLV_GET_STRUCT_TLVLEN 1920 (wmi_peer_create_cmd_fixed_param)); 1921 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1922 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1923 cmd->vdev_id = param->vdev_id; 1924 1925 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1926 buf_ptr += sizeof(*cmd); 1927 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1928 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1929 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1930 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1931 wmi_buf_free(buf); 1932 return QDF_STATUS_E_FAILURE; 1933 } 1934 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1935 QDF_MAC_ADDR_REF(param->peer_addr), 1936 param->vdev_id); 1937 1938 return 0; 1939 } 1940 1941 /** 1942 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1943 * command to fw 1944 * @wmi: wmi handle 1945 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1946 * 1947 * Return: 0 for success or error code 1948 */ 1949 static 1950 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1951 struct rx_reorder_queue_setup_params *param) 1952 { 1953 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1954 wmi_buf_t buf; 1955 int32_t len = sizeof(*cmd); 1956 1957 buf = wmi_buf_alloc(wmi, len); 1958 if (!buf) 1959 return QDF_STATUS_E_NOMEM; 1960 1961 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1962 WMITLV_SET_HDR(&cmd->tlv_header, 1963 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1964 WMITLV_GET_STRUCT_TLVLEN 1965 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1966 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1967 cmd->vdev_id = param->vdev_id; 1968 cmd->tid = param->tid; 1969 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1970 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1971 cmd->queue_no = param->queue_no; 1972 cmd->ba_window_size_valid = param->ba_window_size_valid; 1973 cmd->ba_window_size = param->ba_window_size; 1974 1975 1976 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1977 if (wmi_unified_cmd_send(wmi, buf, len, 1978 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1979 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1980 wmi_buf_free(buf); 1981 return QDF_STATUS_E_FAILURE; 1982 } 1983 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1984 QDF_MAC_ADDR_REF(param->peer_macaddr), 1985 param->vdev_id, param->tid); 1986 1987 return QDF_STATUS_SUCCESS; 1988 } 1989 1990 /** 1991 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1992 * command to fw 1993 * @wmi: wmi handle 1994 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1995 * 1996 * Return: 0 for success or error code 1997 */ 1998 static 1999 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 2000 struct rx_reorder_queue_remove_params *param) 2001 { 2002 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 2003 wmi_buf_t buf; 2004 int32_t len = sizeof(*cmd); 2005 2006 buf = wmi_buf_alloc(wmi, len); 2007 if (!buf) 2008 return QDF_STATUS_E_NOMEM; 2009 2010 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 2011 wmi_buf_data(buf); 2012 WMITLV_SET_HDR(&cmd->tlv_header, 2013 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2014 WMITLV_GET_STRUCT_TLVLEN 2015 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2016 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2017 cmd->vdev_id = param->vdev_id; 2018 cmd->tid_mask = param->peer_tid_bitmap; 2019 2020 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2021 if (wmi_unified_cmd_send(wmi, buf, len, 2022 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2023 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2024 wmi_buf_free(buf); 2025 return QDF_STATUS_E_FAILURE; 2026 } 2027 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2028 QDF_MAC_ADDR_REF(param->peer_macaddr), 2029 param->vdev_id, param->peer_tid_bitmap); 2030 2031 return QDF_STATUS_SUCCESS; 2032 } 2033 2034 #ifdef WLAN_SUPPORT_GREEN_AP 2035 /** 2036 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2037 * @wmi_handle: wmi handle 2038 * @value: value 2039 * @pdev_id: pdev id to have radio context 2040 * 2041 * Return: QDF_STATUS_SUCCESS for success or error code 2042 */ 2043 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2044 uint32_t value, uint8_t pdev_id) 2045 { 2046 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2047 wmi_buf_t buf; 2048 int32_t len = sizeof(*cmd); 2049 2050 wmi_debug("Set Green AP PS val %d", value); 2051 2052 buf = wmi_buf_alloc(wmi_handle, len); 2053 if (!buf) 2054 return QDF_STATUS_E_NOMEM; 2055 2056 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2057 WMITLV_SET_HDR(&cmd->tlv_header, 2058 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2059 WMITLV_GET_STRUCT_TLVLEN 2060 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2061 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2062 wmi_handle, 2063 pdev_id); 2064 cmd->enable = value; 2065 2066 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2067 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2068 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2069 wmi_err("Set Green AP PS param Failed val %d", value); 2070 wmi_buf_free(buf); 2071 return QDF_STATUS_E_FAILURE; 2072 } 2073 2074 return 0; 2075 } 2076 #endif 2077 2078 /** 2079 * send_pdev_utf_cmd_tlv() - send utf command to fw 2080 * @wmi_handle: wmi handle 2081 * @param: pointer to pdev_utf_params 2082 * @mac_id: mac id to have radio context 2083 * 2084 * Return: QDF_STATUS_SUCCESS for success or error code 2085 */ 2086 static QDF_STATUS 2087 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2088 struct pdev_utf_params *param, 2089 uint8_t mac_id) 2090 { 2091 wmi_buf_t buf; 2092 uint8_t *cmd; 2093 /* if param->len is 0 no data is sent, return error */ 2094 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2095 static uint8_t msgref = 1; 2096 uint8_t segNumber = 0, segInfo, numSegments; 2097 uint16_t chunk_len, total_bytes; 2098 uint8_t *bufpos; 2099 struct seg_hdr_info segHdrInfo; 2100 2101 bufpos = param->utf_payload; 2102 total_bytes = param->len; 2103 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2104 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2105 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2106 2107 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2108 numSegments++; 2109 2110 while (param->len) { 2111 if (param->len > MAX_WMI_UTF_LEN) 2112 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2113 else 2114 chunk_len = param->len; 2115 2116 buf = wmi_buf_alloc(wmi_handle, 2117 (chunk_len + sizeof(segHdrInfo) + 2118 WMI_TLV_HDR_SIZE)); 2119 if (!buf) 2120 return QDF_STATUS_E_NOMEM; 2121 2122 cmd = (uint8_t *) wmi_buf_data(buf); 2123 2124 segHdrInfo.len = total_bytes; 2125 segHdrInfo.msgref = msgref; 2126 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2127 segHdrInfo.segmentInfo = segInfo; 2128 segHdrInfo.pad = 0; 2129 2130 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 2131 " segHdrInfo.segmentInfo = %d", 2132 segHdrInfo.len, segHdrInfo.msgref, 2133 segHdrInfo.segmentInfo); 2134 2135 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 2136 " chunk len %d", total_bytes, segNumber, 2137 numSegments, chunk_len); 2138 2139 segNumber++; 2140 2141 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2142 (chunk_len + sizeof(segHdrInfo))); 2143 cmd += WMI_TLV_HDR_SIZE; 2144 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 2145 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 2146 bufpos, chunk_len); 2147 2148 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2149 ret = wmi_unified_cmd_send(wmi_handle, buf, 2150 (chunk_len + sizeof(segHdrInfo) + 2151 WMI_TLV_HDR_SIZE), 2152 WMI_PDEV_UTF_CMDID); 2153 2154 if (QDF_IS_STATUS_ERROR(ret)) { 2155 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2156 wmi_buf_free(buf); 2157 break; 2158 } 2159 2160 param->len -= chunk_len; 2161 bufpos += chunk_len; 2162 } 2163 2164 msgref++; 2165 2166 return ret; 2167 } 2168 2169 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2170 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2171 { 2172 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2173 return pdev_param_tlv[host_param]; 2174 return WMI_UNAVAILABLE_PARAM; 2175 } 2176 2177 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2178 { 2179 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2180 return vdev_param_tlv[host_param]; 2181 return WMI_UNAVAILABLE_PARAM; 2182 } 2183 #else 2184 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2185 { 2186 return host_param; 2187 } 2188 2189 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2190 { 2191 return host_param; 2192 } 2193 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2194 2195 /** 2196 * send_pdev_param_cmd_tlv() - set pdev parameters 2197 * @wmi_handle: wmi handle 2198 * @param: pointer to pdev parameter 2199 * @mac_id: radio context 2200 * 2201 * Return: 0 on success, errno on failure 2202 */ 2203 static QDF_STATUS 2204 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2205 struct pdev_params *param, 2206 uint8_t mac_id) 2207 { 2208 QDF_STATUS ret; 2209 wmi_pdev_set_param_cmd_fixed_param *cmd; 2210 wmi_buf_t buf; 2211 uint16_t len = sizeof(*cmd); 2212 uint32_t pdev_param; 2213 2214 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2215 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2216 wmi_err("Unavailable param %d", param->param_id); 2217 return QDF_STATUS_E_INVAL; 2218 } 2219 2220 buf = wmi_buf_alloc(wmi_handle, len); 2221 if (!buf) 2222 return QDF_STATUS_E_NOMEM; 2223 2224 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2225 WMITLV_SET_HDR(&cmd->tlv_header, 2226 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2227 WMITLV_GET_STRUCT_TLVLEN 2228 (wmi_pdev_set_param_cmd_fixed_param)); 2229 if (param->is_host_pdev_id) 2230 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2231 wmi_handle, 2232 mac_id); 2233 else 2234 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2235 wmi_handle, 2236 mac_id); 2237 cmd->param_id = pdev_param; 2238 cmd->param_value = param->param_value; 2239 wmi_debug("Setting pdev %d param = %x, value = %u", cmd->pdev_id, 2240 cmd->param_id, cmd->param_value); 2241 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2242 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2243 WMI_PDEV_SET_PARAM_CMDID); 2244 if (QDF_IS_STATUS_ERROR(ret)) { 2245 wmi_err("Failed to send set param command ret = %d", ret); 2246 wmi_buf_free(buf); 2247 } 2248 return ret; 2249 } 2250 2251 /** 2252 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2253 * @wmi_handle: wmi handle 2254 * @params: pointer to hold set_multiple_pdev_vdev_param info 2255 * 2256 * Return: 0 on success, errno on failure 2257 */ 2258 static QDF_STATUS 2259 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2260 struct set_multiple_pdev_vdev_param *params) 2261 { 2262 uint8_t index; 2263 struct pdev_params pdevparam; 2264 uint8_t n_params = params->n_params; 2265 2266 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2267 for (index = 0; index < n_params; index++) { 2268 pdevparam.param_id = params->params[index].param_id; 2269 pdevparam.param_value = params->params[index].param_value; 2270 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2271 &pdevparam, 2272 params->dev_id))) { 2273 wmi_err("failed to send pdev setparam:%d", 2274 pdevparam.param_id); 2275 return QDF_STATUS_E_FAILURE; 2276 } 2277 } 2278 return QDF_STATUS_SUCCESS; 2279 } 2280 2281 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2282 2283 /** 2284 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2285 * @params: pointer to point set_multiple_pdev_vdev_param info 2286 * 2287 * Return: returns QDF_STATUS 2288 */ 2289 static QDF_STATUS 2290 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2291 { 2292 uint8_t index; 2293 uint32_t dev_paramid; 2294 uint8_t num = params->n_params; 2295 2296 if (params->param_type == MLME_PDEV_SETPARAM) { 2297 for (index = 0; index < num; index++) { 2298 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2299 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2300 wmi_err("pdev param %d not available", 2301 params->params[index].param_id); 2302 return QDF_STATUS_E_INVAL; 2303 } 2304 params->params[index].param_id = dev_paramid; 2305 } 2306 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2307 for (index = 0; index < num; index++) { 2308 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2309 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2310 wmi_err("vdev param %d not available", 2311 params->params[index].param_id); 2312 return QDF_STATUS_E_INVAL; 2313 } 2314 params->params[index].param_id = dev_paramid; 2315 } 2316 } else { 2317 wmi_err("invalid param type"); 2318 return QDF_STATUS_E_INVAL; 2319 } 2320 return QDF_STATUS_SUCCESS; 2321 } 2322 2323 /** 2324 * send_dev_multi_setparam_cmd_tlv()-to print the paramid and param value 2325 * @setparam: buffer pointer where host is filling paramsid and value 2326 * @params: pointer to hold set_multiple_pdev_vdev_param info 2327 * 2328 */ 2329 static void send_dev_multi_setparam_cmd_tlv(wmi_set_param_info *setparam, 2330 struct set_multiple_pdev_vdev_param *params) 2331 { 2332 if (params->param_type == MLME_VDEV_SETPARAM) { 2333 wmi_debug("Setting vdev %d param = %x value = %u", params->dev_id, 2334 setparam->param_id, setparam->param_value); 2335 } else { 2336 wmi_debug("Setting pdev %d param = %x value = %u", 2337 params->dev_id, setparam->param_id, setparam->param_value); 2338 } 2339 } 2340 2341 /** 2342 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2343 * @wmi_handle: wmi handle 2344 * @params: pointer to hold set_multiple_pdev_vdev_param info 2345 * 2346 * Return: returns QDF_STATUS 2347 */ 2348 static QDF_STATUS 2349 send_multi_pdev_vdev_set_param_cmd_tlv( 2350 wmi_unified_t wmi_handle, 2351 struct set_multiple_pdev_vdev_param *params) 2352 { 2353 uint8_t *buf_ptr; 2354 QDF_STATUS ret; 2355 wmi_buf_t buf; 2356 wmi_set_param_info *setparam; 2357 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2358 uint8_t num = params->n_params; 2359 uint16_t len; 2360 uint8_t index = 0; 2361 2362 if (convert_host_pdev_vdev_param_id_to_target(params)) 2363 return QDF_STATUS_E_INVAL; 2364 2365 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2366 buf = wmi_buf_alloc(wmi_handle, len); 2367 if (!buf) 2368 return QDF_STATUS_E_NOMEM; 2369 2370 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2371 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2372 2373 WMITLV_SET_HDR(&cmd->tlv_header, 2374 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2375 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2376 2377 cmd->is_vdev = params->param_type; 2378 if (params->param_type == MLME_PDEV_SETPARAM) { 2379 if (params->is_host_pdev_id) 2380 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2381 params->dev_id); 2382 else 2383 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2384 params->dev_id); 2385 } 2386 cmd->dev_id = params->dev_id; 2387 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2388 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2389 buf_ptr += WMI_TLV_HDR_SIZE; 2390 for (index = 0; index < num; index++) { 2391 setparam = (wmi_set_param_info *)buf_ptr; 2392 WMITLV_SET_HDR(&setparam->tlv_header, 2393 WMITLV_TAG_STRUC_wmi_set_param_info, 2394 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2395 setparam->param_id = params->params[index].param_id; 2396 setparam->param_value = params->params[index].param_value; 2397 send_dev_multi_setparam_cmd_tlv(setparam, params); 2398 buf_ptr += sizeof(*setparam); 2399 } 2400 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2401 cmd->dev_id, 0); 2402 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2403 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2404 if (QDF_IS_STATUS_ERROR(ret)) { 2405 wmi_err("failed to send WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID"); 2406 wmi_buf_free(buf); 2407 } 2408 return ret; 2409 } 2410 2411 /** 2412 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2413 * @wmi_handle: wmi handle 2414 * @params: pointer to set_multiple_pdev_vdev_param structure 2415 * 2416 * Return: 0 on success, errno on failure 2417 */ 2418 static QDF_STATUS 2419 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2420 struct set_multiple_pdev_vdev_param *params) 2421 { 2422 if (!wmi_service_enabled(wmi_handle, 2423 wmi_service_combined_set_param_support)) 2424 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2425 params); 2426 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2427 } 2428 2429 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2430 /** 2431 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2432 * @wmi_handle: wmi handle 2433 * @params: pointer to set_multiple_pdev_vdev_param structure 2434 * 2435 * Return: 0 on success, errno on failure 2436 */ 2437 static QDF_STATUS 2438 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2439 struct set_multiple_pdev_vdev_param *params) 2440 { 2441 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2442 } 2443 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2444 2445 /** 2446 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2447 * @wmi_handle: wmi handle 2448 * @msg: Structure containing the following parameters 2449 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2450 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2451 * 2452 * Provides notification to the WLAN firmware that host driver is requesting a 2453 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2454 * configurations that include the Dual Band Simultaneous (DBS) feature. 2455 * 2456 * Return: Success if the cmd is sent successfully to the firmware 2457 */ 2458 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2459 uint32_t hw_mode_index) 2460 { 2461 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2462 wmi_buf_t buf; 2463 uint32_t len; 2464 2465 len = sizeof(*cmd); 2466 2467 buf = wmi_buf_alloc(wmi_handle, len); 2468 if (!buf) 2469 return QDF_STATUS_E_NOMEM; 2470 2471 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2472 WMITLV_SET_HDR(&cmd->tlv_header, 2473 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2474 WMITLV_GET_STRUCT_TLVLEN( 2475 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2476 2477 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2478 wmi_handle, 2479 WMI_HOST_PDEV_ID_SOC); 2480 cmd->hw_mode_index = hw_mode_index; 2481 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2482 2483 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2484 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2485 WMI_PDEV_SET_HW_MODE_CMDID)) { 2486 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2487 wmi_buf_free(buf); 2488 return QDF_STATUS_E_FAILURE; 2489 } 2490 2491 return QDF_STATUS_SUCCESS; 2492 } 2493 2494 /** 2495 * send_suspend_cmd_tlv() - WMI suspend function 2496 * @param wmi_handle : handle to WMI. 2497 * @param param : pointer to hold suspend parameter 2498 * @mac_id: radio context 2499 * 2500 * Return 0 on success and -ve on failure. 2501 */ 2502 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2503 struct suspend_params *param, 2504 uint8_t mac_id) 2505 { 2506 wmi_pdev_suspend_cmd_fixed_param *cmd; 2507 wmi_buf_t wmibuf; 2508 uint32_t len = sizeof(*cmd); 2509 int32_t ret; 2510 2511 /* 2512 * send the command to Target to ignore the 2513 * PCIE reset so as to ensure that Host and target 2514 * states are in sync 2515 */ 2516 wmibuf = wmi_buf_alloc(wmi_handle, len); 2517 if (!wmibuf) 2518 return QDF_STATUS_E_NOMEM; 2519 2520 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2521 WMITLV_SET_HDR(&cmd->tlv_header, 2522 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2523 WMITLV_GET_STRUCT_TLVLEN 2524 (wmi_pdev_suspend_cmd_fixed_param)); 2525 if (param->disable_target_intr) 2526 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2527 else 2528 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2529 2530 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2531 wmi_handle, 2532 mac_id); 2533 2534 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2535 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2536 WMI_PDEV_SUSPEND_CMDID); 2537 if (ret) { 2538 wmi_buf_free(wmibuf); 2539 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2540 } 2541 2542 return ret; 2543 } 2544 2545 /** 2546 * send_resume_cmd_tlv() - WMI resume function 2547 * @param wmi_handle : handle to WMI. 2548 * @mac_id: radio context 2549 * 2550 * Return: 0 on success and -ve on failure. 2551 */ 2552 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2553 uint8_t mac_id) 2554 { 2555 wmi_buf_t wmibuf; 2556 wmi_pdev_resume_cmd_fixed_param *cmd; 2557 QDF_STATUS ret; 2558 2559 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2560 if (!wmibuf) 2561 return QDF_STATUS_E_NOMEM; 2562 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2563 WMITLV_SET_HDR(&cmd->tlv_header, 2564 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2565 WMITLV_GET_STRUCT_TLVLEN 2566 (wmi_pdev_resume_cmd_fixed_param)); 2567 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2568 wmi_handle, 2569 mac_id); 2570 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2571 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2572 WMI_PDEV_RESUME_CMDID); 2573 if (QDF_IS_STATUS_ERROR(ret)) { 2574 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2575 wmi_buf_free(wmibuf); 2576 } 2577 2578 return ret; 2579 } 2580 2581 /** 2582 * send_wow_enable_cmd_tlv() - WMI wow enable function 2583 * @param wmi_handle : handle to WMI. 2584 * @param param : pointer to hold wow enable parameter 2585 * @mac_id: radio context 2586 * 2587 * Return: 0 on success and -ve on failure. 2588 */ 2589 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2590 struct wow_cmd_params *param, 2591 uint8_t mac_id) 2592 { 2593 wmi_wow_enable_cmd_fixed_param *cmd; 2594 wmi_buf_t buf; 2595 int32_t len; 2596 int32_t ret; 2597 2598 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2599 2600 buf = wmi_buf_alloc(wmi_handle, len); 2601 if (!buf) 2602 return QDF_STATUS_E_NOMEM; 2603 2604 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2605 WMITLV_SET_HDR(&cmd->tlv_header, 2606 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2607 WMITLV_GET_STRUCT_TLVLEN 2608 (wmi_wow_enable_cmd_fixed_param)); 2609 cmd->enable = param->enable; 2610 if (param->can_suspend_link) 2611 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2612 else 2613 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2614 cmd->flags = param->flags; 2615 2616 wmi_debug("suspend type: %s flag is 0x%x", 2617 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2618 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2619 cmd->flags); 2620 2621 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2622 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2623 WMI_WOW_ENABLE_CMDID); 2624 if (ret) 2625 wmi_buf_free(buf); 2626 2627 return ret; 2628 } 2629 2630 /** 2631 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2632 * @wmi_handle: wmi handle 2633 * @peer_addr: peer mac address 2634 * @param: pointer to ap_ps parameter structure 2635 * 2636 * Return: QDF_STATUS_SUCCESS for success or error code 2637 */ 2638 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2639 uint8_t *peer_addr, 2640 struct ap_ps_params *param) 2641 { 2642 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2643 wmi_buf_t buf; 2644 int32_t err; 2645 2646 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2647 if (!buf) 2648 return QDF_STATUS_E_NOMEM; 2649 2650 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2651 WMITLV_SET_HDR(&cmd->tlv_header, 2652 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2653 WMITLV_GET_STRUCT_TLVLEN 2654 (wmi_ap_ps_peer_cmd_fixed_param)); 2655 cmd->vdev_id = param->vdev_id; 2656 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2657 cmd->param = param->param; 2658 cmd->value = param->value; 2659 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2660 err = wmi_unified_cmd_send(wmi_handle, buf, 2661 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2662 if (err) { 2663 wmi_err("Failed to send set_ap_ps_param cmd"); 2664 wmi_buf_free(buf); 2665 return QDF_STATUS_E_FAILURE; 2666 } 2667 2668 return 0; 2669 } 2670 2671 /** 2672 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2673 * @wmi_handle: wmi handle 2674 * @peer_addr: peer mac address 2675 * @param: pointer to sta_ps parameter structure 2676 * 2677 * Return: QDF_STATUS_SUCCESS for success or error code 2678 */ 2679 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2680 struct sta_ps_params *param) 2681 { 2682 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2683 wmi_buf_t buf; 2684 int32_t len = sizeof(*cmd); 2685 2686 buf = wmi_buf_alloc(wmi_handle, len); 2687 if (!buf) 2688 return QDF_STATUS_E_NOMEM; 2689 2690 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2691 WMITLV_SET_HDR(&cmd->tlv_header, 2692 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2693 WMITLV_GET_STRUCT_TLVLEN 2694 (wmi_sta_powersave_param_cmd_fixed_param)); 2695 cmd->vdev_id = param->vdev_id; 2696 cmd->param = param->param_id; 2697 cmd->value = param->value; 2698 2699 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2700 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2701 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2702 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2703 param->vdev_id, param->param_id, param->value); 2704 wmi_buf_free(buf); 2705 return QDF_STATUS_E_FAILURE; 2706 } 2707 2708 return 0; 2709 } 2710 2711 /** 2712 * send_crash_inject_cmd_tlv() - inject fw crash 2713 * @wmi_handle: wmi handle 2714 * @param: ponirt to crash inject parameter structure 2715 * 2716 * Return: QDF_STATUS_SUCCESS for success or return error 2717 */ 2718 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2719 struct crash_inject *param) 2720 { 2721 int32_t ret = 0; 2722 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2723 uint16_t len = sizeof(*cmd); 2724 wmi_buf_t buf; 2725 2726 buf = wmi_buf_alloc(wmi_handle, len); 2727 if (!buf) 2728 return QDF_STATUS_E_NOMEM; 2729 2730 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2731 WMITLV_SET_HDR(&cmd->tlv_header, 2732 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2733 WMITLV_GET_STRUCT_TLVLEN 2734 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2735 cmd->type = param->type; 2736 cmd->delay_time_ms = param->delay_time_ms; 2737 2738 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2739 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2740 WMI_FORCE_FW_HANG_CMDID); 2741 if (ret) { 2742 wmi_err("Failed to send set param command, ret = %d", ret); 2743 wmi_buf_free(buf); 2744 } 2745 2746 return ret; 2747 } 2748 2749 /** 2750 * send_dbglog_cmd_tlv() - set debug log level 2751 * @param wmi_handle : handle to WMI. 2752 * @param param : pointer to hold dbglog level parameter 2753 * 2754 * Return: 0 on success and -ve on failure. 2755 */ 2756 static QDF_STATUS 2757 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2758 struct dbglog_params *dbglog_param) 2759 { 2760 wmi_buf_t buf; 2761 wmi_debug_log_config_cmd_fixed_param *configmsg; 2762 QDF_STATUS status; 2763 int32_t i; 2764 int32_t len; 2765 int8_t *buf_ptr; 2766 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2767 2768 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2769 2770 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2771 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2772 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2773 buf = wmi_buf_alloc(wmi_handle, len); 2774 if (!buf) 2775 return QDF_STATUS_E_NOMEM; 2776 2777 configmsg = 2778 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2779 buf_ptr = (int8_t *) configmsg; 2780 WMITLV_SET_HDR(&configmsg->tlv_header, 2781 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2782 WMITLV_GET_STRUCT_TLVLEN 2783 (wmi_debug_log_config_cmd_fixed_param)); 2784 configmsg->dbg_log_param = dbglog_param->param; 2785 configmsg->value = dbglog_param->val; 2786 /* Filling in the data part of second tlv -- should 2787 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2788 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2789 sizeof 2790 (wmi_debug_log_config_cmd_fixed_param) 2791 + WMI_TLV_HDR_SIZE); 2792 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2793 WMITLV_TAG_ARRAY_UINT32, 2794 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2795 if (dbglog_param->module_id_bitmap) { 2796 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2797 module_id_bitmap_array[i] = 2798 dbglog_param->module_id_bitmap[i]; 2799 } 2800 } 2801 2802 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2803 status = wmi_unified_cmd_send(wmi_handle, buf, 2804 len, WMI_DBGLOG_CFG_CMDID); 2805 2806 if (status != QDF_STATUS_SUCCESS) 2807 wmi_buf_free(buf); 2808 2809 return status; 2810 } 2811 2812 /** 2813 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2814 * @param wmi_handle : handle to WMI. 2815 * @param macaddr : MAC address 2816 * @param param : pointer to hold vdev set parameter 2817 * 2818 * Return: 0 on success and -ve on failure. 2819 */ 2820 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2821 struct vdev_set_params *param) 2822 { 2823 QDF_STATUS ret; 2824 wmi_vdev_set_param_cmd_fixed_param *cmd; 2825 wmi_buf_t buf; 2826 uint16_t len = sizeof(*cmd); 2827 uint32_t vdev_param; 2828 2829 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2830 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2831 wmi_err("Vdev param %d not available", param->param_id); 2832 return QDF_STATUS_E_INVAL; 2833 2834 } 2835 2836 buf = wmi_buf_alloc(wmi_handle, len); 2837 if (!buf) 2838 return QDF_STATUS_E_NOMEM; 2839 2840 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2841 WMITLV_SET_HDR(&cmd->tlv_header, 2842 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2843 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 2844 cmd->vdev_id = param->vdev_id; 2845 cmd->param_id = vdev_param; 2846 cmd->param_value = param->param_value; 2847 wmi_debug("Setting vdev %d param = %x, value = %u", 2848 cmd->vdev_id, cmd->param_id, cmd->param_value); 2849 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2850 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 2851 if (QDF_IS_STATUS_ERROR(ret)) { 2852 wmi_err("Failed to send set param command ret = %d", ret); 2853 wmi_buf_free(buf); 2854 } 2855 2856 return ret; 2857 } 2858 2859 /** 2860 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 2861 * @wmi_handle : handle to WMI. 2862 * @dev_id: device id of pdev/vdev 2863 * @params: pointer to point array of structure dev_set_param with @n_params 2864 * @n_params: total number of set params that are combined with @params 2865 * 2866 * Return: returns QDF_STATUS. 2867 */ 2868 static QDF_STATUS 2869 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 2870 struct set_multiple_pdev_vdev_param *params) 2871 { 2872 uint8_t index; 2873 struct vdev_set_params vdevparam; 2874 2875 for (index = 0; index < params->n_params; index++) { 2876 vdevparam.param_id = params->params[index].param_id; 2877 vdevparam.param_value = params->params[index].param_value; 2878 vdevparam.vdev_id = params->dev_id; 2879 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 2880 wmi_err("failed to send param:%d", vdevparam.param_id); 2881 return QDF_STATUS_E_FAILURE; 2882 } 2883 } 2884 return QDF_STATUS_SUCCESS; 2885 } 2886 2887 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2888 /** 2889 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2890 * @wmi_handle : handle to WMI. 2891 * @params: pointer to hold set_multiple_pdev_vdev_param info 2892 * 2893 * Return: 0 on success and errorcode on failure. 2894 */ 2895 static QDF_STATUS 2896 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2897 struct set_multiple_pdev_vdev_param *params) 2898 { 2899 if (!wmi_service_enabled(wmi_handle, 2900 wmi_service_combined_set_param_support)) 2901 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 2902 params); 2903 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2904 } 2905 2906 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2907 2908 /** 2909 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 2910 * @wmi_handle : handle to WMI. 2911 * @params: pointer to hold set_multiple_pdev_vdev_param info 2912 * 2913 * Return: 0 on success and errorcode on failure. 2914 */ 2915 static QDF_STATUS 2916 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2917 struct set_multiple_pdev_vdev_param *params) 2918 { 2919 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 2920 } 2921 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2922 2923 /** 2924 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 2925 * @param wmi_handle : handle to WMI. 2926 * @param param : pointer to hold mu sniffer parameter 2927 * 2928 * Return: 0 on success and -ve on failure. 2929 */ 2930 static 2931 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 2932 struct vdev_set_mu_snif_param *param) 2933 { 2934 QDF_STATUS ret; 2935 wmi_vdev_set_mu_snif_cmd_param *cmd; 2936 wmi_buf_t buf; 2937 uint32_t *tmp_ptr; 2938 uint16_t len = sizeof(*cmd); 2939 uint8_t *buf_ptr; 2940 uint32_t i; 2941 2942 /* Length TLV placeholder for array of uint32_t */ 2943 len += WMI_TLV_HDR_SIZE; 2944 2945 if (param->num_aid) 2946 len += param->num_aid * sizeof(uint32_t); 2947 2948 buf = wmi_buf_alloc(wmi_handle, len); 2949 if (!buf) 2950 return QDF_STATUS_E_NOMEM; 2951 2952 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2953 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 2954 2955 WMITLV_SET_HDR(&cmd->tlv_header, 2956 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 2957 WMITLV_GET_STRUCT_TLVLEN 2958 (wmi_vdev_set_mu_snif_cmd_param)); 2959 2960 cmd->vdev_id = param->vdev_id; 2961 cmd->mode = param->mode; 2962 cmd->max_num_user = param->num_user; 2963 2964 buf_ptr += sizeof(*cmd); 2965 2966 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 2967 2968 for (i = 0; i < param->num_aid; ++i) 2969 tmp_ptr[i] = param->aid[i]; 2970 2971 WMITLV_SET_HDR(buf_ptr, 2972 WMITLV_TAG_ARRAY_UINT32, 2973 (param->num_aid * sizeof(uint32_t))); 2974 2975 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 2976 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 2977 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2979 WMI_VDEV_SET_MU_SNIF_CMDID); 2980 if (QDF_IS_STATUS_ERROR(ret)) { 2981 wmi_err("Failed to send set param command ret = %d", ret); 2982 wmi_buf_free(buf); 2983 } 2984 2985 return ret; 2986 } 2987 2988 /** 2989 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2990 * @wmi_handle: handle to WMI. 2991 * @macaddr: Peer mac address to be filter 2992 * @mac_id: mac id to have radio context 2993 * @enb_dsb: Enable MAC based filtering or Disable 2994 * 2995 * Return: QDF_STATUS 2996 */ 2997 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2998 uint8_t *macaddr, 2999 uint8_t mac_id, 3000 uint8_t enb_dsb) 3001 { 3002 int32_t ret; 3003 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3004 wmi_pdev_pktlog_filter_info *mac_info; 3005 wmi_buf_t buf; 3006 uint8_t *buf_ptr; 3007 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3008 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3009 3010 buf = wmi_buf_alloc(wmi_handle, len); 3011 if (!buf) 3012 return QDF_STATUS_E_NOMEM; 3013 3014 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3015 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3016 WMITLV_SET_HDR(&cmd->tlv_header, 3017 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3018 WMITLV_GET_STRUCT_TLVLEN 3019 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3020 cmd->pdev_id = mac_id; 3021 cmd->enable = enb_dsb; 3022 cmd->num_of_mac_addresses = 1; 3023 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3024 3025 buf_ptr += sizeof(*cmd); 3026 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3027 sizeof(wmi_pdev_pktlog_filter_info)); 3028 buf_ptr += WMI_TLV_HDR_SIZE; 3029 3030 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3031 3032 WMITLV_SET_HDR(&mac_info->tlv_header, 3033 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3034 WMITLV_GET_STRUCT_TLVLEN 3035 (wmi_pdev_pktlog_filter_info)); 3036 3037 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3038 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3039 WMI_PDEV_PKTLOG_FILTER_CMDID); 3040 if (ret) { 3041 wmi_err("Failed to send peer based pktlog command to FW =%d" 3042 , ret); 3043 wmi_buf_free(buf); 3044 } 3045 3046 return ret; 3047 } 3048 3049 /** 3050 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3051 * @param wmi_handle : handle to WMI. 3052 * @param PKTLOG_EVENT : packet log event 3053 * @mac_id: mac id to have radio context 3054 * 3055 * Return: 0 on success and -ve on failure. 3056 */ 3057 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3058 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3059 { 3060 int32_t ret, idx, max_idx; 3061 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3062 wmi_buf_t buf; 3063 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3064 3065 buf = wmi_buf_alloc(wmi_handle, len); 3066 if (!buf) 3067 return -QDF_STATUS_E_NOMEM; 3068 3069 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3070 WMITLV_SET_HDR(&cmd->tlv_header, 3071 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3072 WMITLV_GET_STRUCT_TLVLEN 3073 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3074 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3075 cmd->evlist = 0; 3076 for (idx = 0; idx < max_idx; idx++) { 3077 if (PKTLOG_EVENT & (1 << idx)) 3078 cmd->evlist |= pktlog_event_tlv[idx]; 3079 } 3080 cmd->pdev_id = mac_id; 3081 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3082 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3083 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3084 if (ret) { 3085 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3086 wmi_buf_free(buf); 3087 } 3088 3089 return ret; 3090 } 3091 3092 /** 3093 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3094 * @param wmi_handle : handle to WMI. 3095 * @mac_id: mac id to have radio context 3096 * 3097 * Return: 0 on success and -ve on failure. 3098 */ 3099 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3100 uint8_t mac_id) 3101 { 3102 int32_t ret; 3103 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3104 wmi_buf_t buf; 3105 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3106 3107 buf = wmi_buf_alloc(wmi_handle, len); 3108 if (!buf) 3109 return -QDF_STATUS_E_NOMEM; 3110 3111 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3112 WMITLV_SET_HDR(&cmd->tlv_header, 3113 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3114 WMITLV_GET_STRUCT_TLVLEN 3115 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3116 cmd->pdev_id = mac_id; 3117 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3118 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3119 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3120 if (ret) { 3121 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3122 wmi_buf_free(buf); 3123 } 3124 3125 return ret; 3126 } 3127 3128 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3129 /** 3130 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3131 * sync time between between host and firmware 3132 * @param wmi_handle : handle to WMI. 3133 * 3134 * Return: None 3135 */ 3136 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3137 { 3138 wmi_buf_t buf; 3139 QDF_STATUS status = QDF_STATUS_SUCCESS; 3140 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3141 int32_t len; 3142 qdf_time_t time_ms; 3143 3144 len = sizeof(*time_stamp); 3145 buf = wmi_buf_alloc(wmi_handle, len); 3146 3147 if (!buf) 3148 return; 3149 3150 time_stamp = 3151 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3152 (wmi_buf_data(buf)); 3153 WMITLV_SET_HDR(&time_stamp->tlv_header, 3154 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3155 WMITLV_GET_STRUCT_TLVLEN( 3156 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3157 3158 time_ms = qdf_get_time_of_the_day_ms(); 3159 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3160 time_stamp->time_stamp_low = time_ms & 3161 WMI_FW_TIME_STAMP_LOW_MASK; 3162 /* 3163 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3164 * won't exceed 27 bit 3165 */ 3166 time_stamp->time_stamp_high = 0; 3167 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3168 time_stamp->mode, time_stamp->time_stamp_low, 3169 time_stamp->time_stamp_high); 3170 3171 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3172 status = wmi_unified_cmd_send(wmi_handle, buf, 3173 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3174 if (status) { 3175 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3176 wmi_buf_free(buf); 3177 } 3178 3179 } 3180 3181 /** 3182 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3183 * @param wmi_handle : handle to WMI. 3184 * @param param : pointer to hold FILS Discovery send cmd parameter 3185 * 3186 * Return: 0 on success and -ve on failure. 3187 */ 3188 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3189 struct fils_discovery_tmpl_params *param) 3190 { 3191 int32_t ret; 3192 wmi_fd_tmpl_cmd_fixed_param *cmd; 3193 wmi_buf_t wmi_buf; 3194 uint8_t *buf_ptr; 3195 uint32_t wmi_buf_len; 3196 3197 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3198 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3199 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3200 if (!wmi_buf) 3201 return QDF_STATUS_E_NOMEM; 3202 3203 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3204 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3205 WMITLV_SET_HDR(&cmd->tlv_header, 3206 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3207 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3208 cmd->vdev_id = param->vdev_id; 3209 cmd->buf_len = param->tmpl_len; 3210 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3211 3212 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3213 buf_ptr += WMI_TLV_HDR_SIZE; 3214 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3215 3216 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3217 ret = wmi_unified_cmd_send(wmi_handle, 3218 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3219 3220 if (ret) { 3221 wmi_err("Failed to send fd tmpl: %d", ret); 3222 wmi_buf_free(wmi_buf); 3223 return ret; 3224 } 3225 3226 return 0; 3227 } 3228 3229 /** 3230 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 3231 * @param wmi_handle : handle to WMI. 3232 * @param param : pointer to hold beacon send cmd parameter 3233 * 3234 * Return: 0 on success and -ve on failure. 3235 */ 3236 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3237 struct beacon_tmpl_params *param) 3238 { 3239 int32_t ret; 3240 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3241 wmi_bcn_prb_info *bcn_prb_info; 3242 wmi_buf_t wmi_buf; 3243 uint8_t *buf_ptr; 3244 uint32_t wmi_buf_len; 3245 3246 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3247 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3248 param->tmpl_len_aligned + 3249 bcn_tmpl_mlo_param_size(param) + 3250 bcn_tmpl_ml_info_size(param); 3251 3252 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3253 if (!wmi_buf) 3254 return QDF_STATUS_E_NOMEM; 3255 3256 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3257 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3258 WMITLV_SET_HDR(&cmd->tlv_header, 3259 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3260 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3261 cmd->vdev_id = param->vdev_id; 3262 cmd->tim_ie_offset = param->tim_ie_offset; 3263 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3264 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3265 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3266 cmd->esp_ie_offset = param->esp_ie_offset; 3267 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3268 cmd->ema_params = param->ema_params; 3269 cmd->buf_len = param->tmpl_len; 3270 cmd->csa_event_bitmap = param->csa_event_bitmap; 3271 3272 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3273 param->enable_bigtk); 3274 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3275 3276 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3277 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3278 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3279 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3280 bcn_prb_info->caps = 0; 3281 bcn_prb_info->erp = 0; 3282 buf_ptr += sizeof(wmi_bcn_prb_info); 3283 3284 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3285 buf_ptr += WMI_TLV_HDR_SIZE; 3286 3287 /* for big endian host, copy engine byte_swap is enabled 3288 * But the frame content is in network byte order 3289 * Need to byte swap the frame content - so when copy engine 3290 * does byte_swap - target gets frame content in the correct order 3291 */ 3292 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3293 param->tmpl_len); 3294 3295 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3296 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3297 3298 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3299 3300 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3301 ret = wmi_unified_cmd_send(wmi_handle, 3302 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3303 if (ret) { 3304 wmi_err("Failed to send bcn tmpl: %d", ret); 3305 wmi_buf_free(wmi_buf); 3306 } 3307 3308 return 0; 3309 } 3310 3311 #ifdef WLAN_FEATURE_11BE 3312 static inline void copy_peer_flags_tlv_11be( 3313 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3314 struct peer_assoc_params *param) 3315 { 3316 if (param->bw_320) 3317 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3318 if (param->eht_flag) 3319 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3320 3321 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3322 } 3323 #else 3324 static inline void copy_peer_flags_tlv_11be( 3325 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3326 struct peer_assoc_params *param) 3327 { 3328 } 3329 #endif 3330 3331 static inline void copy_peer_flags_tlv( 3332 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3333 struct peer_assoc_params *param) 3334 { 3335 /* 3336 * The target only needs a subset of the flags maintained in the host. 3337 * Just populate those flags and send it down 3338 */ 3339 cmd->peer_flags = 0; 3340 if (param->peer_dms_capable) 3341 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3342 /* 3343 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3344 */ 3345 if (param->is_wme_set) { 3346 3347 if (param->qos_flag) 3348 cmd->peer_flags |= WMI_PEER_QOS; 3349 if (param->apsd_flag) 3350 cmd->peer_flags |= WMI_PEER_APSD; 3351 if (param->ht_flag) 3352 cmd->peer_flags |= WMI_PEER_HT; 3353 if (param->bw_40) 3354 cmd->peer_flags |= WMI_PEER_40MHZ; 3355 if (param->bw_80) 3356 cmd->peer_flags |= WMI_PEER_80MHZ; 3357 if (param->bw_160) 3358 cmd->peer_flags |= WMI_PEER_160MHZ; 3359 3360 copy_peer_flags_tlv_11be(cmd, param); 3361 3362 /* Typically if STBC is enabled for VHT it should be enabled 3363 * for HT as well 3364 **/ 3365 if (param->stbc_flag) 3366 cmd->peer_flags |= WMI_PEER_STBC; 3367 3368 /* Typically if LDPC is enabled for VHT it should be enabled 3369 * for HT as well 3370 **/ 3371 if (param->ldpc_flag) 3372 cmd->peer_flags |= WMI_PEER_LDPC; 3373 3374 if (param->static_mimops_flag) 3375 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3376 if (param->dynamic_mimops_flag) 3377 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3378 if (param->spatial_mux_flag) 3379 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3380 if (param->vht_flag) 3381 cmd->peer_flags |= WMI_PEER_VHT; 3382 if (param->he_flag) 3383 cmd->peer_flags |= WMI_PEER_HE; 3384 if (param->p2p_capable_sta) 3385 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3386 } 3387 3388 if (param->is_pmf_enabled) 3389 cmd->peer_flags |= WMI_PEER_PMF; 3390 /* 3391 * Suppress authorization for all AUTH modes that need 4-way handshake 3392 * (during re-association). 3393 * Authorization will be done for these modes on key installation. 3394 */ 3395 if (param->auth_flag) 3396 cmd->peer_flags |= WMI_PEER_AUTH; 3397 if (param->need_ptk_4_way) 3398 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3399 else 3400 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3401 if (param->need_gtk_2_way) 3402 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3403 /* safe mode bypass the 4-way handshake */ 3404 if (param->safe_mode_enabled) 3405 cmd->peer_flags &= 3406 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3407 /* inter BSS peer */ 3408 if (param->inter_bss_peer) 3409 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3410 /* Disable AMSDU for station transmit, if user configures it */ 3411 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3412 * it 3413 * if (param->amsdu_disable) Add after FW support 3414 **/ 3415 3416 /* Target asserts if node is marked HT and all MCS is set to 0. 3417 * Mark the node as non-HT if all the mcs rates are disabled through 3418 * iwpriv 3419 **/ 3420 if (param->peer_ht_rates.num_rates == 0) 3421 cmd->peer_flags &= ~WMI_PEER_HT; 3422 3423 if (param->twt_requester) 3424 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3425 3426 if (param->twt_responder) 3427 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3428 } 3429 3430 static inline void copy_peer_mac_addr_tlv( 3431 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3432 struct peer_assoc_params *param) 3433 { 3434 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3435 } 3436 3437 #ifdef WLAN_FEATURE_11BE 3438 static uint8_t *update_peer_flags_tlv_ehtinfo( 3439 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3440 struct peer_assoc_params *param, uint8_t *buf_ptr) 3441 { 3442 wmi_eht_rate_set *eht_mcs; 3443 int i; 3444 3445 cmd->peer_eht_ops = param->peer_eht_ops; 3446 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3447 3448 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3449 sizeof(param->peer_eht_cap_macinfo)); 3450 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3451 sizeof(param->peer_eht_cap_phyinfo)); 3452 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3453 sizeof(param->peer_eht_ppet)); 3454 3455 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3456 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3457 buf_ptr += WMI_TLV_HDR_SIZE; 3458 3459 /* Loop through the EHT rate set */ 3460 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3461 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3462 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3463 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3464 3465 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3466 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3467 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3468 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3469 buf_ptr += sizeof(wmi_eht_rate_set); 3470 } 3471 3472 wmi_debug("nss %d ru mask 0x%x", 3473 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3474 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3475 wmi_debug("ppet idx %d ppet %x ", 3476 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3477 } 3478 3479 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3480 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3481 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3482 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3483 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3484 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3485 param->peer_eht_tx_mcs_set 3486 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3487 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3488 param->peer_eht_rx_mcs_set 3489 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3490 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3491 QDF_MAC_ADDR_REF(param->peer_mac)); 3492 } 3493 3494 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3495 cmd->peer_eht_cap_mac[0], 3496 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3497 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 3498 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3499 3500 return buf_ptr; 3501 } 3502 #else 3503 static uint8_t *update_peer_flags_tlv_ehtinfo( 3504 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3505 struct peer_assoc_params *param, uint8_t *buf_ptr) 3506 { 3507 return buf_ptr; 3508 } 3509 #endif 3510 3511 #ifdef WLAN_FEATURE_11BE 3512 static 3513 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3514 { 3515 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3516 + WMI_TLV_HDR_SIZE); 3517 } 3518 3519 static void wmi_populate_service_11be(uint32_t *wmi_service) 3520 { 3521 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3522 } 3523 3524 #else 3525 static 3526 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3527 { 3528 return 0; 3529 } 3530 3531 static void wmi_populate_service_11be(uint32_t *wmi_service) 3532 { 3533 } 3534 3535 #endif 3536 3537 /** 3538 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3539 * @param wmi_handle : handle to WMI. 3540 * @param param : pointer to peer assoc parameter 3541 * 3542 * Return: 0 on success and -ve on failure. 3543 */ 3544 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3545 struct peer_assoc_params *param) 3546 { 3547 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3548 wmi_vht_rate_set *mcs; 3549 wmi_he_rate_set *he_mcs; 3550 wmi_buf_t buf; 3551 int32_t len; 3552 uint8_t *buf_ptr; 3553 QDF_STATUS ret; 3554 uint32_t peer_legacy_rates_align; 3555 uint32_t peer_ht_rates_align; 3556 int32_t i; 3557 3558 3559 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3560 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3561 3562 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3563 (peer_legacy_rates_align * sizeof(uint8_t)) + 3564 WMI_TLV_HDR_SIZE + 3565 (peer_ht_rates_align * sizeof(uint8_t)) + 3566 sizeof(wmi_vht_rate_set) + 3567 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3568 + WMI_TLV_HDR_SIZE) 3569 + wmi_eht_peer_assoc_params_len(param) + 3570 peer_assoc_mlo_params_size(param) + 3571 peer_assoc_t2lm_params_size(param); 3572 3573 buf = wmi_buf_alloc(wmi_handle, len); 3574 if (!buf) 3575 return QDF_STATUS_E_NOMEM; 3576 3577 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3578 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3579 WMITLV_SET_HDR(&cmd->tlv_header, 3580 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3581 WMITLV_GET_STRUCT_TLVLEN 3582 (wmi_peer_assoc_complete_cmd_fixed_param)); 3583 3584 cmd->vdev_id = param->vdev_id; 3585 3586 cmd->peer_new_assoc = param->peer_new_assoc; 3587 cmd->peer_associd = param->peer_associd; 3588 3589 copy_peer_flags_tlv(cmd, param); 3590 copy_peer_mac_addr_tlv(cmd, param); 3591 3592 cmd->peer_rate_caps = param->peer_rate_caps; 3593 cmd->peer_caps = param->peer_caps; 3594 cmd->peer_listen_intval = param->peer_listen_intval; 3595 cmd->peer_ht_caps = param->peer_ht_caps; 3596 cmd->peer_max_mpdu = param->peer_max_mpdu; 3597 cmd->peer_mpdu_density = param->peer_mpdu_density; 3598 cmd->peer_vht_caps = param->peer_vht_caps; 3599 cmd->peer_phymode = param->peer_phymode; 3600 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3601 3602 /* Update 11ax capabilities */ 3603 cmd->peer_he_cap_info = 3604 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3605 cmd->peer_he_cap_info_ext = 3606 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3607 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3608 cmd->peer_he_ops = param->peer_he_ops; 3609 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3610 sizeof(param->peer_he_cap_phyinfo)); 3611 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3612 sizeof(param->peer_ppet)); 3613 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3614 3615 /* Update peer legacy rate information */ 3616 buf_ptr += sizeof(*cmd); 3617 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3618 peer_legacy_rates_align); 3619 buf_ptr += WMI_TLV_HDR_SIZE; 3620 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3621 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3622 param->peer_legacy_rates.num_rates); 3623 3624 /* Update peer HT rate information */ 3625 buf_ptr += peer_legacy_rates_align; 3626 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3627 peer_ht_rates_align); 3628 buf_ptr += WMI_TLV_HDR_SIZE; 3629 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3630 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3631 param->peer_ht_rates.num_rates); 3632 3633 /* VHT Rates */ 3634 buf_ptr += peer_ht_rates_align; 3635 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3636 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3637 3638 cmd->auth_mode = param->akm; 3639 cmd->peer_nss = param->peer_nss; 3640 3641 /* Update bandwidth-NSS mapping */ 3642 cmd->peer_bw_rxnss_override = 0; 3643 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3644 3645 mcs = (wmi_vht_rate_set *) buf_ptr; 3646 if (param->vht_capable) { 3647 mcs->rx_max_rate = param->rx_max_rate; 3648 mcs->rx_mcs_set = param->rx_mcs_set; 3649 mcs->tx_max_rate = param->tx_max_rate; 3650 mcs->tx_mcs_set = param->tx_mcs_set; 3651 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3652 } 3653 3654 /* HE Rates */ 3655 cmd->min_data_rate = param->min_data_rate; 3656 cmd->peer_he_mcs = param->peer_he_mcs_count; 3657 buf_ptr += sizeof(wmi_vht_rate_set); 3658 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3659 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3660 buf_ptr += WMI_TLV_HDR_SIZE; 3661 3662 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3663 /* Loop through the HE rate set */ 3664 for (i = 0; i < param->peer_he_mcs_count; i++) { 3665 he_mcs = (wmi_he_rate_set *) buf_ptr; 3666 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3667 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3668 3669 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3670 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3671 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3672 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3673 buf_ptr += sizeof(wmi_he_rate_set); 3674 } 3675 3676 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3677 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3678 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3679 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3680 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3681 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3682 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3683 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3684 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3685 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3686 QDF_MAC_ADDR_REF(param->peer_mac)); 3687 } 3688 3689 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3690 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3691 "nss %d phymode %d peer_mpdu_density %d " 3692 "cmd->peer_vht_caps %x " 3693 "HE cap_info %x ops %x " 3694 "HE cap_info_ext %x " 3695 "HE phy %x %x %x " 3696 "peer_bw_rxnss_override %x", 3697 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3698 cmd->peer_rate_caps, cmd->peer_caps, 3699 cmd->peer_listen_intval, cmd->peer_ht_caps, 3700 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3701 cmd->peer_mpdu_density, 3702 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3703 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3704 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3705 cmd->peer_he_cap_phy[2], 3706 cmd->peer_bw_rxnss_override); 3707 3708 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3709 3710 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3711 3712 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3713 3714 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3715 3716 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3717 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3718 WMI_PEER_ASSOC_CMDID); 3719 if (QDF_IS_STATUS_ERROR(ret)) { 3720 wmi_err("Failed to send peer assoc command ret = %d", ret); 3721 wmi_buf_free(buf); 3722 } 3723 3724 return ret; 3725 } 3726 3727 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3728 */ 3729 static inline void copy_scan_event_cntrl_flags( 3730 wmi_start_scan_cmd_fixed_param * cmd, 3731 struct scan_req_params *param) 3732 { 3733 3734 /* Scan events subscription */ 3735 if (param->scan_ev_started) 3736 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3737 if (param->scan_ev_completed) 3738 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3739 if (param->scan_ev_bss_chan) 3740 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3741 if (param->scan_ev_foreign_chan) 3742 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3743 if (param->scan_ev_dequeued) 3744 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3745 if (param->scan_ev_preempted) 3746 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3747 if (param->scan_ev_start_failed) 3748 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3749 if (param->scan_ev_restarted) 3750 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3751 if (param->scan_ev_foreign_chn_exit) 3752 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3753 if (param->scan_ev_suspended) 3754 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3755 if (param->scan_ev_resumed) 3756 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 3757 3758 /** Set scan control flags */ 3759 cmd->scan_ctrl_flags = 0; 3760 if (param->scan_f_passive) 3761 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 3762 if (param->scan_f_strict_passive_pch) 3763 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 3764 if (param->scan_f_promisc_mode) 3765 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 3766 if (param->scan_f_capture_phy_err) 3767 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 3768 if (param->scan_f_half_rate) 3769 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 3770 if (param->scan_f_quarter_rate) 3771 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 3772 if (param->scan_f_cck_rates) 3773 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 3774 if (param->scan_f_ofdm_rates) 3775 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 3776 if (param->scan_f_chan_stat_evnt) 3777 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 3778 if (param->scan_f_filter_prb_req) 3779 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 3780 if (param->scan_f_bcast_probe) 3781 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 3782 if (param->scan_f_offchan_mgmt_tx) 3783 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 3784 if (param->scan_f_offchan_data_tx) 3785 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 3786 if (param->scan_f_force_active_dfs_chn) 3787 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 3788 if (param->scan_f_add_tpc_ie_in_probe) 3789 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 3790 if (param->scan_f_add_ds_ie_in_probe) 3791 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 3792 if (param->scan_f_add_spoofed_mac_in_probe) 3793 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 3794 if (param->scan_f_add_rand_seq_in_probe) 3795 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 3796 if (param->scan_f_en_ie_allowlist_in_probe) 3797 cmd->scan_ctrl_flags |= 3798 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 3799 3800 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 3801 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 3802 param->adaptive_dwell_time_mode); 3803 } 3804 3805 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3806 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3807 struct scan_req_params *params) 3808 { 3809 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3810 } 3811 3812 /** 3813 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3814 * @mac: random mac addr 3815 * @mask: random mac mask 3816 * @mac_addr: wmi random mac 3817 * @mac_mask: wmi random mac mask 3818 * 3819 * Return None. 3820 */ 3821 static inline 3822 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3823 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3824 { 3825 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3826 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3827 } 3828 3829 /* 3830 * wmi_fill_vendor_oui() - fill vendor OUIs 3831 * @buf_ptr: pointer to wmi tlv buffer 3832 * @num_vendor_oui: number of vendor OUIs to be filled 3833 * @param_voui: pointer to OUI buffer 3834 * 3835 * This function populates the wmi tlv buffer when vendor specific OUIs are 3836 * present. 3837 * 3838 * Return: None 3839 */ 3840 static inline 3841 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3842 uint32_t *pvoui) 3843 { 3844 wmi_vendor_oui *voui = NULL; 3845 uint32_t i; 3846 3847 voui = (wmi_vendor_oui *)buf_ptr; 3848 3849 for (i = 0; i < num_vendor_oui; i++) { 3850 WMITLV_SET_HDR(&voui[i].tlv_header, 3851 WMITLV_TAG_STRUC_wmi_vendor_oui, 3852 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3853 voui[i].oui_type_subtype = pvoui[i]; 3854 } 3855 } 3856 3857 /* 3858 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 3859 * @ie_bitmap: output pointer to ie bit map in cmd 3860 * @num_vendor_oui: output pointer to num vendor OUIs 3861 * @ie_allowlist: input parameter 3862 * 3863 * This function populates the IE allowlist attrs of scan, pno and 3864 * scan oui commands for ie_allowlist parameter. 3865 * 3866 * Return: None 3867 */ 3868 static inline 3869 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 3870 uint32_t *num_vendor_oui, 3871 struct probe_req_allowlist_attr *ie_allowlist) 3872 { 3873 uint32_t i = 0; 3874 3875 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3876 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 3877 3878 *num_vendor_oui = ie_allowlist->num_vendor_oui; 3879 } 3880 3881 /** 3882 * send_scan_start_cmd_tlv() - WMI scan start function 3883 * @param wmi_handle : handle to WMI. 3884 * @param param : pointer to hold scan start cmd parameter 3885 * 3886 * Return: 0 on success and -ve on failure. 3887 */ 3888 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3889 struct scan_req_params *params) 3890 { 3891 int32_t ret = 0; 3892 int32_t i; 3893 wmi_buf_t wmi_buf; 3894 wmi_start_scan_cmd_fixed_param *cmd; 3895 uint8_t *buf_ptr; 3896 uint32_t *tmp_ptr; 3897 wmi_ssid *ssid = NULL; 3898 wmi_mac_addr *bssid; 3899 size_t len = sizeof(*cmd); 3900 uint16_t extraie_len_with_pad = 0; 3901 uint8_t phymode_roundup = 0; 3902 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 3903 wmi_hint_freq_short_ssid *s_ssid = NULL; 3904 wmi_hint_freq_bssid *hint_bssid = NULL; 3905 3906 /* Length TLV placeholder for array of uint32_t */ 3907 len += WMI_TLV_HDR_SIZE; 3908 /* calculate the length of buffer required */ 3909 if (params->chan_list.num_chan) 3910 len += params->chan_list.num_chan * sizeof(uint32_t); 3911 3912 /* Length TLV placeholder for array of wmi_ssid structures */ 3913 len += WMI_TLV_HDR_SIZE; 3914 if (params->num_ssids) 3915 len += params->num_ssids * sizeof(wmi_ssid); 3916 3917 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3918 len += WMI_TLV_HDR_SIZE; 3919 if (params->num_bssid) 3920 len += sizeof(wmi_mac_addr) * params->num_bssid; 3921 3922 /* Length TLV placeholder for array of bytes */ 3923 len += WMI_TLV_HDR_SIZE; 3924 if (params->extraie.len) 3925 extraie_len_with_pad = 3926 roundup(params->extraie.len, sizeof(uint32_t)); 3927 len += extraie_len_with_pad; 3928 3929 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3930 if (ie_allowlist->num_vendor_oui) 3931 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 3932 3933 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3934 if (params->scan_f_wide_band) 3935 phymode_roundup = 3936 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3937 sizeof(uint32_t)); 3938 len += phymode_roundup; 3939 3940 len += WMI_TLV_HDR_SIZE; 3941 if (params->num_hint_bssid) 3942 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3943 3944 len += WMI_TLV_HDR_SIZE; 3945 if (params->num_hint_s_ssid) 3946 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3947 3948 /* Allocate the memory */ 3949 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3950 if (!wmi_buf) 3951 return QDF_STATUS_E_FAILURE; 3952 3953 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3954 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3955 WMITLV_SET_HDR(&cmd->tlv_header, 3956 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3957 WMITLV_GET_STRUCT_TLVLEN 3958 (wmi_start_scan_cmd_fixed_param)); 3959 3960 cmd->scan_id = params->scan_id; 3961 cmd->scan_req_id = params->scan_req_id; 3962 cmd->vdev_id = params->vdev_id; 3963 cmd->scan_priority = params->scan_priority; 3964 3965 copy_scan_event_cntrl_flags(cmd, params); 3966 3967 cmd->dwell_time_active = params->dwell_time_active; 3968 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3969 cmd->dwell_time_passive = params->dwell_time_passive; 3970 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3971 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3972 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3973 cmd->scan_start_offset = params->scan_offset_time; 3974 cmd->min_rest_time = params->min_rest_time; 3975 cmd->max_rest_time = params->max_rest_time; 3976 cmd->repeat_probe_time = params->repeat_probe_time; 3977 cmd->probe_spacing_time = params->probe_spacing_time; 3978 cmd->idle_time = params->idle_time; 3979 cmd->max_scan_time = params->max_scan_time; 3980 cmd->probe_delay = params->probe_delay; 3981 cmd->burst_duration = params->burst_duration; 3982 cmd->num_chan = params->chan_list.num_chan; 3983 cmd->num_bssid = params->num_bssid; 3984 cmd->num_ssids = params->num_ssids; 3985 cmd->ie_len = params->extraie.len; 3986 cmd->n_probes = params->n_probes; 3987 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3988 3989 if (params->scan_random.randomize) 3990 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3991 params->scan_random.mac_mask, 3992 &cmd->mac_addr, 3993 &cmd->mac_mask); 3994 3995 if (ie_allowlist->allow_list) 3996 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 3997 &cmd->num_vendor_oui, 3998 ie_allowlist); 3999 4000 buf_ptr += sizeof(*cmd); 4001 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4002 for (i = 0; i < params->chan_list.num_chan; ++i) { 4003 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4004 params->chan_list.chan[i].freq); 4005 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4006 params->chan_list.chan[i].flags); 4007 } 4008 4009 WMITLV_SET_HDR(buf_ptr, 4010 WMITLV_TAG_ARRAY_UINT32, 4011 (params->chan_list.num_chan * sizeof(uint32_t))); 4012 buf_ptr += WMI_TLV_HDR_SIZE + 4013 (params->chan_list.num_chan * sizeof(uint32_t)); 4014 4015 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4016 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4017 goto error; 4018 } 4019 4020 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4021 (params->num_ssids * sizeof(wmi_ssid))); 4022 4023 if (params->num_ssids) { 4024 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4025 for (i = 0; i < params->num_ssids; ++i) { 4026 ssid->ssid_len = params->ssid[i].length; 4027 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4028 params->ssid[i].length); 4029 ssid++; 4030 } 4031 } 4032 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4033 4034 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4035 (params->num_bssid * sizeof(wmi_mac_addr))); 4036 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4037 4038 if (params->num_bssid) { 4039 for (i = 0; i < params->num_bssid; ++i) { 4040 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4041 ¶ms->bssid_list[i].bytes[0], bssid); 4042 bssid++; 4043 } 4044 } 4045 4046 buf_ptr += WMI_TLV_HDR_SIZE + 4047 (params->num_bssid * sizeof(wmi_mac_addr)); 4048 4049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4050 if (params->extraie.len) 4051 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4052 params); 4053 4054 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4055 4056 /* probe req ie allowlisting */ 4057 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4058 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4059 4060 buf_ptr += WMI_TLV_HDR_SIZE; 4061 4062 if (cmd->num_vendor_oui) { 4063 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4064 ie_allowlist->voui); 4065 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4066 } 4067 4068 /* Add phy mode TLV if it's a wide band scan */ 4069 if (params->scan_f_wide_band) { 4070 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4071 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4072 for (i = 0; i < params->chan_list.num_chan; ++i) 4073 buf_ptr[i] = 4074 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4075 buf_ptr += phymode_roundup; 4076 } else { 4077 /* Add ZERO length phy mode TLV */ 4078 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4079 buf_ptr += WMI_TLV_HDR_SIZE; 4080 } 4081 4082 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4083 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4084 if (params->num_hint_s_ssid) { 4085 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4086 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4087 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4088 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4089 s_ssid++; 4090 } 4091 } 4092 buf_ptr += WMI_TLV_HDR_SIZE + 4093 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4094 4095 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4096 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4097 if (params->num_hint_bssid) { 4098 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4099 for (i = 0; i < params->num_hint_bssid; ++i) { 4100 hint_bssid->freq_flags = 4101 params->hint_bssid[i].freq_flags; 4102 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4103 &hint_bssid->bssid); 4104 hint_bssid++; 4105 } 4106 } 4107 4108 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4109 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4110 len, WMI_START_SCAN_CMDID); 4111 if (ret) { 4112 wmi_err("Failed to start scan: %d", ret); 4113 wmi_buf_free(wmi_buf); 4114 } 4115 return ret; 4116 error: 4117 wmi_buf_free(wmi_buf); 4118 return QDF_STATUS_E_FAILURE; 4119 } 4120 4121 /** 4122 * send_scan_stop_cmd_tlv() - WMI scan start function 4123 * @param wmi_handle : handle to WMI. 4124 * @param param : pointer to hold scan cancel cmd parameter 4125 * 4126 * Return: 0 on success and -ve on failure. 4127 */ 4128 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4129 struct scan_cancel_param *param) 4130 { 4131 wmi_stop_scan_cmd_fixed_param *cmd; 4132 int ret; 4133 int len = sizeof(*cmd); 4134 wmi_buf_t wmi_buf; 4135 4136 /* Allocate the memory */ 4137 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4138 if (!wmi_buf) { 4139 ret = QDF_STATUS_E_NOMEM; 4140 goto error; 4141 } 4142 4143 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4144 WMITLV_SET_HDR(&cmd->tlv_header, 4145 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4146 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4147 cmd->vdev_id = param->vdev_id; 4148 cmd->requestor = param->requester; 4149 cmd->scan_id = param->scan_id; 4150 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4151 wmi_handle, 4152 param->pdev_id); 4153 /* stop the scan with the corresponding scan_id */ 4154 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4155 /* Cancelling all scans */ 4156 cmd->req_type = WMI_SCAN_STOP_ALL; 4157 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4158 /* Cancelling VAP scans */ 4159 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4160 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4161 /* Cancelling specific scan */ 4162 cmd->req_type = WMI_SCAN_STOP_ONE; 4163 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4164 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4165 } else { 4166 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4167 wmi_buf_free(wmi_buf); 4168 return QDF_STATUS_E_INVAL; 4169 } 4170 4171 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4172 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4173 len, WMI_STOP_SCAN_CMDID); 4174 if (ret) { 4175 wmi_err("Failed to send stop scan: %d", ret); 4176 wmi_buf_free(wmi_buf); 4177 } 4178 4179 error: 4180 return ret; 4181 } 4182 4183 #define WMI_MAX_CHAN_INFO_LOG 192 4184 4185 /** 4186 * wmi_scan_chanlist_dump() - Dump scan channel list info 4187 * @scan_chan_list: scan channel list 4188 * 4189 * Return: void 4190 */ 4191 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4192 { 4193 uint32_t i; 4194 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4195 uint32_t len = 0; 4196 struct channel_param *chan; 4197 int ret; 4198 4199 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4200 for (i = 0; i < scan_chan_list->nallchans; i++) { 4201 chan = &scan_chan_list->ch_param[i]; 4202 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4203 " %d[%d][%d][%d]", chan->mhz, 4204 chan->maxregpower, 4205 chan->dfs_set, chan->nan_disabled); 4206 if (ret <= 0) 4207 break; 4208 len += ret; 4209 if (len >= (sizeof(info) - 20)) { 4210 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4211 info); 4212 len = 0; 4213 } 4214 } 4215 if (len) 4216 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4217 } 4218 4219 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4220 struct scan_chan_list_params *chan_list) 4221 { 4222 wmi_buf_t buf; 4223 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4224 wmi_scan_chan_list_cmd_fixed_param *cmd; 4225 int i; 4226 uint8_t *buf_ptr; 4227 wmi_channel *chan_info; 4228 struct channel_param *tchan_info; 4229 uint16_t len; 4230 uint16_t num_send_chans, num_sends = 0; 4231 4232 wmi_scan_chanlist_dump(chan_list); 4233 tchan_info = &chan_list->ch_param[0]; 4234 while (chan_list->nallchans) { 4235 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4236 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4237 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4238 else 4239 num_send_chans = chan_list->nallchans; 4240 4241 chan_list->nallchans -= num_send_chans; 4242 len += sizeof(wmi_channel) * num_send_chans; 4243 buf = wmi_buf_alloc(wmi_handle, len); 4244 if (!buf) { 4245 qdf_status = QDF_STATUS_E_NOMEM; 4246 goto end; 4247 } 4248 4249 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4250 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4251 WMITLV_SET_HDR(&cmd->tlv_header, 4252 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4253 WMITLV_GET_STRUCT_TLVLEN 4254 (wmi_scan_chan_list_cmd_fixed_param)); 4255 4256 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4257 4258 if (num_sends) 4259 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4260 4261 if (chan_list->max_bw_support_present) 4262 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4263 4264 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4265 wmi_handle, 4266 chan_list->pdev_id); 4267 4268 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4269 4270 cmd->num_scan_chans = num_send_chans; 4271 WMITLV_SET_HDR((buf_ptr + 4272 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4273 WMITLV_TAG_ARRAY_STRUC, 4274 sizeof(wmi_channel) * num_send_chans); 4275 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4276 WMI_TLV_HDR_SIZE); 4277 4278 for (i = 0; i < num_send_chans; ++i) { 4279 WMITLV_SET_HDR(&chan_info->tlv_header, 4280 WMITLV_TAG_STRUC_wmi_channel, 4281 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4282 chan_info->mhz = tchan_info->mhz; 4283 chan_info->band_center_freq1 = 4284 tchan_info->cfreq1; 4285 chan_info->band_center_freq2 = 4286 tchan_info->cfreq2; 4287 4288 if (tchan_info->is_chan_passive) 4289 WMI_SET_CHANNEL_FLAG(chan_info, 4290 WMI_CHAN_FLAG_PASSIVE); 4291 if (tchan_info->dfs_set) 4292 WMI_SET_CHANNEL_FLAG(chan_info, 4293 WMI_CHAN_FLAG_DFS); 4294 4295 if (tchan_info->dfs_set_cfreq2) 4296 WMI_SET_CHANNEL_FLAG(chan_info, 4297 WMI_CHAN_FLAG_DFS_CFREQ2); 4298 4299 if (tchan_info->allow_he) 4300 WMI_SET_CHANNEL_FLAG(chan_info, 4301 WMI_CHAN_FLAG_ALLOW_HE); 4302 4303 if (tchan_info->allow_eht) 4304 WMI_SET_CHANNEL_FLAG(chan_info, 4305 WMI_CHAN_FLAG_ALLOW_EHT); 4306 4307 if (tchan_info->allow_vht) 4308 WMI_SET_CHANNEL_FLAG(chan_info, 4309 WMI_CHAN_FLAG_ALLOW_VHT); 4310 4311 if (tchan_info->allow_ht) 4312 WMI_SET_CHANNEL_FLAG(chan_info, 4313 WMI_CHAN_FLAG_ALLOW_HT); 4314 WMI_SET_CHANNEL_MODE(chan_info, 4315 tchan_info->phy_mode); 4316 4317 if (tchan_info->half_rate) 4318 WMI_SET_CHANNEL_FLAG(chan_info, 4319 WMI_CHAN_FLAG_HALF_RATE); 4320 4321 if (tchan_info->quarter_rate) 4322 WMI_SET_CHANNEL_FLAG(chan_info, 4323 WMI_CHAN_FLAG_QUARTER_RATE); 4324 4325 if (tchan_info->psc_channel) 4326 WMI_SET_CHANNEL_FLAG(chan_info, 4327 WMI_CHAN_FLAG_PSC); 4328 4329 if (tchan_info->nan_disabled) 4330 WMI_SET_CHANNEL_FLAG(chan_info, 4331 WMI_CHAN_FLAG_NAN_DISABLED); 4332 4333 /* also fill in power information */ 4334 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4335 tchan_info->minpower); 4336 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4337 tchan_info->maxpower); 4338 WMI_SET_CHANNEL_REG_POWER(chan_info, 4339 tchan_info->maxregpower); 4340 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4341 tchan_info->antennamax); 4342 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4343 tchan_info->reg_class_id); 4344 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4345 tchan_info->maxregpower); 4346 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4347 tchan_info->max_bw_supported); 4348 4349 tchan_info++; 4350 chan_info++; 4351 } 4352 4353 qdf_status = wmi_unified_cmd_send( 4354 wmi_handle, 4355 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4356 4357 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4358 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4359 wmi_buf_free(buf); 4360 goto end; 4361 } 4362 num_sends++; 4363 } 4364 4365 end: 4366 return qdf_status; 4367 } 4368 4369 /** 4370 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4371 * 4372 * @bufp: Pointer to buffer 4373 * @param: Pointer to tx param 4374 * 4375 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4376 */ 4377 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4378 struct tx_send_params param) 4379 { 4380 wmi_tx_send_params *tx_param; 4381 QDF_STATUS status = QDF_STATUS_SUCCESS; 4382 4383 if (!bufp) { 4384 status = QDF_STATUS_E_FAILURE; 4385 return status; 4386 } 4387 tx_param = (wmi_tx_send_params *)bufp; 4388 WMITLV_SET_HDR(&tx_param->tlv_header, 4389 WMITLV_TAG_STRUC_wmi_tx_send_params, 4390 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4391 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4392 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4393 param.mcs_mask); 4394 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4395 param.nss_mask); 4396 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4397 param.retry_limit); 4398 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4399 param.chain_mask); 4400 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4401 param.bw_mask); 4402 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4403 param.preamble_type); 4404 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4405 param.frame_type); 4406 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4407 param.cfr_enable); 4408 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4409 param.en_beamforming); 4410 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4411 param.retry_limit_ext); 4412 4413 return status; 4414 } 4415 4416 #ifdef CONFIG_HL_SUPPORT 4417 /** 4418 * send_mgmt_cmd_tlv() - WMI scan start function 4419 * @wmi_handle : handle to WMI. 4420 * @param : pointer to hold mgmt cmd parameter 4421 * 4422 * Return: 0 on success and -ve on failure. 4423 */ 4424 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4425 struct wmi_mgmt_params *param) 4426 { 4427 wmi_buf_t buf; 4428 uint8_t *bufp; 4429 int32_t cmd_len; 4430 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4431 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4432 mgmt_tx_dl_frm_len; 4433 4434 if (param->frm_len > mgmt_tx_dl_frm_len) { 4435 wmi_err("mgmt frame len %u exceeds %u", 4436 param->frm_len, mgmt_tx_dl_frm_len); 4437 return QDF_STATUS_E_INVAL; 4438 } 4439 4440 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4441 WMI_TLV_HDR_SIZE + 4442 roundup(bufp_len, sizeof(uint32_t)); 4443 4444 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4445 if (!buf) 4446 return QDF_STATUS_E_NOMEM; 4447 4448 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4449 bufp = (uint8_t *) cmd; 4450 WMITLV_SET_HDR(&cmd->tlv_header, 4451 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4452 WMITLV_GET_STRUCT_TLVLEN 4453 (wmi_mgmt_tx_send_cmd_fixed_param)); 4454 4455 cmd->vdev_id = param->vdev_id; 4456 4457 cmd->desc_id = param->desc_id; 4458 cmd->chanfreq = param->chanfreq; 4459 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4460 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4461 sizeof(uint32_t))); 4462 bufp += WMI_TLV_HDR_SIZE; 4463 qdf_mem_copy(bufp, param->pdata, bufp_len); 4464 4465 cmd->frame_len = param->frm_len; 4466 cmd->buf_len = bufp_len; 4467 cmd->tx_params_valid = param->tx_params_valid; 4468 cmd->tx_flags = param->tx_flags; 4469 cmd->peer_rssi = param->peer_rssi; 4470 4471 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4472 bufp, cmd->vdev_id, cmd->chanfreq); 4473 4474 bufp += roundup(bufp_len, sizeof(uint32_t)); 4475 if (param->tx_params_valid) { 4476 if (populate_tx_send_params(bufp, param->tx_param) != 4477 QDF_STATUS_SUCCESS) { 4478 wmi_err("Populate TX send params failed"); 4479 goto free_buf; 4480 } 4481 cmd_len += sizeof(wmi_tx_send_params); 4482 } 4483 4484 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4485 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4486 WMI_MGMT_TX_SEND_CMDID)) { 4487 wmi_err("Failed to send mgmt Tx"); 4488 goto free_buf; 4489 } 4490 return QDF_STATUS_SUCCESS; 4491 4492 free_buf: 4493 wmi_buf_free(buf); 4494 return QDF_STATUS_E_FAILURE; 4495 } 4496 #else 4497 /** 4498 * send_mgmt_cmd_tlv() - WMI scan start function 4499 * @wmi_handle : handle to WMI. 4500 * @param : pointer to hold mgmt cmd parameter 4501 * 4502 * Return: 0 on success and -ve on failure. 4503 */ 4504 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4505 struct wmi_mgmt_params *param) 4506 { 4507 wmi_buf_t buf; 4508 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4509 int32_t cmd_len; 4510 uint64_t dma_addr; 4511 void *qdf_ctx = param->qdf_ctx; 4512 uint8_t *bufp; 4513 QDF_STATUS status = QDF_STATUS_SUCCESS; 4514 wmi_mlo_tx_send_params *mlo_params; 4515 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4516 mgmt_tx_dl_frm_len; 4517 4518 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4519 WMI_TLV_HDR_SIZE + 4520 roundup(bufp_len, sizeof(uint32_t)); 4521 4522 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4523 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4524 if (!buf) 4525 return QDF_STATUS_E_NOMEM; 4526 4527 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4528 bufp = (uint8_t *) cmd; 4529 WMITLV_SET_HDR(&cmd->tlv_header, 4530 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4531 WMITLV_GET_STRUCT_TLVLEN 4532 (wmi_mgmt_tx_send_cmd_fixed_param)); 4533 4534 cmd->vdev_id = param->vdev_id; 4535 4536 cmd->desc_id = param->desc_id; 4537 cmd->chanfreq = param->chanfreq; 4538 cmd->peer_rssi = param->peer_rssi; 4539 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4540 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4541 sizeof(uint32_t))); 4542 bufp += WMI_TLV_HDR_SIZE; 4543 4544 /* for big endian host, copy engine byte_swap is enabled 4545 * But the frame content is in network byte order 4546 * Need to byte swap the frame content - so when copy engine 4547 * does byte_swap - target gets frame content in the correct order 4548 */ 4549 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4550 4551 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4552 QDF_DMA_TO_DEVICE); 4553 if (status != QDF_STATUS_SUCCESS) { 4554 wmi_err("wmi buf map failed"); 4555 goto free_buf; 4556 } 4557 4558 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4559 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4560 #if defined(HTT_PADDR64) 4561 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4562 #endif 4563 cmd->frame_len = param->frm_len; 4564 cmd->buf_len = bufp_len; 4565 cmd->tx_params_valid = param->tx_params_valid; 4566 cmd->tx_flags = param->tx_flags; 4567 4568 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4569 bufp, cmd->vdev_id, cmd->chanfreq); 4570 4571 bufp += roundup(bufp_len, sizeof(uint32_t)); 4572 if (param->tx_params_valid) { 4573 status = populate_tx_send_params(bufp, param->tx_param); 4574 if (status != QDF_STATUS_SUCCESS) { 4575 wmi_err("Populate TX send params failed"); 4576 goto unmap_tx_frame; 4577 } 4578 } else { 4579 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4580 WMITLV_TAG_STRUC_wmi_tx_send_params, 4581 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4582 } 4583 4584 /* Even tx_params_valid is false, still need reserve space to pass wmi 4585 * tag check */ 4586 cmd_len += sizeof(wmi_tx_send_params); 4587 bufp += sizeof(wmi_tx_send_params); 4588 /* wmi_mlo_tx_send_params */ 4589 if (param->mlo_link_agnostic) { 4590 wmi_debug("Set mlo mgmt tid"); 4591 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4592 sizeof(wmi_mlo_tx_send_params)); 4593 bufp += WMI_TLV_HDR_SIZE; 4594 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4595 WMITLV_SET_HDR(&mlo_params->tlv_header, 4596 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4597 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4598 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4599 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4600 } 4601 4602 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4603 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4604 WMI_MGMT_TX_SEND_CMDID)) { 4605 wmi_err("Failed to send mgmt Tx"); 4606 goto unmap_tx_frame; 4607 } 4608 return QDF_STATUS_SUCCESS; 4609 4610 unmap_tx_frame: 4611 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4612 QDF_DMA_TO_DEVICE); 4613 free_buf: 4614 wmi_buf_free(buf); 4615 return QDF_STATUS_E_FAILURE; 4616 } 4617 #endif /* CONFIG_HL_SUPPORT */ 4618 4619 /** 4620 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 4621 * @wmi_handle : handle to WMI. 4622 * @param : pointer to offchan data tx cmd parameter 4623 * 4624 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4625 */ 4626 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4627 struct wmi_offchan_data_tx_params *param) 4628 { 4629 wmi_buf_t buf; 4630 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4631 int32_t cmd_len; 4632 uint64_t dma_addr; 4633 void *qdf_ctx = param->qdf_ctx; 4634 uint8_t *bufp; 4635 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4636 param->frm_len : mgmt_tx_dl_frm_len; 4637 QDF_STATUS status = QDF_STATUS_SUCCESS; 4638 4639 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4640 WMI_TLV_HDR_SIZE + 4641 roundup(bufp_len, sizeof(uint32_t)); 4642 4643 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4644 if (!buf) 4645 return QDF_STATUS_E_NOMEM; 4646 4647 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4648 bufp = (uint8_t *) cmd; 4649 WMITLV_SET_HDR(&cmd->tlv_header, 4650 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4651 WMITLV_GET_STRUCT_TLVLEN 4652 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4653 4654 cmd->vdev_id = param->vdev_id; 4655 4656 cmd->desc_id = param->desc_id; 4657 cmd->chanfreq = param->chanfreq; 4658 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4659 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4660 sizeof(uint32_t))); 4661 bufp += WMI_TLV_HDR_SIZE; 4662 qdf_mem_copy(bufp, param->pdata, bufp_len); 4663 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4664 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4665 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4666 #if defined(HTT_PADDR64) 4667 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4668 #endif 4669 cmd->frame_len = param->frm_len; 4670 cmd->buf_len = bufp_len; 4671 cmd->tx_params_valid = param->tx_params_valid; 4672 4673 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4674 bufp, cmd->vdev_id, cmd->chanfreq); 4675 4676 bufp += roundup(bufp_len, sizeof(uint32_t)); 4677 if (param->tx_params_valid) { 4678 status = populate_tx_send_params(bufp, param->tx_param); 4679 if (status != QDF_STATUS_SUCCESS) { 4680 wmi_err("Populate TX send params failed"); 4681 goto err1; 4682 } 4683 cmd_len += sizeof(wmi_tx_send_params); 4684 } 4685 4686 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4687 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4688 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4689 wmi_err("Failed to offchan data Tx"); 4690 goto err1; 4691 } 4692 4693 return QDF_STATUS_SUCCESS; 4694 4695 err1: 4696 wmi_buf_free(buf); 4697 return QDF_STATUS_E_FAILURE; 4698 } 4699 4700 /** 4701 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4702 * @wmi_handle: wmi handle 4703 * @param_value: parameter value 4704 * 4705 * Return: QDF_STATUS_SUCCESS for success or error code 4706 */ 4707 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4708 uint32_t param_value) 4709 { 4710 QDF_STATUS ret; 4711 wmi_modem_power_state_cmd_param *cmd; 4712 wmi_buf_t buf; 4713 uint16_t len = sizeof(*cmd); 4714 4715 buf = wmi_buf_alloc(wmi_handle, len); 4716 if (!buf) 4717 return QDF_STATUS_E_NOMEM; 4718 4719 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4720 WMITLV_SET_HDR(&cmd->tlv_header, 4721 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4722 WMITLV_GET_STRUCT_TLVLEN 4723 (wmi_modem_power_state_cmd_param)); 4724 cmd->modem_power_state = param_value; 4725 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4726 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4727 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4728 WMI_MODEM_POWER_STATE_CMDID); 4729 if (QDF_IS_STATUS_ERROR(ret)) { 4730 wmi_err("Failed to send notify cmd ret = %d", ret); 4731 wmi_buf_free(buf); 4732 } 4733 4734 return ret; 4735 } 4736 4737 /** 4738 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4739 * @wmi_handle: wmi handle 4740 * @vdev_id: vdev id 4741 * @val: value 4742 * 4743 * Return: QDF_STATUS_SUCCESS for success or error code. 4744 */ 4745 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4746 uint32_t vdev_id, uint8_t val) 4747 { 4748 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 4749 wmi_buf_t buf; 4750 int32_t len = sizeof(*cmd); 4751 4752 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 4753 4754 buf = wmi_buf_alloc(wmi_handle, len); 4755 if (!buf) 4756 return QDF_STATUS_E_NOMEM; 4757 4758 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 4759 WMITLV_SET_HDR(&cmd->tlv_header, 4760 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 4761 WMITLV_GET_STRUCT_TLVLEN 4762 (wmi_sta_powersave_mode_cmd_fixed_param)); 4763 cmd->vdev_id = vdev_id; 4764 if (val) 4765 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 4766 else 4767 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 4768 4769 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 4770 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4771 WMI_STA_POWERSAVE_MODE_CMDID)) { 4772 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 4773 vdev_id, val); 4774 wmi_buf_free(buf); 4775 return QDF_STATUS_E_FAILURE; 4776 } 4777 return QDF_STATUS_SUCCESS; 4778 } 4779 4780 /** 4781 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 4782 * @wmi_handle: wmi handle 4783 * @vdev_id: vdev id 4784 * 4785 * Return: QDF_STATUS_SUCCESS for success or error code. 4786 */ 4787 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 4788 uint8_t val) 4789 { 4790 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 4791 wmi_buf_t buf; 4792 size_t len = sizeof(*cmd); 4793 4794 buf = wmi_buf_alloc(wmi_handle, len); 4795 if (!buf) 4796 return QDF_STATUS_E_NOMEM; 4797 4798 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 4799 WMITLV_SET_HDR(&cmd->tlv_header, 4800 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 4801 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 4802 4803 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 4804 WMI_IDLE_TRIGGER_MONITOR_OFF); 4805 4806 wmi_debug("val: %d", cmd->idle_trigger_monitor); 4807 4808 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4809 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 4810 wmi_buf_free(buf); 4811 return QDF_STATUS_E_FAILURE; 4812 } 4813 return QDF_STATUS_SUCCESS; 4814 } 4815 4816 /** 4817 * send_set_mimops_cmd_tlv() - set MIMO powersave 4818 * @wmi_handle: wmi handle 4819 * @vdev_id: vdev id 4820 * @value: value 4821 * 4822 * Return: QDF_STATUS_SUCCESS for success or error code. 4823 */ 4824 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 4825 uint8_t vdev_id, int value) 4826 { 4827 QDF_STATUS ret; 4828 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 4829 wmi_buf_t buf; 4830 uint16_t len = sizeof(*cmd); 4831 4832 buf = wmi_buf_alloc(wmi_handle, len); 4833 if (!buf) 4834 return QDF_STATUS_E_NOMEM; 4835 4836 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4837 WMITLV_SET_HDR(&cmd->tlv_header, 4838 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4839 WMITLV_GET_STRUCT_TLVLEN 4840 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4841 4842 cmd->vdev_id = vdev_id; 4843 4844 /* WMI_SMPS_FORCED_MODE values do not directly map 4845 * to SM power save values defined in the specification. 4846 * Make sure to send the right mapping. 4847 */ 4848 switch (value) { 4849 case 0: 4850 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4851 break; 4852 case 1: 4853 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4854 break; 4855 case 2: 4856 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4857 break; 4858 case 3: 4859 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4860 break; 4861 default: 4862 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4863 wmi_buf_free(buf); 4864 return QDF_STATUS_E_FAILURE; 4865 } 4866 4867 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4868 4869 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4870 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4871 WMI_STA_SMPS_FORCE_MODE_CMDID); 4872 if (QDF_IS_STATUS_ERROR(ret)) { 4873 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4874 wmi_buf_free(buf); 4875 } 4876 4877 return ret; 4878 } 4879 4880 /** 4881 * send_set_smps_params_cmd_tlv() - set smps params 4882 * @wmi_handle: wmi handle 4883 * @vdev_id: vdev id 4884 * @value: value 4885 * 4886 * Return: QDF_STATUS_SUCCESS for success or error code. 4887 */ 4888 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4889 int value) 4890 { 4891 QDF_STATUS ret; 4892 wmi_sta_smps_param_cmd_fixed_param *cmd; 4893 wmi_buf_t buf; 4894 uint16_t len = sizeof(*cmd); 4895 4896 buf = wmi_buf_alloc(wmi_handle, len); 4897 if (!buf) 4898 return QDF_STATUS_E_NOMEM; 4899 4900 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4901 WMITLV_SET_HDR(&cmd->tlv_header, 4902 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4903 WMITLV_GET_STRUCT_TLVLEN 4904 (wmi_sta_smps_param_cmd_fixed_param)); 4905 4906 cmd->vdev_id = vdev_id; 4907 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4908 cmd->param = 4909 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4910 4911 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4912 cmd->param); 4913 4914 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4915 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4916 WMI_STA_SMPS_PARAM_CMDID); 4917 if (QDF_IS_STATUS_ERROR(ret)) { 4918 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4919 wmi_buf_free(buf); 4920 } 4921 4922 return ret; 4923 } 4924 4925 /** 4926 * send_get_temperature_cmd_tlv() - get pdev temperature req 4927 * @wmi_handle: wmi handle 4928 * 4929 * Return: QDF_STATUS_SUCCESS for success or error code. 4930 */ 4931 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4932 { 4933 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4934 wmi_buf_t wmi_buf; 4935 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4936 uint8_t *buf_ptr; 4937 4938 if (!wmi_handle) { 4939 wmi_err("WMI is closed, can not issue cmd"); 4940 return QDF_STATUS_E_INVAL; 4941 } 4942 4943 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4944 if (!wmi_buf) 4945 return QDF_STATUS_E_NOMEM; 4946 4947 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4948 4949 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4950 WMITLV_SET_HDR(&cmd->tlv_header, 4951 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4952 WMITLV_GET_STRUCT_TLVLEN 4953 (wmi_pdev_get_temperature_cmd_fixed_param)); 4954 4955 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4956 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4957 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4958 wmi_err("Failed to send get temperature command"); 4959 wmi_buf_free(wmi_buf); 4960 return QDF_STATUS_E_FAILURE; 4961 } 4962 4963 return QDF_STATUS_SUCCESS; 4964 } 4965 4966 /** 4967 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4968 * @wmi_handle: wmi handle 4969 * @vdevid: vdev id 4970 * @peer_addr: peer mac address 4971 * @auto_triggerparam: auto trigger parameters 4972 * @num_ac: number of access category 4973 * 4974 * This function sets the trigger 4975 * uapsd params such as service interval, delay interval 4976 * and suspend interval which will be used by the firmware 4977 * to send trigger frames periodically when there is no 4978 * traffic on the transmit side. 4979 * 4980 * Return: QDF_STATUS_SUCCESS for success or error code. 4981 */ 4982 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4983 struct sta_uapsd_trig_params *param) 4984 { 4985 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4986 QDF_STATUS ret; 4987 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4988 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4989 uint32_t i; 4990 wmi_buf_t buf; 4991 uint8_t *buf_ptr; 4992 struct sta_uapsd_params *uapsd_param; 4993 wmi_sta_uapsd_auto_trig_param *trig_param; 4994 4995 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4996 if (!buf) 4997 return QDF_STATUS_E_NOMEM; 4998 4999 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5000 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5001 WMITLV_SET_HDR(&cmd->tlv_header, 5002 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5003 WMITLV_GET_STRUCT_TLVLEN 5004 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5005 cmd->vdev_id = param->vdevid; 5006 cmd->num_ac = param->num_ac; 5007 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5008 5009 /* TLV indicating array of structures to follow */ 5010 buf_ptr += sizeof(*cmd); 5011 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5012 5013 buf_ptr += WMI_TLV_HDR_SIZE; 5014 5015 /* 5016 * Update tag and length for uapsd auto trigger params (this will take 5017 * care of updating tag and length if it is not pre-filled by caller). 5018 */ 5019 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5020 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5021 for (i = 0; i < param->num_ac; i++) { 5022 WMITLV_SET_HDR((buf_ptr + 5023 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5024 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5025 WMITLV_GET_STRUCT_TLVLEN 5026 (wmi_sta_uapsd_auto_trig_param)); 5027 trig_param->wmm_ac = uapsd_param->wmm_ac; 5028 trig_param->user_priority = uapsd_param->user_priority; 5029 trig_param->service_interval = uapsd_param->service_interval; 5030 trig_param->suspend_interval = uapsd_param->suspend_interval; 5031 trig_param->delay_interval = uapsd_param->delay_interval; 5032 trig_param++; 5033 uapsd_param++; 5034 } 5035 5036 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5037 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5038 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5039 if (QDF_IS_STATUS_ERROR(ret)) { 5040 wmi_err("Failed to send set uapsd param ret = %d", ret); 5041 wmi_buf_free(buf); 5042 } 5043 5044 return ret; 5045 } 5046 5047 /** 5048 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5049 * @wmi_handle: Pointer to wmi handle 5050 * @thermal_info: Thermal command information 5051 * 5052 * This function sends the thermal management command 5053 * to the firmware 5054 * 5055 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5056 */ 5057 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5058 struct thermal_cmd_params *thermal_info) 5059 { 5060 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5061 wmi_buf_t buf = NULL; 5062 QDF_STATUS status; 5063 uint32_t len = 0; 5064 uint8_t action; 5065 5066 switch (thermal_info->thermal_action) { 5067 case THERMAL_MGMT_ACTION_DEFAULT: 5068 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5069 break; 5070 5071 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5072 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5073 break; 5074 5075 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5076 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5077 break; 5078 5079 case THERMAL_MGMT_ACTION_CHAINSCALING: 5080 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5081 break; 5082 5083 default: 5084 wmi_err("Invalid thermal_action code %d", 5085 thermal_info->thermal_action); 5086 return QDF_STATUS_E_FAILURE; 5087 } 5088 5089 len = sizeof(*cmd); 5090 5091 buf = wmi_buf_alloc(wmi_handle, len); 5092 if (!buf) 5093 return QDF_STATUS_E_FAILURE; 5094 5095 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5096 5097 WMITLV_SET_HDR(&cmd->tlv_header, 5098 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5099 WMITLV_GET_STRUCT_TLVLEN 5100 (wmi_thermal_mgmt_cmd_fixed_param)); 5101 5102 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5103 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5104 cmd->enable = thermal_info->thermal_enable; 5105 cmd->action = action; 5106 5107 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5108 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5109 cmd->enable, cmd->action); 5110 5111 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5112 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5113 WMI_THERMAL_MGMT_CMDID); 5114 if (QDF_IS_STATUS_ERROR(status)) { 5115 wmi_buf_free(buf); 5116 wmi_err("Failed to send thermal mgmt command"); 5117 } 5118 5119 return status; 5120 } 5121 5122 /** 5123 * send_lro_config_cmd_tlv() - process the LRO config command 5124 * @wmi_handle: Pointer to WMI handle 5125 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5126 * 5127 * This function sends down the LRO configuration parameters to 5128 * the firmware to enable LRO, sets the TCP flags and sets the 5129 * seed values for the toeplitz hash generation 5130 * 5131 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5132 */ 5133 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5134 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5135 { 5136 wmi_lro_info_cmd_fixed_param *cmd; 5137 wmi_buf_t buf; 5138 QDF_STATUS status; 5139 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5140 5141 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5142 if (!buf) 5143 return QDF_STATUS_E_FAILURE; 5144 5145 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5146 5147 WMITLV_SET_HDR(&cmd->tlv_header, 5148 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5149 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5150 5151 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5152 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5153 wmi_lro_cmd->tcp_flag); 5154 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5155 wmi_lro_cmd->tcp_flag_mask); 5156 cmd->toeplitz_hash_ipv4_0_3 = 5157 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5158 cmd->toeplitz_hash_ipv4_4_7 = 5159 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5160 cmd->toeplitz_hash_ipv4_8_11 = 5161 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5162 cmd->toeplitz_hash_ipv4_12_15 = 5163 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5164 cmd->toeplitz_hash_ipv4_16 = 5165 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5166 5167 cmd->toeplitz_hash_ipv6_0_3 = 5168 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5169 cmd->toeplitz_hash_ipv6_4_7 = 5170 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5171 cmd->toeplitz_hash_ipv6_8_11 = 5172 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5173 cmd->toeplitz_hash_ipv6_12_15 = 5174 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5175 cmd->toeplitz_hash_ipv6_16_19 = 5176 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5177 cmd->toeplitz_hash_ipv6_20_23 = 5178 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5179 cmd->toeplitz_hash_ipv6_24_27 = 5180 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5181 cmd->toeplitz_hash_ipv6_28_31 = 5182 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5183 cmd->toeplitz_hash_ipv6_32_35 = 5184 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5185 cmd->toeplitz_hash_ipv6_36_39 = 5186 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5187 cmd->toeplitz_hash_ipv6_40 = 5188 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5189 5190 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5191 wmi_handle, 5192 pdev_id); 5193 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5194 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5195 5196 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5197 status = wmi_unified_cmd_send(wmi_handle, buf, 5198 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5199 if (QDF_IS_STATUS_ERROR(status)) { 5200 wmi_buf_free(buf); 5201 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5202 } 5203 5204 return status; 5205 } 5206 5207 /** 5208 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5209 * @wmi_handle: Pointer to wmi handle 5210 * @rate_report_params: Pointer to peer rate report parameters 5211 * 5212 * 5213 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5214 */ 5215 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5216 struct wmi_peer_rate_report_params *rate_report_params) 5217 { 5218 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5219 wmi_buf_t buf = NULL; 5220 QDF_STATUS status = 0; 5221 uint32_t len = 0; 5222 uint32_t i, j; 5223 5224 len = sizeof(*cmd); 5225 5226 buf = wmi_buf_alloc(wmi_handle, len); 5227 if (!buf) 5228 return QDF_STATUS_E_FAILURE; 5229 5230 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5231 wmi_buf_data(buf); 5232 5233 WMITLV_SET_HDR( 5234 &cmd->tlv_header, 5235 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5236 WMITLV_GET_STRUCT_TLVLEN( 5237 wmi_peer_set_rate_report_condition_fixed_param)); 5238 5239 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5240 cmd->report_backoff_time = rate_report_params->backoff_time; 5241 cmd->report_timer_period = rate_report_params->timer_period; 5242 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5243 cmd->cond_per_phy[i].val_cond_flags = 5244 rate_report_params->report_per_phy[i].cond_flags; 5245 cmd->cond_per_phy[i].rate_delta.min_delta = 5246 rate_report_params->report_per_phy[i].delta.delta_min; 5247 cmd->cond_per_phy[i].rate_delta.percentage = 5248 rate_report_params->report_per_phy[i].delta.percent; 5249 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5250 cmd->cond_per_phy[i].rate_threshold[j] = 5251 rate_report_params->report_per_phy[i]. 5252 report_rate_threshold[j]; 5253 } 5254 } 5255 5256 wmi_debug("enable %d backoff_time %d period %d", 5257 cmd->enable_rate_report, 5258 cmd->report_backoff_time, cmd->report_timer_period); 5259 5260 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5261 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5262 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5263 if (QDF_IS_STATUS_ERROR(status)) { 5264 wmi_buf_free(buf); 5265 wmi_err("Failed to send peer_set_report_cond command"); 5266 } 5267 return status; 5268 } 5269 5270 /** 5271 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5272 * @wmi_handle: wmi handle 5273 * @vdev_id: vdev id. 5274 * @wmm_vparams: edca parameters 5275 * 5276 * This function updates EDCA parameters to the target 5277 * 5278 * Return: CDF Status 5279 */ 5280 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5281 uint8_t vdev_id, bool mu_edca_param, 5282 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5283 { 5284 uint8_t *buf_ptr; 5285 wmi_buf_t buf; 5286 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5287 wmi_wmm_vparams *wmm_param; 5288 struct wmi_host_wme_vparams *twmm_param; 5289 int len = sizeof(*cmd); 5290 int ac; 5291 5292 buf = wmi_buf_alloc(wmi_handle, len); 5293 5294 if (!buf) 5295 return QDF_STATUS_E_NOMEM; 5296 5297 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5298 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5299 WMITLV_SET_HDR(&cmd->tlv_header, 5300 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5301 WMITLV_GET_STRUCT_TLVLEN 5302 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5303 cmd->vdev_id = vdev_id; 5304 cmd->wmm_param_type = mu_edca_param; 5305 5306 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5307 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5308 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5309 WMITLV_SET_HDR(&wmm_param->tlv_header, 5310 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5311 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5312 wmm_param->cwmin = twmm_param->cwmin; 5313 wmm_param->cwmax = twmm_param->cwmax; 5314 wmm_param->aifs = twmm_param->aifs; 5315 if (mu_edca_param) 5316 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5317 else 5318 wmm_param->txoplimit = twmm_param->txoplimit; 5319 wmm_param->acm = twmm_param->acm; 5320 wmm_param->no_ack = twmm_param->noackpolicy; 5321 } 5322 5323 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5324 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5325 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5326 goto fail; 5327 5328 return QDF_STATUS_SUCCESS; 5329 5330 fail: 5331 wmi_buf_free(buf); 5332 wmi_err("Failed to set WMM Parameters"); 5333 return QDF_STATUS_E_FAILURE; 5334 } 5335 5336 /** 5337 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5338 * @wmi_handle: wmi handle 5339 * @vdev_id: vdev id 5340 * @probe_rsp_info: probe response info 5341 * 5342 * Return: QDF_STATUS_SUCCESS for success or error code 5343 */ 5344 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5345 uint8_t vdev_id, 5346 struct wmi_probe_resp_params *probe_rsp_info) 5347 { 5348 wmi_prb_tmpl_cmd_fixed_param *cmd; 5349 wmi_bcn_prb_info *bcn_prb_info; 5350 wmi_buf_t wmi_buf; 5351 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5352 uint8_t *buf_ptr; 5353 QDF_STATUS ret; 5354 5355 wmi_debug("Send probe response template for vdev %d", vdev_id); 5356 5357 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5358 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5359 5360 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5361 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5362 tmpl_len_aligned; 5363 5364 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5365 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5366 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5367 return QDF_STATUS_E_INVAL; 5368 } 5369 5370 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5371 if (!wmi_buf) 5372 return QDF_STATUS_E_NOMEM; 5373 5374 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5375 5376 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5377 WMITLV_SET_HDR(&cmd->tlv_header, 5378 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5379 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5380 cmd->vdev_id = vdev_id; 5381 cmd->buf_len = tmpl_len; 5382 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5383 5384 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5385 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5386 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5387 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5388 bcn_prb_info->caps = 0; 5389 bcn_prb_info->erp = 0; 5390 buf_ptr += sizeof(wmi_bcn_prb_info); 5391 5392 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5393 buf_ptr += WMI_TLV_HDR_SIZE; 5394 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5395 5396 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5397 ret = wmi_unified_cmd_send(wmi_handle, 5398 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5399 if (QDF_IS_STATUS_ERROR(ret)) { 5400 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5401 wmi_buf_free(wmi_buf); 5402 } 5403 5404 return ret; 5405 } 5406 5407 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5408 #define WPI_IV_LEN 16 5409 5410 /** 5411 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5412 * 5413 * @dest_tx: destination address of tsc key counter 5414 * @src_tx: source address of tsc key counter 5415 * @dest_rx: destination address of rsc key counter 5416 * @src_rx: source address of rsc key counter 5417 * 5418 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5419 * 5420 * Return: None 5421 * 5422 */ 5423 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5424 uint8_t *dest_rx, uint8_t *src_rx) 5425 { 5426 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5427 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5428 } 5429 #else 5430 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5431 uint8_t *dest_rx, uint8_t *src_rx) 5432 { 5433 return; 5434 } 5435 #endif 5436 5437 /** 5438 * send_setup_install_key_cmd_tlv() - set key parameters 5439 * @wmi_handle: wmi handle 5440 * @key_params: key parameters 5441 * 5442 * This function fills structure from information 5443 * passed in key_params. 5444 * 5445 * Return: QDF_STATUS_SUCCESS - success 5446 * QDF_STATUS_E_FAILURE - failure 5447 * QDF_STATUS_E_NOMEM - not able to allocate buffer 5448 */ 5449 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 5450 struct set_key_params *key_params) 5451 { 5452 wmi_vdev_install_key_cmd_fixed_param *cmd; 5453 wmi_buf_t buf; 5454 uint8_t *buf_ptr; 5455 uint32_t len; 5456 uint8_t *key_data; 5457 QDF_STATUS status; 5458 5459 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 5460 WMI_TLV_HDR_SIZE; 5461 5462 buf = wmi_buf_alloc(wmi_handle, len); 5463 if (!buf) 5464 return QDF_STATUS_E_NOMEM; 5465 5466 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5467 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 5468 WMITLV_SET_HDR(&cmd->tlv_header, 5469 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 5470 WMITLV_GET_STRUCT_TLVLEN 5471 (wmi_vdev_install_key_cmd_fixed_param)); 5472 cmd->vdev_id = key_params->vdev_id; 5473 cmd->key_ix = key_params->key_idx; 5474 if (key_params->group_key_idx) { 5475 cmd->is_group_key_ix_valid = 1; 5476 cmd->group_key_ix = key_params->group_key_idx; 5477 } 5478 5479 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 5480 cmd->key_flags |= key_params->key_flags; 5481 cmd->key_cipher = key_params->key_cipher; 5482 if ((key_params->key_txmic_len) && 5483 (key_params->key_rxmic_len)) { 5484 cmd->key_txmic_len = key_params->key_txmic_len; 5485 cmd->key_rxmic_len = key_params->key_rxmic_len; 5486 } 5487 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5488 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 5489 key_params->tx_iv, 5490 cmd->wpi_key_rsc_counter, 5491 key_params->rx_iv); 5492 #endif 5493 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 5494 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 5495 roundup(key_params->key_len, sizeof(uint32_t))); 5496 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 5497 5498 /* for big endian host, copy engine byte_swap is enabled 5499 * But key_data is in network byte order 5500 * Need to byte swap the key_data - so when copy engine 5501 * does byte_swap - target gets key_data in the correct order 5502 */ 5503 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 5504 (const void *)key_params->key_data, 5505 key_params->key_len); 5506 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 5507 sizeof(wmi_key_seq_counter)); 5508 cmd->key_len = key_params->key_len; 5509 5510 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 5511 sizeof(wmi_key_seq_counter)); 5512 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 5513 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5514 WMI_VDEV_INSTALL_KEY_CMDID); 5515 if (QDF_IS_STATUS_ERROR(status)) { 5516 qdf_mem_zero(wmi_buf_data(buf), len); 5517 wmi_buf_free(buf); 5518 } 5519 return status; 5520 } 5521 5522 /** 5523 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 5524 * @wmi_handle: wmi handle 5525 * @vdev_id: vdev id 5526 * @p2p_ie: p2p IE 5527 * 5528 * Return: QDF_STATUS_SUCCESS for success or error code 5529 */ 5530 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 5531 uint32_t vdev_id, uint8_t *p2p_ie) 5532 { 5533 QDF_STATUS ret; 5534 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 5535 wmi_buf_t wmi_buf; 5536 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 5537 uint8_t *buf_ptr; 5538 5539 ie_len = (uint32_t) (p2p_ie[1] + 2); 5540 5541 /* More than one P2P IE may be included in a single frame. 5542 If multiple P2P IEs are present, the complete P2P attribute 5543 data consists of the concatenation of the P2P Attribute 5544 fields of the P2P IEs. The P2P Attributes field of each 5545 P2P IE may be any length up to the maximum (251 octets). 5546 In this case host sends one P2P IE to firmware so the length 5547 should not exceed more than 251 bytes 5548 */ 5549 if (ie_len > 251) { 5550 wmi_err("Invalid p2p ie length %u", ie_len); 5551 return QDF_STATUS_E_INVAL; 5552 } 5553 5554 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 5555 5556 wmi_buf_len = 5557 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 5558 WMI_TLV_HDR_SIZE; 5559 5560 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5561 if (!wmi_buf) 5562 return QDF_STATUS_E_NOMEM; 5563 5564 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5565 5566 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 5567 WMITLV_SET_HDR(&cmd->tlv_header, 5568 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 5569 WMITLV_GET_STRUCT_TLVLEN 5570 (wmi_p2p_go_set_beacon_ie_fixed_param)); 5571 cmd->vdev_id = vdev_id; 5572 cmd->ie_buf_len = ie_len; 5573 5574 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 5575 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 5576 buf_ptr += WMI_TLV_HDR_SIZE; 5577 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 5578 5579 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 5580 5581 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 5582 ret = wmi_unified_cmd_send(wmi_handle, 5583 wmi_buf, wmi_buf_len, 5584 WMI_P2P_GO_SET_BEACON_IE); 5585 if (QDF_IS_STATUS_ERROR(ret)) { 5586 wmi_err("Failed to send bcn tmpl: %d", ret); 5587 wmi_buf_free(wmi_buf); 5588 } 5589 5590 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 5591 return ret; 5592 } 5593 5594 /** 5595 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 5596 * @wmi_handle: wmi handle 5597 * @psetoui: OUI parameters 5598 * 5599 * set scan probe OUI parameters in firmware 5600 * 5601 * Return: CDF status 5602 */ 5603 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 5604 struct scan_mac_oui *psetoui) 5605 { 5606 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 5607 wmi_buf_t wmi_buf; 5608 uint32_t len; 5609 uint8_t *buf_ptr; 5610 uint32_t *oui_buf; 5611 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 5612 5613 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 5614 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 5615 5616 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5617 if (!wmi_buf) 5618 return QDF_STATUS_E_NOMEM; 5619 5620 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5621 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 5622 WMITLV_SET_HDR(&cmd->tlv_header, 5623 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 5624 WMITLV_GET_STRUCT_TLVLEN 5625 (wmi_scan_prob_req_oui_cmd_fixed_param)); 5626 5627 oui_buf = &cmd->prob_req_oui; 5628 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 5629 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 5630 | psetoui->oui[2]; 5631 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 5632 5633 cmd->vdev_id = psetoui->vdev_id; 5634 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 5635 if (psetoui->enb_probe_req_sno_randomization) 5636 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 5637 5638 if (ie_allowlist->allow_list) { 5639 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 5640 &cmd->num_vendor_oui, 5641 ie_allowlist); 5642 cmd->flags |= 5643 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5644 } 5645 5646 buf_ptr += sizeof(*cmd); 5647 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5648 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5649 buf_ptr += WMI_TLV_HDR_SIZE; 5650 5651 if (cmd->num_vendor_oui != 0) { 5652 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5653 ie_allowlist->voui); 5654 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5655 } 5656 5657 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 5658 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5659 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 5660 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 5661 wmi_buf_free(wmi_buf); 5662 return QDF_STATUS_E_FAILURE; 5663 } 5664 return QDF_STATUS_SUCCESS; 5665 } 5666 5667 #ifdef IPA_OFFLOAD 5668 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 5669 * @wmi_handle: wmi handle 5670 * @ipa_offload: ipa offload control parameter 5671 * 5672 * Returns: 0 on success, error number otherwise 5673 */ 5674 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 5675 struct ipa_uc_offload_control_params *ipa_offload) 5676 { 5677 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 5678 wmi_buf_t wmi_buf; 5679 uint32_t len; 5680 u_int8_t *buf_ptr; 5681 5682 len = sizeof(*cmd); 5683 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5684 if (!wmi_buf) 5685 return QDF_STATUS_E_NOMEM; 5686 5687 wmi_debug("offload_type=%d, enable=%d", 5688 ipa_offload->offload_type, ipa_offload->enable); 5689 5690 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 5691 5692 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 5693 WMITLV_SET_HDR(&cmd->tlv_header, 5694 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 5695 WMITLV_GET_STRUCT_TLVLEN( 5696 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 5697 5698 cmd->offload_type = ipa_offload->offload_type; 5699 cmd->vdev_id = ipa_offload->vdev_id; 5700 cmd->enable = ipa_offload->enable; 5701 5702 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 5703 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5704 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 5705 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 5706 wmi_buf_free(wmi_buf); 5707 return QDF_STATUS_E_FAILURE; 5708 } 5709 5710 return QDF_STATUS_SUCCESS; 5711 } 5712 #endif 5713 5714 /** 5715 * send_pno_stop_cmd_tlv() - PNO stop request 5716 * @wmi_handle: wmi handle 5717 * @vdev_id: vdev id 5718 * 5719 * This function request FW to stop ongoing PNO operation. 5720 * 5721 * Return: CDF status 5722 */ 5723 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5724 { 5725 wmi_nlo_config_cmd_fixed_param *cmd; 5726 int32_t len = sizeof(*cmd); 5727 wmi_buf_t buf; 5728 uint8_t *buf_ptr; 5729 int ret; 5730 5731 /* 5732 * TLV place holder for array of structures nlo_configured_parameters 5733 * TLV place holder for array of uint32_t channel_list 5734 * TLV place holder for chnl prediction cfg 5735 */ 5736 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5737 buf = wmi_buf_alloc(wmi_handle, len); 5738 if (!buf) 5739 return QDF_STATUS_E_NOMEM; 5740 5741 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5742 buf_ptr = (uint8_t *) cmd; 5743 5744 WMITLV_SET_HDR(&cmd->tlv_header, 5745 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5746 WMITLV_GET_STRUCT_TLVLEN 5747 (wmi_nlo_config_cmd_fixed_param)); 5748 5749 cmd->vdev_id = vdev_id; 5750 cmd->flags = WMI_NLO_CONFIG_STOP; 5751 buf_ptr += sizeof(*cmd); 5752 5753 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5754 buf_ptr += WMI_TLV_HDR_SIZE; 5755 5756 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 5757 buf_ptr += WMI_TLV_HDR_SIZE; 5758 5759 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 5760 buf_ptr += WMI_TLV_HDR_SIZE; 5761 5762 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5763 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5764 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5765 if (ret) { 5766 wmi_err("Failed to send nlo wmi cmd"); 5767 wmi_buf_free(buf); 5768 return QDF_STATUS_E_FAILURE; 5769 } 5770 5771 return QDF_STATUS_SUCCESS; 5772 } 5773 5774 /** 5775 * send_obss_disable_cmd_tlv() - disable obss scan request 5776 * @wmi_handle: wmi handle 5777 * @vdev_id: vdev id 5778 * 5779 * This function request FW to disable ongoing obss scan operation. 5780 * 5781 * Return: QDF status 5782 */ 5783 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 5784 uint8_t vdev_id) 5785 { 5786 QDF_STATUS status; 5787 wmi_buf_t buf; 5788 wmi_obss_scan_disable_cmd_fixed_param *cmd; 5789 int len = sizeof(*cmd); 5790 5791 buf = wmi_buf_alloc(wmi_handle, len); 5792 if (!buf) 5793 return QDF_STATUS_E_NOMEM; 5794 5795 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 5796 5797 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 5798 WMITLV_SET_HDR(&cmd->tlv_header, 5799 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 5800 WMITLV_GET_STRUCT_TLVLEN( 5801 wmi_obss_scan_disable_cmd_fixed_param)); 5802 5803 cmd->vdev_id = vdev_id; 5804 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5805 WMI_OBSS_SCAN_DISABLE_CMDID); 5806 if (QDF_IS_STATUS_ERROR(status)) 5807 wmi_buf_free(buf); 5808 5809 return status; 5810 } 5811 5812 /** 5813 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 5814 * @buf_ptr: Buffer passed by upper layers 5815 * @pno: Buffer to be sent to the firmware 5816 * 5817 * Copy the PNO Channel prediction configuration parameters 5818 * passed by the upper layers to a WMI format TLV and send it 5819 * down to the firmware. 5820 * 5821 * Return: None 5822 */ 5823 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 5824 struct pno_scan_req_params *pno) 5825 { 5826 nlo_channel_prediction_cfg *channel_prediction_cfg = 5827 (nlo_channel_prediction_cfg *) buf_ptr; 5828 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 5829 WMITLV_TAG_ARRAY_BYTE, 5830 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 5831 #ifdef FEATURE_WLAN_SCAN_PNO 5832 channel_prediction_cfg->enable = pno->pno_channel_prediction; 5833 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 5834 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5835 channel_prediction_cfg->full_scan_period_ms = 5836 pno->channel_prediction_full_scan; 5837 #endif 5838 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5839 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5840 channel_prediction_cfg->enable, 5841 channel_prediction_cfg->top_k_num, 5842 channel_prediction_cfg->stationary_threshold, 5843 channel_prediction_cfg->full_scan_period_ms); 5844 } 5845 5846 /** 5847 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5848 * @wmi_handle: wmi handle 5849 * @buf_ptr: Buffer passed by upper layers 5850 * @buf_len: Length of passed buffer by upper layer 5851 * 5852 * Copy the buffer passed by the upper layers and send it 5853 * down to the firmware. 5854 * 5855 * Return: None 5856 */ 5857 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5858 void *buf_ptr, uint32_t buf_len) 5859 { 5860 wmi_buf_t buf = NULL; 5861 QDF_STATUS status; 5862 int len; 5863 uint8_t *data_ptr; 5864 5865 len = buf_len; 5866 buf = wmi_buf_alloc(wmi_handle, len); 5867 if (!buf) 5868 return QDF_STATUS_E_NOMEM; 5869 5870 data_ptr = (uint8_t *)wmi_buf_data(buf); 5871 qdf_mem_copy(data_ptr, buf_ptr, len); 5872 5873 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5874 status = wmi_unified_cmd_send(wmi_handle, buf, 5875 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5876 5877 if (QDF_IS_STATUS_ERROR(status)) { 5878 wmi_buf_free(buf); 5879 return QDF_STATUS_E_FAILURE; 5880 } 5881 return QDF_STATUS_SUCCESS; 5882 } 5883 5884 /** 5885 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 5886 * @wmi_handle: wmi handle 5887 * @buf_ptr: Buffer passed by upper layers 5888 * @buf_len: Length of passed buffer by upper layer 5889 * 5890 * Copy the buffer passed by the upper layers and send it 5891 * down to the firmware. 5892 * 5893 * Return: None 5894 */ 5895 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 5896 void *buf_ptr, uint32_t buf_len) 5897 { 5898 wmi_buf_t buf = NULL; 5899 QDF_STATUS status; 5900 int len; 5901 uint8_t *data_ptr; 5902 5903 len = buf_len; 5904 buf = wmi_buf_alloc(wmi_handle, len); 5905 if (!buf) 5906 return QDF_STATUS_E_NOMEM; 5907 5908 data_ptr = (uint8_t *)wmi_buf_data(buf); 5909 qdf_mem_copy(data_ptr, buf_ptr, len); 5910 5911 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5912 status = wmi_unified_cmd_send(wmi_handle, buf, 5913 len, 5914 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 5915 5916 if (QDF_IS_STATUS_ERROR(status)) { 5917 wmi_buf_free(buf); 5918 return QDF_STATUS_E_FAILURE; 5919 } 5920 return QDF_STATUS_SUCCESS; 5921 } 5922 5923 /** 5924 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5925 * @wmi_handle: wmi handle 5926 * @evt_buf: event buffer 5927 * @more_flag: buffer to populate more flag 5928 * 5929 * Return: status of operation 5930 */ 5931 static QDF_STATUS 5932 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5933 uint32_t *more_flag) 5934 { 5935 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5936 wmi_ctrl_path_stats_event_fixed_param *ev; 5937 5938 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5939 if (!param_buf) { 5940 wmi_err_rl("param_buf is NULL"); 5941 return QDF_STATUS_E_FAILURE; 5942 } 5943 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5944 5945 *more_flag = ev->more; 5946 return QDF_STATUS_SUCCESS; 5947 } 5948 5949 /** 5950 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 5951 * from event data 5952 * @wmi_handle: wmi handle 5953 * @evt_buf: event buffer 5954 * @end_of_event_flag: buffer to populate end_of_event flag 5955 * 5956 * Return: status of operation 5957 */ 5958 static QDF_STATUS 5959 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi, void *evt_buf, 5960 uint32_t *end_of_event_flag) 5961 { 5962 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5963 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5964 5965 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5966 if (!param_buf) { 5967 wmi_err_rl("param_buf is NULL"); 5968 return QDF_STATUS_E_FAILURE; 5969 } 5970 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5971 param_buf->fixed_param; 5972 5973 *end_of_event_flag = ev->end_of_event; 5974 return QDF_STATUS_SUCCESS; 5975 } 5976 5977 /** 5978 * extract_halphy_stats_event_count - api to extract event count flag from 5979 * event data 5980 * @wmi_handle: wmi handle 5981 * @evt_buf: event buffer 5982 * @event_count_flag: buffer to populate event_count flag 5983 * 5984 * Return: status of operation 5985 */ 5986 static QDF_STATUS 5987 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi, void *evt_buf, 5988 uint32_t *event_count_flag) 5989 { 5990 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5991 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 5992 5993 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5994 if (!param_buf) { 5995 wmi_err_rl("param_buf is NULL"); 5996 return QDF_STATUS_E_FAILURE; 5997 } 5998 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 5999 param_buf->fixed_param; 6000 6001 *event_count_flag = ev->event_count; 6002 return QDF_STATUS_SUCCESS; 6003 } 6004 6005 /** 6006 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6007 * @wmi_handle: wmi handle 6008 * @params: configuration parameters 6009 * 6010 * Return: QDF_STATUS 6011 */ 6012 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6013 struct nlo_mawc_params *params) 6014 { 6015 wmi_buf_t buf = NULL; 6016 QDF_STATUS status; 6017 int len; 6018 uint8_t *buf_ptr; 6019 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6020 6021 len = sizeof(*wmi_nlo_mawc_params); 6022 buf = wmi_buf_alloc(wmi_handle, len); 6023 if (!buf) 6024 return QDF_STATUS_E_NOMEM; 6025 6026 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6027 wmi_nlo_mawc_params = 6028 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6029 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6030 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6031 WMITLV_GET_STRUCT_TLVLEN 6032 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6033 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6034 if (params->enable) 6035 wmi_nlo_mawc_params->enable = 1; 6036 else 6037 wmi_nlo_mawc_params->enable = 0; 6038 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6039 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6040 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6041 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6042 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6043 wmi_nlo_mawc_params->exp_backoff_ratio, 6044 wmi_nlo_mawc_params->init_scan_interval, 6045 wmi_nlo_mawc_params->max_scan_interval); 6046 6047 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6048 status = wmi_unified_cmd_send(wmi_handle, buf, 6049 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6050 if (QDF_IS_STATUS_ERROR(status)) { 6051 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6052 status); 6053 wmi_buf_free(buf); 6054 return QDF_STATUS_E_FAILURE; 6055 } 6056 6057 return QDF_STATUS_SUCCESS; 6058 } 6059 6060 /** 6061 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6062 * scan 6063 * @scan_freq_list: frequency list for pno scan 6064 * 6065 * Return: void 6066 */ 6067 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6068 { 6069 uint32_t i; 6070 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6071 uint32_t len = 0; 6072 struct chan_info *chan_info; 6073 int ret; 6074 6075 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6076 for (i = 0; i < scan_freq_list->num_chan; i++) { 6077 chan_info = &scan_freq_list->chan[i]; 6078 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6079 " %d[%d]", chan_info->freq, 6080 chan_info->flags); 6081 if (ret <= 0) 6082 break; 6083 len += ret; 6084 if (len >= (sizeof(info) - 20)) { 6085 wmi_nofl_debug("Freq[flag]:%s", 6086 info); 6087 len = 0; 6088 } 6089 } 6090 if (len) 6091 wmi_nofl_debug("Freq[flag]:%s", info); 6092 } 6093 6094 /** 6095 * send_pno_start_cmd_tlv() - PNO start request 6096 * @wmi_handle: wmi handle 6097 * @pno: PNO request 6098 * 6099 * This function request FW to start PNO request. 6100 * Request: CDF status 6101 */ 6102 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6103 struct pno_scan_req_params *pno) 6104 { 6105 wmi_nlo_config_cmd_fixed_param *cmd; 6106 nlo_configured_parameters *nlo_list; 6107 uint32_t *channel_list; 6108 int32_t len; 6109 qdf_freq_t freq; 6110 wmi_buf_t buf; 6111 uint8_t *buf_ptr; 6112 uint8_t i; 6113 int ret; 6114 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6115 connected_nlo_rssi_params *nlo_relative_rssi; 6116 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6117 6118 /* 6119 * TLV place holder for array nlo_configured_parameters(nlo_list) 6120 * TLV place holder for array of uint32_t channel_list 6121 * TLV place holder for chnnl prediction cfg 6122 * TLV place holder for array of wmi_vendor_oui 6123 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6124 */ 6125 len = sizeof(*cmd) + 6126 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6127 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6128 6129 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6130 len += sizeof(nlo_configured_parameters) * 6131 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6132 len += sizeof(nlo_channel_prediction_cfg); 6133 len += sizeof(enlo_candidate_score_params); 6134 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6135 len += sizeof(connected_nlo_rssi_params); 6136 len += sizeof(connected_nlo_bss_band_rssi_pref); 6137 6138 buf = wmi_buf_alloc(wmi_handle, len); 6139 if (!buf) 6140 return QDF_STATUS_E_NOMEM; 6141 6142 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6143 6144 buf_ptr = (uint8_t *) cmd; 6145 WMITLV_SET_HDR(&cmd->tlv_header, 6146 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6147 WMITLV_GET_STRUCT_TLVLEN 6148 (wmi_nlo_config_cmd_fixed_param)); 6149 cmd->vdev_id = pno->vdev_id; 6150 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6151 6152 #ifdef FEATURE_WLAN_SCAN_PNO 6153 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6154 pno->adaptive_dwell_mode); 6155 #endif 6156 /* Current FW does not support min-max range for dwell time */ 6157 cmd->active_dwell_time = pno->active_dwell_time; 6158 cmd->passive_dwell_time = pno->passive_dwell_time; 6159 6160 if (pno->do_passive_scan) 6161 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6162 /* Copy scan interval */ 6163 cmd->fast_scan_period = pno->fast_scan_period; 6164 cmd->slow_scan_period = pno->slow_scan_period; 6165 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6166 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6167 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6168 6169 /* mac randomization attributes */ 6170 if (pno->scan_random.randomize) { 6171 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6172 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6173 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6174 pno->scan_random.mac_mask, 6175 &cmd->mac_addr, 6176 &cmd->mac_mask); 6177 } 6178 6179 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6180 6181 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6182 6183 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6184 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6185 buf_ptr += WMI_TLV_HDR_SIZE; 6186 6187 nlo_list = (nlo_configured_parameters *) buf_ptr; 6188 for (i = 0; i < cmd->no_of_ssids; i++) { 6189 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6190 WMITLV_TAG_ARRAY_BYTE, 6191 WMITLV_GET_STRUCT_TLVLEN 6192 (nlo_configured_parameters)); 6193 /* Copy ssid and it's length */ 6194 nlo_list[i].ssid.valid = true; 6195 nlo_list[i].ssid.ssid.ssid_len = 6196 pno->networks_list[i].ssid.length; 6197 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6198 pno->networks_list[i].ssid.ssid, 6199 nlo_list[i].ssid.ssid.ssid_len); 6200 6201 /* Copy rssi threshold */ 6202 if (pno->networks_list[i].rssi_thresh && 6203 pno->networks_list[i].rssi_thresh > 6204 WMI_RSSI_THOLD_DEFAULT) { 6205 nlo_list[i].rssi_cond.valid = true; 6206 nlo_list[i].rssi_cond.rssi = 6207 pno->networks_list[i].rssi_thresh; 6208 } 6209 nlo_list[i].bcast_nw_type.valid = true; 6210 nlo_list[i].bcast_nw_type.bcast_nw_type = 6211 pno->networks_list[i].bc_new_type; 6212 } 6213 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6214 6215 /* Copy channel info */ 6216 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6217 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6218 (cmd->num_of_channels * sizeof(uint32_t))); 6219 buf_ptr += WMI_TLV_HDR_SIZE; 6220 6221 channel_list = (uint32_t *) buf_ptr; 6222 for (i = 0; i < cmd->num_of_channels; i++) { 6223 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6224 pno->networks_list[0].pno_chan_list.chan[i].freq); 6225 6226 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6227 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6228 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6229 wlan_chan_to_freq(freq)); 6230 } 6231 6232 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6233 pno->networks_list[0].pno_chan_list.chan[i].flags); 6234 } 6235 6236 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6237 6238 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6239 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6240 sizeof(nlo_channel_prediction_cfg)); 6241 buf_ptr += WMI_TLV_HDR_SIZE; 6242 wmi_set_pno_channel_prediction(buf_ptr, pno); 6243 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6244 /** TODO: Discrete firmware doesn't have command/option to configure 6245 * App IE which comes from wpa_supplicant as of part PNO start request. 6246 */ 6247 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6248 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6249 buf_ptr += sizeof(enlo_candidate_score_params); 6250 6251 if (ie_allowlist->allow_list) { 6252 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6253 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6254 &cmd->num_vendor_oui, 6255 ie_allowlist); 6256 } 6257 6258 /* ie allow list */ 6259 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6260 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6261 buf_ptr += WMI_TLV_HDR_SIZE; 6262 if (cmd->num_vendor_oui != 0) { 6263 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6264 ie_allowlist->voui); 6265 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6266 } 6267 6268 if (pno->relative_rssi_set) 6269 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6270 6271 /* 6272 * Firmware calculation using connected PNO params: 6273 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6274 * deduction of rssi_pref for chosen band_pref and 6275 * addition of rssi_pref for remaining bands (other than chosen band). 6276 */ 6277 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6278 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6279 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6280 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6281 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6282 buf_ptr += sizeof(*nlo_relative_rssi); 6283 6284 /* 6285 * As of now Kernel and Host supports one band and rssi preference. 6286 * Firmware supports array of band and rssi preferences 6287 */ 6288 cmd->num_cnlo_band_pref = 1; 6289 WMITLV_SET_HDR(buf_ptr, 6290 WMITLV_TAG_ARRAY_STRUC, 6291 cmd->num_cnlo_band_pref * 6292 sizeof(connected_nlo_bss_band_rssi_pref)); 6293 buf_ptr += WMI_TLV_HDR_SIZE; 6294 6295 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6296 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6297 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6298 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6299 WMITLV_GET_STRUCT_TLVLEN( 6300 connected_nlo_bss_band_rssi_pref)); 6301 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6302 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6303 } 6304 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6305 6306 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6307 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6308 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6309 if (ret) { 6310 wmi_err("Failed to send nlo wmi cmd"); 6311 wmi_buf_free(buf); 6312 return QDF_STATUS_E_FAILURE; 6313 } 6314 6315 return QDF_STATUS_SUCCESS; 6316 } 6317 6318 /** 6319 * is_service_enabled_tlv() - Check if service enabled 6320 * @param wmi_handle: wmi handle 6321 * @param service_id: service identifier 6322 * 6323 * Return: 1 enabled, 0 disabled 6324 */ 6325 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6326 uint32_t service_id) 6327 { 6328 struct wmi_soc *soc = wmi_handle->soc; 6329 6330 if (!soc->wmi_service_bitmap) { 6331 wmi_err("WMI service bit map is not saved yet"); 6332 return false; 6333 } 6334 6335 /* if wmi_service_enabled was received with extended2 bitmap, 6336 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6337 */ 6338 if (soc->wmi_ext2_service_bitmap) { 6339 if (!soc->wmi_ext_service_bitmap) { 6340 wmi_err("WMI service ext bit map is not saved yet"); 6341 return false; 6342 } 6343 6344 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6345 soc->wmi_ext_service_bitmap, 6346 soc->wmi_ext2_service_bitmap, 6347 service_id); 6348 } 6349 6350 if (service_id >= WMI_MAX_EXT_SERVICE) { 6351 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6352 service_id); 6353 return false; 6354 } 6355 /* if wmi_service_enabled was received with extended bitmap, 6356 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6357 */ 6358 if (soc->wmi_ext_service_bitmap) 6359 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6360 soc->wmi_ext_service_bitmap, 6361 service_id); 6362 6363 if (service_id >= WMI_MAX_SERVICE) { 6364 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6365 service_id); 6366 return false; 6367 } 6368 6369 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6370 service_id); 6371 } 6372 6373 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6374 /** 6375 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6376 * @wmi_handle: wmi handle 6377 * @clear_req: ll stats clear request command params 6378 * 6379 * Return: QDF_STATUS_SUCCESS for success or error code 6380 */ 6381 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6382 const struct ll_stats_clear_params *clear_req) 6383 { 6384 wmi_clear_link_stats_cmd_fixed_param *cmd; 6385 int32_t len; 6386 wmi_buf_t buf; 6387 uint8_t *buf_ptr; 6388 int ret; 6389 6390 len = sizeof(*cmd); 6391 buf = wmi_buf_alloc(wmi_handle, len); 6392 6393 if (!buf) 6394 return QDF_STATUS_E_NOMEM; 6395 6396 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6397 qdf_mem_zero(buf_ptr, len); 6398 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6399 6400 WMITLV_SET_HDR(&cmd->tlv_header, 6401 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6402 WMITLV_GET_STRUCT_TLVLEN 6403 (wmi_clear_link_stats_cmd_fixed_param)); 6404 6405 cmd->stop_stats_collection_req = clear_req->stop_req; 6406 cmd->vdev_id = clear_req->vdev_id; 6407 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6408 6409 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6410 &cmd->peer_macaddr); 6411 6412 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6413 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6414 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6415 cmd->stop_stats_collection_req, 6416 cmd->vdev_id, cmd->stats_clear_req_mask, 6417 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6418 6419 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6420 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6421 WMI_CLEAR_LINK_STATS_CMDID); 6422 if (ret) { 6423 wmi_err("Failed to send clear link stats req"); 6424 wmi_buf_free(buf); 6425 return QDF_STATUS_E_FAILURE; 6426 } 6427 6428 wmi_debug("Clear Link Layer Stats request sent successfully"); 6429 return QDF_STATUS_SUCCESS; 6430 } 6431 6432 /** 6433 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 6434 * @wmi_handle: wmi handle 6435 * @set_req: ll stats set request command params 6436 * 6437 * Return: QDF_STATUS_SUCCESS for success or error code 6438 */ 6439 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 6440 const struct ll_stats_set_params *set_req) 6441 { 6442 wmi_start_link_stats_cmd_fixed_param *cmd; 6443 int32_t len; 6444 wmi_buf_t buf; 6445 uint8_t *buf_ptr; 6446 int ret; 6447 6448 len = sizeof(*cmd); 6449 buf = wmi_buf_alloc(wmi_handle, len); 6450 6451 if (!buf) 6452 return QDF_STATUS_E_NOMEM; 6453 6454 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6455 qdf_mem_zero(buf_ptr, len); 6456 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 6457 6458 WMITLV_SET_HDR(&cmd->tlv_header, 6459 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 6460 WMITLV_GET_STRUCT_TLVLEN 6461 (wmi_start_link_stats_cmd_fixed_param)); 6462 6463 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 6464 cmd->aggressive_statistics_gathering = 6465 set_req->aggressive_statistics_gathering; 6466 6467 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 6468 cmd->mpdu_size_threshold, 6469 cmd->aggressive_statistics_gathering); 6470 6471 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 6472 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6473 WMI_START_LINK_STATS_CMDID); 6474 if (ret) { 6475 wmi_err("Failed to send set link stats request"); 6476 wmi_buf_free(buf); 6477 return QDF_STATUS_E_FAILURE; 6478 } 6479 6480 return QDF_STATUS_SUCCESS; 6481 } 6482 6483 /** 6484 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 6485 * @wmi_handle: wmi handle 6486 * @get_req: ll stats get request command params 6487 * 6488 * Return: QDF_STATUS_SUCCESS for success or error code 6489 */ 6490 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 6491 const struct ll_stats_get_params *get_req) 6492 { 6493 wmi_request_link_stats_cmd_fixed_param *cmd; 6494 int32_t len; 6495 wmi_buf_t buf; 6496 uint8_t *buf_ptr; 6497 int ret; 6498 6499 len = sizeof(*cmd); 6500 buf = wmi_buf_alloc(wmi_handle, len); 6501 6502 if (!buf) 6503 return QDF_STATUS_E_NOMEM; 6504 6505 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6506 qdf_mem_zero(buf_ptr, len); 6507 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 6508 6509 WMITLV_SET_HDR(&cmd->tlv_header, 6510 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 6511 WMITLV_GET_STRUCT_TLVLEN 6512 (wmi_request_link_stats_cmd_fixed_param)); 6513 6514 cmd->request_id = get_req->req_id; 6515 cmd->stats_type = get_req->param_id_mask; 6516 cmd->vdev_id = get_req->vdev_id; 6517 6518 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6519 &cmd->peer_macaddr); 6520 6521 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6522 cmd->request_id, cmd->stats_type, cmd->vdev_id, 6523 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6524 6525 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 6526 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 6527 WMI_REQUEST_LINK_STATS_CMDID, true); 6528 if (ret) { 6529 wmi_buf_free(buf); 6530 return QDF_STATUS_E_FAILURE; 6531 } 6532 6533 return QDF_STATUS_SUCCESS; 6534 } 6535 6536 #ifdef WLAN_FEATURE_11BE_MLO 6537 static int 6538 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6539 { 6540 int32_t len = 0; 6541 6542 /* In case of MLO connection, update the length of the buffer. 6543 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 6544 * hence just update the TLV header, but allocate no memory for it. 6545 */ 6546 if (!get_req->is_mlo_req) 6547 return len; 6548 6549 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 6550 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 6551 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 6552 6553 return len; 6554 } 6555 6556 static void 6557 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6558 void *buf_ptr) 6559 { 6560 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6561 uint32_t *vdev_id_bitmap; 6562 wmi_mac_addr *mld_mac; 6563 6564 /* In case of MLO connection, update the TLV Headers */ 6565 if (!get_req->is_mlo_req) 6566 return; 6567 6568 buf_ptr += sizeof(*unified_cmd); 6569 6570 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 6571 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6572 buf_ptr += WMI_TLV_HDR_SIZE; 6573 6574 /* Adding vdev_bitmap_id array TLV */ 6575 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6576 sizeof(*vdev_id_bitmap)); 6577 buf_ptr += WMI_TLV_HDR_SIZE; 6578 vdev_id_bitmap = buf_ptr; 6579 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 6580 buf_ptr += sizeof(*vdev_id_bitmap); 6581 6582 /* Adding mld_macaddr array TLV */ 6583 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 6584 sizeof(*mld_mac)); 6585 buf_ptr += WMI_TLV_HDR_SIZE; 6586 mld_mac = buf_ptr; 6587 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 6588 6589 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 6590 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 6591 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 6592 } 6593 #else 6594 static inline int 6595 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 6596 { 6597 return 0; 6598 } 6599 6600 static inline void 6601 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 6602 void *buf_ptr) 6603 { 6604 } 6605 #endif 6606 6607 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 6608 /** 6609 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 6610 * station request 6611 * @wmi_handle: wmi handle 6612 * @get_req: ll stats get request command params 6613 * 6614 * Return: QDF_STATUS_SUCCESS for success or error code 6615 */ 6616 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 6617 wmi_unified_t wmi_handle, 6618 const struct ll_stats_get_params *get_req) 6619 { 6620 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 6621 int32_t len; 6622 wmi_buf_t buf; 6623 void *buf_ptr; 6624 QDF_STATUS ret; 6625 bool is_ll_get_sta_stats_over_qmi; 6626 6627 len = sizeof(*unified_cmd); 6628 len += wmi_get_tlv_length_for_mlo_stats(get_req); 6629 6630 buf = wmi_buf_alloc(wmi_handle, len); 6631 if (!buf) 6632 return QDF_STATUS_E_NOMEM; 6633 6634 buf_ptr = wmi_buf_data(buf); 6635 6636 unified_cmd = buf_ptr; 6637 WMITLV_SET_HDR( 6638 &unified_cmd->tlv_header, 6639 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 6640 WMITLV_GET_STRUCT_TLVLEN 6641 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 6642 6643 unified_cmd->link_stats_type = get_req->param_id_mask; 6644 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 6645 WMI_REQUEST_PEER_STAT | 6646 WMI_REQUEST_VDEV_STAT | 6647 WMI_REQUEST_PDEV_STAT | 6648 WMI_REQUEST_PEER_EXTD2_STAT | 6649 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 6650 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6651 wmi_handle, 6652 WMI_HOST_PDEV_ID_SOC); 6653 6654 unified_cmd->vdev_id = get_req->vdev_id; 6655 unified_cmd->request_id = get_req->req_id; 6656 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 6657 &unified_cmd->peer_macaddr); 6658 6659 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 6660 QDF_MAC_ADDR_FMT, 6661 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 6662 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 6663 6664 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 6665 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 6666 6667 /** 6668 * FW support for LL_get_sta command. True represents the unified 6669 * ll_get_sta command should be sent over QMI always irrespective of 6670 * WOW state. 6671 */ 6672 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 6673 wmi_handle, 6674 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 6675 6676 if (is_ll_get_sta_stats_over_qmi) { 6677 ret = wmi_unified_cmd_send_over_qmi( 6678 wmi_handle, buf, len, 6679 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 6680 } else { 6681 ret = wmi_unified_cmd_send_pm_chk( 6682 wmi_handle, buf, len, 6683 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 6684 true); 6685 } 6686 6687 if (QDF_IS_STATUS_ERROR(ret)) { 6688 wmi_buf_free(buf); 6689 return QDF_STATUS_E_FAILURE; 6690 } 6691 6692 return ret; 6693 } 6694 #endif 6695 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 6696 6697 /** 6698 * send_congestion_cmd_tlv() - send request to fw to get CCA 6699 * @wmi_handle: wmi handle 6700 * @vdev_id: vdev id 6701 * 6702 * Return: CDF status 6703 */ 6704 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 6705 uint8_t vdev_id) 6706 { 6707 wmi_buf_t buf; 6708 wmi_request_stats_cmd_fixed_param *cmd; 6709 uint8_t len; 6710 uint8_t *buf_ptr; 6711 6712 len = sizeof(*cmd); 6713 buf = wmi_buf_alloc(wmi_handle, len); 6714 if (!buf) 6715 return QDF_STATUS_E_FAILURE; 6716 6717 buf_ptr = wmi_buf_data(buf); 6718 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 6719 WMITLV_SET_HDR(&cmd->tlv_header, 6720 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6721 WMITLV_GET_STRUCT_TLVLEN 6722 (wmi_request_stats_cmd_fixed_param)); 6723 6724 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 6725 cmd->vdev_id = vdev_id; 6726 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 6727 cmd->vdev_id, cmd->stats_id); 6728 6729 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6730 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6731 WMI_REQUEST_STATS_CMDID)) { 6732 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 6733 wmi_buf_free(buf); 6734 return QDF_STATUS_E_FAILURE; 6735 } 6736 6737 return QDF_STATUS_SUCCESS; 6738 } 6739 6740 /** 6741 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 6742 * @wmi_handle: wmi handle 6743 * @rssi_req: get RSSI request 6744 * 6745 * Return: CDF status 6746 */ 6747 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 6748 { 6749 wmi_buf_t buf; 6750 wmi_request_stats_cmd_fixed_param *cmd; 6751 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6752 6753 buf = wmi_buf_alloc(wmi_handle, len); 6754 if (!buf) 6755 return QDF_STATUS_E_FAILURE; 6756 6757 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6758 WMITLV_SET_HDR(&cmd->tlv_header, 6759 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6760 WMITLV_GET_STRUCT_TLVLEN 6761 (wmi_request_stats_cmd_fixed_param)); 6762 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6763 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6764 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6765 WMI_REQUEST_STATS_CMDID)) { 6766 wmi_err("Failed to send host stats request to fw"); 6767 wmi_buf_free(buf); 6768 return QDF_STATUS_E_FAILURE; 6769 } 6770 6771 return QDF_STATUS_SUCCESS; 6772 } 6773 6774 /** 6775 * send_snr_cmd_tlv() - get RSSI from fw 6776 * @wmi_handle: wmi handle 6777 * @vdev_id: vdev id 6778 * 6779 * Return: CDF status 6780 */ 6781 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6782 { 6783 wmi_buf_t buf; 6784 wmi_request_stats_cmd_fixed_param *cmd; 6785 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6786 6787 buf = wmi_buf_alloc(wmi_handle, len); 6788 if (!buf) 6789 return QDF_STATUS_E_FAILURE; 6790 6791 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6792 cmd->vdev_id = vdev_id; 6793 6794 WMITLV_SET_HDR(&cmd->tlv_header, 6795 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6796 WMITLV_GET_STRUCT_TLVLEN 6797 (wmi_request_stats_cmd_fixed_param)); 6798 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 6799 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6800 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6801 WMI_REQUEST_STATS_CMDID)) { 6802 wmi_err("Failed to send host stats request to fw"); 6803 wmi_buf_free(buf); 6804 return QDF_STATUS_E_FAILURE; 6805 } 6806 6807 return QDF_STATUS_SUCCESS; 6808 } 6809 6810 /** 6811 * send_link_status_req_cmd_tlv() - process link status request from UMAC 6812 * @wmi_handle: wmi handle 6813 * @link_status: get link params 6814 * 6815 * Return: CDF status 6816 */ 6817 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 6818 struct link_status_params *link_status) 6819 { 6820 wmi_buf_t buf; 6821 wmi_request_stats_cmd_fixed_param *cmd; 6822 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 6823 6824 buf = wmi_buf_alloc(wmi_handle, len); 6825 if (!buf) 6826 return QDF_STATUS_E_FAILURE; 6827 6828 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 6829 WMITLV_SET_HDR(&cmd->tlv_header, 6830 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 6831 WMITLV_GET_STRUCT_TLVLEN 6832 (wmi_request_stats_cmd_fixed_param)); 6833 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 6834 cmd->vdev_id = link_status->vdev_id; 6835 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 6836 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6837 WMI_REQUEST_STATS_CMDID)) { 6838 wmi_err("Failed to send WMI link status request to fw"); 6839 wmi_buf_free(buf); 6840 return QDF_STATUS_E_FAILURE; 6841 } 6842 6843 return QDF_STATUS_SUCCESS; 6844 } 6845 6846 #ifdef WLAN_SUPPORT_GREEN_AP 6847 /** 6848 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 6849 * @wmi_handle: wmi handler 6850 * @egap_params: pointer to egap_params 6851 * 6852 * Return: 0 for success, otherwise appropriate error code 6853 */ 6854 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 6855 struct wlan_green_ap_egap_params *egap_params) 6856 { 6857 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 6858 wmi_buf_t buf; 6859 int32_t err; 6860 6861 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6862 if (!buf) 6863 return QDF_STATUS_E_NOMEM; 6864 6865 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 6866 WMITLV_SET_HDR(&cmd->tlv_header, 6867 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 6868 WMITLV_GET_STRUCT_TLVLEN( 6869 wmi_ap_ps_egap_param_cmd_fixed_param)); 6870 6871 cmd->enable = egap_params->host_enable_egap; 6872 cmd->inactivity_time = egap_params->egap_inactivity_time; 6873 cmd->wait_time = egap_params->egap_wait_time; 6874 cmd->flags = egap_params->egap_feature_flags; 6875 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 6876 err = wmi_unified_cmd_send(wmi_handle, buf, 6877 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 6878 if (err) { 6879 wmi_err("Failed to send ap_ps_egap cmd"); 6880 wmi_buf_free(buf); 6881 return QDF_STATUS_E_FAILURE; 6882 } 6883 6884 return QDF_STATUS_SUCCESS; 6885 } 6886 #endif 6887 6888 /** 6889 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 6890 * @wmi_handle: wmi handle 6891 * @vdev_id: vdev id 6892 * 6893 * Return: QDF_STATUS_SUCCESS for success or error code 6894 */ 6895 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 6896 uint8_t vdev_id) 6897 { 6898 wmi_csa_offload_enable_cmd_fixed_param *cmd; 6899 wmi_buf_t buf; 6900 int32_t len = sizeof(*cmd); 6901 6902 wmi_debug("vdev_id %d", vdev_id); 6903 buf = wmi_buf_alloc(wmi_handle, len); 6904 if (!buf) 6905 return QDF_STATUS_E_NOMEM; 6906 6907 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 6908 WMITLV_SET_HDR(&cmd->tlv_header, 6909 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 6910 WMITLV_GET_STRUCT_TLVLEN 6911 (wmi_csa_offload_enable_cmd_fixed_param)); 6912 cmd->vdev_id = vdev_id; 6913 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 6914 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 6915 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6916 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 6917 wmi_err("Failed to send CSA offload enable command"); 6918 wmi_buf_free(buf); 6919 return QDF_STATUS_E_FAILURE; 6920 } 6921 6922 return 0; 6923 } 6924 6925 #ifdef WLAN_FEATURE_CIF_CFR 6926 /** 6927 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 6928 * @wmi_handle: wmi handle 6929 * @data_len: len of dma cfg req 6930 * @data: dma cfg req 6931 * 6932 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 6933 */ 6934 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 6935 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 6936 { 6937 wmi_buf_t buf; 6938 uint8_t *cmd; 6939 QDF_STATUS ret; 6940 6941 WMITLV_SET_HDR(cfg, 6942 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 6943 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 6944 6945 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 6946 if (!buf) 6947 return QDF_STATUS_E_FAILURE; 6948 6949 cmd = (uint8_t *) wmi_buf_data(buf); 6950 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 6951 wmi_debug("Sending OEM Data Request to target, data len %lu", 6952 sizeof(*cfg)); 6953 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 6954 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 6955 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 6956 if (QDF_IS_STATUS_ERROR(ret)) { 6957 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 6958 wmi_buf_free(buf); 6959 } 6960 6961 return ret; 6962 } 6963 #endif 6964 6965 /** 6966 * send_start_11d_scan_cmd_tlv() - start 11d scan request 6967 * @wmi_handle: wmi handle 6968 * @start_11d_scan: 11d scan start request parameters 6969 * 6970 * This function request FW to start 11d scan. 6971 * 6972 * Return: QDF status 6973 */ 6974 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 6975 struct reg_start_11d_scan_req *start_11d_scan) 6976 { 6977 wmi_11d_scan_start_cmd_fixed_param *cmd; 6978 int32_t len; 6979 wmi_buf_t buf; 6980 int ret; 6981 6982 len = sizeof(*cmd); 6983 buf = wmi_buf_alloc(wmi_handle, len); 6984 if (!buf) 6985 return QDF_STATUS_E_NOMEM; 6986 6987 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 6988 6989 WMITLV_SET_HDR(&cmd->tlv_header, 6990 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 6991 WMITLV_GET_STRUCT_TLVLEN 6992 (wmi_11d_scan_start_cmd_fixed_param)); 6993 6994 cmd->vdev_id = start_11d_scan->vdev_id; 6995 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 6996 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 6997 6998 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 6999 7000 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7001 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7002 WMI_11D_SCAN_START_CMDID); 7003 if (ret) { 7004 wmi_err("Failed to send start 11d scan wmi cmd"); 7005 wmi_buf_free(buf); 7006 return QDF_STATUS_E_FAILURE; 7007 } 7008 7009 return QDF_STATUS_SUCCESS; 7010 } 7011 7012 /** 7013 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7014 * @wmi_handle: wmi handle 7015 * @start_11d_scan: 11d scan stop request parameters 7016 * 7017 * This function request FW to stop 11d scan. 7018 * 7019 * Return: QDF status 7020 */ 7021 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7022 struct reg_stop_11d_scan_req *stop_11d_scan) 7023 { 7024 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7025 int32_t len; 7026 wmi_buf_t buf; 7027 int ret; 7028 7029 len = sizeof(*cmd); 7030 buf = wmi_buf_alloc(wmi_handle, len); 7031 if (!buf) 7032 return QDF_STATUS_E_NOMEM; 7033 7034 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7035 7036 WMITLV_SET_HDR(&cmd->tlv_header, 7037 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7038 WMITLV_GET_STRUCT_TLVLEN 7039 (wmi_11d_scan_stop_cmd_fixed_param)); 7040 7041 cmd->vdev_id = stop_11d_scan->vdev_id; 7042 7043 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7044 7045 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7046 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7047 WMI_11D_SCAN_STOP_CMDID); 7048 if (ret) { 7049 wmi_err("Failed to send stop 11d scan wmi cmd"); 7050 wmi_buf_free(buf); 7051 return QDF_STATUS_E_FAILURE; 7052 } 7053 7054 return QDF_STATUS_SUCCESS; 7055 } 7056 7057 /** 7058 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7059 * @wmi_handle: wmi handle 7060 * @data_len: the length of @data 7061 * @data: the pointer to data buf 7062 * 7063 * Return: CDF status 7064 */ 7065 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7066 uint32_t data_len, 7067 uint8_t *data) 7068 { 7069 wmi_buf_t buf; 7070 uint8_t *cmd; 7071 QDF_STATUS ret; 7072 7073 buf = wmi_buf_alloc(wmi_handle, 7074 (data_len + WMI_TLV_HDR_SIZE)); 7075 if (!buf) 7076 return QDF_STATUS_E_FAILURE; 7077 7078 cmd = (uint8_t *) wmi_buf_data(buf); 7079 7080 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7081 cmd += WMI_TLV_HDR_SIZE; 7082 qdf_mem_copy(cmd, data, 7083 data_len); 7084 7085 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7086 7087 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7088 ret = wmi_unified_cmd_send(wmi_handle, buf, 7089 (data_len + 7090 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7091 7092 if (QDF_IS_STATUS_ERROR(ret)) { 7093 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7094 wmi_buf_free(buf); 7095 } 7096 7097 return ret; 7098 } 7099 7100 #ifdef FEATURE_OEM_DATA 7101 /** 7102 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7103 * @wmi_handle: wmi handle 7104 * @oem_data: the pointer to oem data 7105 * 7106 * Return: QDF status 7107 */ 7108 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7109 struct oem_data *oem_data) 7110 { 7111 QDF_STATUS ret; 7112 wmi_oem_data_cmd_fixed_param *cmd; 7113 struct wmi_ops *ops; 7114 wmi_buf_t buf; 7115 uint16_t len = sizeof(*cmd); 7116 uint16_t oem_data_len_aligned; 7117 uint8_t *buf_ptr; 7118 uint32_t pdev_id; 7119 7120 if (!oem_data || !oem_data->data) { 7121 wmi_err_rl("oem data is not valid"); 7122 return QDF_STATUS_E_FAILURE; 7123 } 7124 7125 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7126 if (oem_data_len_aligned < oem_data->data_len) { 7127 wmi_err_rl("integer overflow while rounding up data_len"); 7128 return QDF_STATUS_E_FAILURE; 7129 } 7130 7131 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7132 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7133 return QDF_STATUS_E_FAILURE; 7134 } 7135 7136 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7137 buf = wmi_buf_alloc(wmi_handle, len); 7138 if (!buf) 7139 return QDF_STATUS_E_NOMEM; 7140 7141 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7142 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7143 WMITLV_SET_HDR(&cmd->tlv_header, 7144 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7145 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7146 7147 pdev_id = oem_data->pdev_id; 7148 if (oem_data->pdev_vdev_flag) { 7149 ops = wmi_handle->ops; 7150 if (oem_data->is_host_pdev_id) 7151 pdev_id = 7152 ops->convert_host_pdev_id_to_target(wmi_handle, 7153 pdev_id); 7154 else 7155 pdev_id = 7156 ops->convert_pdev_id_host_to_target(wmi_handle, 7157 pdev_id); 7158 } 7159 7160 cmd->vdev_id = oem_data->vdev_id; 7161 cmd->data_len = oem_data->data_len; 7162 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7163 cmd->pdev_id = pdev_id; 7164 7165 buf_ptr += sizeof(*cmd); 7166 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7167 buf_ptr += WMI_TLV_HDR_SIZE; 7168 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7169 7170 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7171 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7172 if (QDF_IS_STATUS_ERROR(ret)) { 7173 wmi_err_rl("Failed with ret = %d", ret); 7174 wmi_buf_free(buf); 7175 } 7176 7177 return ret; 7178 } 7179 #endif 7180 7181 /** 7182 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7183 * @wmi_handle: wmi handle 7184 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7185 * 7186 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7187 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7188 * to firmware based on phyerr filtering 7189 * offload status. 7190 * 7191 * Return: 1 success, 0 failure 7192 */ 7193 static QDF_STATUS 7194 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7195 bool dfs_phyerr_filter_offload) 7196 { 7197 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7198 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7199 wmi_buf_t buf; 7200 uint16_t len; 7201 QDF_STATUS ret; 7202 7203 7204 if (false == dfs_phyerr_filter_offload) { 7205 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7206 len = sizeof(*disable_phyerr_offload_cmd); 7207 buf = wmi_buf_alloc(wmi_handle, len); 7208 if (!buf) 7209 return 0; 7210 7211 disable_phyerr_offload_cmd = 7212 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7213 wmi_buf_data(buf); 7214 7215 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7216 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7217 WMITLV_GET_STRUCT_TLVLEN 7218 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7219 7220 /* 7221 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7222 * to the firmware to disable the phyerror 7223 * filtering offload. 7224 */ 7225 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7226 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7227 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7228 if (QDF_IS_STATUS_ERROR(ret)) { 7229 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7230 ret); 7231 wmi_buf_free(buf); 7232 return QDF_STATUS_E_FAILURE; 7233 } 7234 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7235 } else { 7236 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7237 7238 len = sizeof(*enable_phyerr_offload_cmd); 7239 buf = wmi_buf_alloc(wmi_handle, len); 7240 if (!buf) 7241 return QDF_STATUS_E_FAILURE; 7242 7243 enable_phyerr_offload_cmd = 7244 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7245 wmi_buf_data(buf); 7246 7247 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7248 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7249 WMITLV_GET_STRUCT_TLVLEN 7250 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7251 7252 /* 7253 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7254 * to the firmware to enable the phyerror 7255 * filtering offload. 7256 */ 7257 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7258 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7259 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7260 7261 if (QDF_IS_STATUS_ERROR(ret)) { 7262 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7263 wmi_buf_free(buf); 7264 return QDF_STATUS_E_FAILURE; 7265 } 7266 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7267 } 7268 7269 return QDF_STATUS_SUCCESS; 7270 } 7271 7272 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7273 /** 7274 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7275 * @wmi_handle: wmi handle 7276 * @pktlog_event: pktlog event 7277 * @cmd_id: pktlog cmd id 7278 * @user_triggered: user triggered input for PKTLOG enable mode 7279 * 7280 * Return: CDF status 7281 */ 7282 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7283 WMI_PKTLOG_EVENT pktlog_event, 7284 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7285 { 7286 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7287 WMI_CMD_ID CMD_ID; 7288 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7289 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7290 int len = 0; 7291 wmi_buf_t buf; 7292 int32_t idx, max_idx; 7293 7294 PKTLOG_EVENT = pktlog_event; 7295 CMD_ID = cmd_id; 7296 7297 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7298 switch (CMD_ID) { 7299 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7300 len = sizeof(*cmd); 7301 buf = wmi_buf_alloc(wmi_handle, len); 7302 if (!buf) 7303 return QDF_STATUS_E_NOMEM; 7304 7305 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7306 wmi_buf_data(buf); 7307 WMITLV_SET_HDR(&cmd->tlv_header, 7308 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7309 WMITLV_GET_STRUCT_TLVLEN 7310 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7311 cmd->evlist = 0; 7312 for (idx = 0; idx < max_idx; idx++) { 7313 if (PKTLOG_EVENT & (1 << idx)) 7314 cmd->evlist |= pktlog_event_tlv[idx]; 7315 } 7316 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7317 : WMI_PKTLOG_ENABLE_AUTO; 7318 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7319 wmi_handle, 7320 WMI_HOST_PDEV_ID_SOC); 7321 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7322 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7323 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7324 wmi_err("Failed to send pktlog enable cmdid"); 7325 goto wmi_send_failed; 7326 } 7327 break; 7328 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7329 len = sizeof(*disable_cmd); 7330 buf = wmi_buf_alloc(wmi_handle, len); 7331 if (!buf) 7332 return QDF_STATUS_E_NOMEM; 7333 7334 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7335 wmi_buf_data(buf); 7336 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7337 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7338 WMITLV_GET_STRUCT_TLVLEN 7339 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7340 disable_cmd->pdev_id = 7341 wmi_handle->ops->convert_pdev_id_host_to_target( 7342 wmi_handle, 7343 WMI_HOST_PDEV_ID_SOC); 7344 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7345 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7346 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7347 wmi_err("failed to send pktlog disable cmdid"); 7348 goto wmi_send_failed; 7349 } 7350 break; 7351 default: 7352 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7353 break; 7354 } 7355 7356 return QDF_STATUS_SUCCESS; 7357 7358 wmi_send_failed: 7359 wmi_buf_free(buf); 7360 return QDF_STATUS_E_FAILURE; 7361 } 7362 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7363 7364 /** 7365 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7366 * @wmi_handle: wmi handle 7367 * @preq: stats ext params 7368 * 7369 * Return: CDF status 7370 */ 7371 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7372 struct stats_ext_params *preq) 7373 { 7374 QDF_STATUS ret; 7375 wmi_req_stats_ext_cmd_fixed_param *cmd; 7376 wmi_buf_t buf; 7377 size_t len; 7378 uint8_t *buf_ptr; 7379 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7380 uint32_t *vdev_bitmap; 7381 7382 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7383 sizeof(*cmd))) { 7384 wmi_err("Data length=%d is greater than max wmi msg size", 7385 preq->request_data_len); 7386 return QDF_STATUS_E_FAILURE; 7387 } 7388 7389 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7390 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7391 7392 buf = wmi_buf_alloc(wmi_handle, len); 7393 if (!buf) 7394 return QDF_STATUS_E_NOMEM; 7395 7396 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7397 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7398 7399 WMITLV_SET_HDR(&cmd->tlv_header, 7400 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7401 WMITLV_GET_STRUCT_TLVLEN 7402 (wmi_req_stats_ext_cmd_fixed_param)); 7403 cmd->vdev_id = preq->vdev_id; 7404 cmd->data_len = preq->request_data_len; 7405 7406 wmi_debug("The data len value is %u and vdev id set is %u", 7407 preq->request_data_len, preq->vdev_id); 7408 7409 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7410 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7411 7412 buf_ptr += WMI_TLV_HDR_SIZE; 7413 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7414 7415 buf_ptr += cmd->data_len; 7416 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7417 7418 buf_ptr += WMI_TLV_HDR_SIZE; 7419 7420 vdev_bitmap = (A_UINT32 *)buf_ptr; 7421 7422 vdev_bitmap[0] = preq->vdev_id_bitmap; 7423 7424 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 7425 7426 buf_ptr += sizeof(uint32_t); 7427 7428 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 7429 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7430 WMI_REQUEST_STATS_EXT_CMDID); 7431 if (QDF_IS_STATUS_ERROR(ret)) { 7432 wmi_err("Failed to send notify cmd ret = %d", ret); 7433 wmi_buf_free(buf); 7434 } 7435 7436 return ret; 7437 } 7438 7439 /** 7440 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 7441 * @wmi_handle: wmi handle 7442 * @params: DHCP server offload info 7443 * 7444 * Return: QDF_STATUS_SUCCESS for success or error code 7445 */ 7446 static QDF_STATUS 7447 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 7448 struct dhcp_offload_info_params *params) 7449 { 7450 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 7451 wmi_buf_t buf; 7452 QDF_STATUS status; 7453 7454 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7455 if (!buf) 7456 return QDF_STATUS_E_NOMEM; 7457 7458 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 7459 7460 WMITLV_SET_HDR(&cmd->tlv_header, 7461 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 7462 WMITLV_GET_STRUCT_TLVLEN 7463 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 7464 cmd->vdev_id = params->vdev_id; 7465 cmd->enable = params->dhcp_offload_enabled; 7466 cmd->num_client = params->dhcp_client_num; 7467 cmd->srv_ipv4 = params->dhcp_srv_addr; 7468 cmd->start_lsb = 0; 7469 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 7470 status = wmi_unified_cmd_send(wmi_handle, buf, 7471 sizeof(*cmd), 7472 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 7473 if (QDF_IS_STATUS_ERROR(status)) { 7474 wmi_err("Failed to send set_dhcp_server_offload cmd"); 7475 wmi_buf_free(buf); 7476 return QDF_STATUS_E_FAILURE; 7477 } 7478 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 7479 7480 return status; 7481 } 7482 7483 /** 7484 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 7485 * @wmi_handle: wmi handle 7486 * @param: pointer to pdev regdomain params 7487 * 7488 * Return: 0 for success or error code 7489 */ 7490 static QDF_STATUS 7491 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 7492 struct pdev_set_regdomain_params *param) 7493 { 7494 wmi_buf_t buf; 7495 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7496 int32_t len = sizeof(*cmd); 7497 7498 buf = wmi_buf_alloc(wmi_handle, len); 7499 if (!buf) 7500 return QDF_STATUS_E_NOMEM; 7501 7502 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7503 WMITLV_SET_HDR(&cmd->tlv_header, 7504 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7505 WMITLV_GET_STRUCT_TLVLEN 7506 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7507 7508 cmd->reg_domain = param->currentRDinuse; 7509 cmd->reg_domain_2G = param->currentRD2G; 7510 cmd->reg_domain_5G = param->currentRD5G; 7511 cmd->conformance_test_limit_2G = param->ctl_2G; 7512 cmd->conformance_test_limit_5G = param->ctl_5G; 7513 cmd->dfs_domain = param->dfsDomain; 7514 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7515 wmi_handle, 7516 param->pdev_id); 7517 7518 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7519 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7520 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7521 wmi_err("Failed to send pdev set regdomain command"); 7522 wmi_buf_free(buf); 7523 return QDF_STATUS_E_FAILURE; 7524 } 7525 7526 return QDF_STATUS_SUCCESS; 7527 } 7528 7529 /** 7530 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 7531 * @wmi_handle: wmi handle 7532 * @reg_dmn: reg domain 7533 * @regdmn2G: 2G reg domain 7534 * @regdmn5G: 5G reg domain 7535 * @ctl2G: 2G test limit 7536 * @ctl5G: 5G test limit 7537 * 7538 * Return: none 7539 */ 7540 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 7541 uint32_t reg_dmn, uint16_t regdmn2G, 7542 uint16_t regdmn5G, uint8_t ctl2G, 7543 uint8_t ctl5G) 7544 { 7545 wmi_buf_t buf; 7546 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 7547 int32_t len = sizeof(*cmd); 7548 7549 7550 buf = wmi_buf_alloc(wmi_handle, len); 7551 if (!buf) 7552 return QDF_STATUS_E_NOMEM; 7553 7554 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 7555 WMITLV_SET_HDR(&cmd->tlv_header, 7556 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 7557 WMITLV_GET_STRUCT_TLVLEN 7558 (wmi_pdev_set_regdomain_cmd_fixed_param)); 7559 cmd->reg_domain = reg_dmn; 7560 cmd->reg_domain_2G = regdmn2G; 7561 cmd->reg_domain_5G = regdmn5G; 7562 cmd->conformance_test_limit_2G = ctl2G; 7563 cmd->conformance_test_limit_5G = ctl5G; 7564 7565 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 7566 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 7567 cmd->conformance_test_limit_2G, 7568 cmd->conformance_test_limit_5G); 7569 7570 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 7571 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7572 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 7573 wmi_err("Failed to send pdev set regdomain command"); 7574 wmi_buf_free(buf); 7575 return QDF_STATUS_E_FAILURE; 7576 } 7577 7578 return QDF_STATUS_SUCCESS; 7579 } 7580 7581 /** 7582 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 7583 * @param: param sent from the host side 7584 * @cmd: param to be sent to the fw side 7585 */ 7586 static inline void copy_custom_aggr_bitmap( 7587 struct set_custom_aggr_size_params *param, 7588 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 7589 { 7590 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 7591 param->ac); 7592 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 7593 param->aggr_type); 7594 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7595 param->tx_aggr_size_disable); 7596 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 7597 param->rx_aggr_size_disable); 7598 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 7599 param->tx_ac_enable); 7600 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 7601 param->aggr_ba_enable); 7602 } 7603 7604 /** 7605 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 7606 * @wmi_handle: wmi handle 7607 * @param: pointer to hold custom aggr size params 7608 * 7609 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7610 */ 7611 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 7612 wmi_unified_t wmi_handle, 7613 struct set_custom_aggr_size_params *param) 7614 { 7615 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 7616 wmi_buf_t buf; 7617 int32_t len = sizeof(*cmd); 7618 7619 buf = wmi_buf_alloc(wmi_handle, len); 7620 if (!buf) 7621 return QDF_STATUS_E_FAILURE; 7622 7623 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 7624 wmi_buf_data(buf); 7625 WMITLV_SET_HDR(&cmd->tlv_header, 7626 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 7627 WMITLV_GET_STRUCT_TLVLEN( 7628 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 7629 cmd->vdev_id = param->vdev_id; 7630 cmd->tx_aggr_size = param->tx_aggr_size; 7631 cmd->rx_aggr_size = param->rx_aggr_size; 7632 copy_custom_aggr_bitmap(param, cmd); 7633 7634 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 7635 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 7636 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 7637 "tx_ac_enable=0x%X", 7638 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 7639 param->ac, param->aggr_type, param->tx_aggr_size_disable, 7640 param->rx_aggr_size_disable, param->tx_ac_enable); 7641 7642 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 7643 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7644 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 7645 wmi_err("Setting custom aggregation size failed"); 7646 wmi_buf_free(buf); 7647 return QDF_STATUS_E_FAILURE; 7648 } 7649 7650 return QDF_STATUS_SUCCESS; 7651 } 7652 7653 /** 7654 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 7655 * @param wmi_handle : handle to WMI. 7656 * @param param : pointer to tx antenna param 7657 * 7658 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7659 */ 7660 7661 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 7662 struct set_qdepth_thresh_params *param) 7663 { 7664 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 7665 wmi_msduq_qdepth_thresh_update *cmd_update; 7666 wmi_buf_t buf; 7667 int32_t len = 0; 7668 int i; 7669 uint8_t *buf_ptr; 7670 QDF_STATUS ret; 7671 7672 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 7673 wmi_err("Invalid Update Count!"); 7674 return QDF_STATUS_E_INVAL; 7675 } 7676 7677 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 7678 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 7679 param->num_of_msduq_updates); 7680 buf = wmi_buf_alloc(wmi_handle, len); 7681 7682 if (!buf) 7683 return QDF_STATUS_E_NOMEM; 7684 7685 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7686 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 7687 buf_ptr; 7688 7689 WMITLV_SET_HDR(&cmd->tlv_header, 7690 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 7691 , WMITLV_GET_STRUCT_TLVLEN( 7692 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 7693 7694 cmd->pdev_id = 7695 wmi_handle->ops->convert_pdev_id_host_to_target( 7696 wmi_handle, 7697 param->pdev_id); 7698 cmd->vdev_id = param->vdev_id; 7699 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 7700 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 7701 7702 buf_ptr += sizeof( 7703 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 7704 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7705 param->num_of_msduq_updates * 7706 sizeof(wmi_msduq_qdepth_thresh_update)); 7707 buf_ptr += WMI_TLV_HDR_SIZE; 7708 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 7709 7710 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 7711 WMITLV_SET_HDR(&cmd_update->tlv_header, 7712 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 7713 WMITLV_GET_STRUCT_TLVLEN( 7714 wmi_msduq_qdepth_thresh_update)); 7715 cmd_update->tid_num = param->update_params[i].tid_num; 7716 cmd_update->msduq_update_mask = 7717 param->update_params[i].msduq_update_mask; 7718 cmd_update->qdepth_thresh_value = 7719 param->update_params[i].qdepth_thresh_value; 7720 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 7721 "mac_addr_upper4=%X, mac_addr_lower2:%X," 7722 " update mask=0x%X thresh val=0x%X", 7723 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 7724 cmd->peer_mac_address.mac_addr31to0, 7725 cmd->peer_mac_address.mac_addr47to32, 7726 cmd_update->msduq_update_mask, 7727 cmd_update->qdepth_thresh_value); 7728 cmd_update++; 7729 } 7730 7731 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 7732 cmd->vdev_id, 0); 7733 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7734 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 7735 7736 if (ret != 0) { 7737 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 7738 wmi_buf_free(buf); 7739 } 7740 7741 return ret; 7742 } 7743 7744 /** 7745 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 7746 * @wmi_handle: wmi handle 7747 * @param: pointer to hold vap dscp tid map param 7748 * 7749 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7750 */ 7751 static QDF_STATUS 7752 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 7753 struct vap_dscp_tid_map_params *param) 7754 { 7755 wmi_buf_t buf; 7756 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 7757 int32_t len = sizeof(*cmd); 7758 7759 buf = wmi_buf_alloc(wmi_handle, len); 7760 if (!buf) 7761 return QDF_STATUS_E_FAILURE; 7762 7763 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 7764 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 7765 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 7766 7767 cmd->vdev_id = param->vdev_id; 7768 cmd->enable_override = 0; 7769 7770 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 7771 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 7772 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7773 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 7774 wmi_err("Failed to set dscp cmd"); 7775 wmi_buf_free(buf); 7776 return QDF_STATUS_E_FAILURE; 7777 } 7778 7779 return QDF_STATUS_SUCCESS; 7780 } 7781 7782 /** 7783 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 7784 * @wmi_handle: wmi handle 7785 * @param: pointer to hold fwtest param 7786 * 7787 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7788 */ 7789 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 7790 struct set_fwtest_params *param) 7791 { 7792 wmi_fwtest_set_param_cmd_fixed_param *cmd; 7793 wmi_buf_t buf; 7794 int32_t len = sizeof(*cmd); 7795 7796 buf = wmi_buf_alloc(wmi_handle, len); 7797 7798 if (!buf) 7799 return QDF_STATUS_E_FAILURE; 7800 7801 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 7802 WMITLV_SET_HDR(&cmd->tlv_header, 7803 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 7804 WMITLV_GET_STRUCT_TLVLEN( 7805 wmi_fwtest_set_param_cmd_fixed_param)); 7806 cmd->param_id = param->arg; 7807 cmd->param_value = param->value; 7808 7809 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 7810 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 7811 wmi_err("Setting FW test param failed"); 7812 wmi_buf_free(buf); 7813 return QDF_STATUS_E_FAILURE; 7814 } 7815 7816 return QDF_STATUS_SUCCESS; 7817 } 7818 7819 /** 7820 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 7821 * 7822 * @param wmi_handle : handle to WMI. 7823 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7824 */ 7825 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 7826 { 7827 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 7828 wmi_buf_t buf; 7829 QDF_STATUS ret; 7830 int32_t len; 7831 7832 len = sizeof(*cmd); 7833 7834 buf = wmi_buf_alloc(wmi_handle, len); 7835 if (!buf) 7836 return QDF_STATUS_E_FAILURE; 7837 7838 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 7839 WMITLV_SET_HDR(&cmd->tlv_header, 7840 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 7841 WMITLV_GET_STRUCT_TLVLEN( 7842 wmi_pdev_dfs_disable_cmd_fixed_param)); 7843 /* Filling it with WMI_PDEV_ID_SOC for now */ 7844 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7845 wmi_handle, 7846 WMI_HOST_PDEV_ID_SOC); 7847 7848 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 7849 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7850 WMI_PDEV_DFS_DISABLE_CMDID); 7851 7852 if (ret != 0) { 7853 wmi_err("Sending PDEV DFS disable cmd failed"); 7854 wmi_buf_free(buf); 7855 } 7856 7857 return ret; 7858 } 7859 7860 /** 7861 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 7862 * 7863 * @param wmi_handle : handle to WMI. 7864 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7865 */ 7866 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 7867 { 7868 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 7869 wmi_buf_t buf; 7870 QDF_STATUS ret; 7871 int32_t len; 7872 7873 len = sizeof(*cmd); 7874 7875 buf = wmi_buf_alloc(wmi_handle, len); 7876 if (!buf) 7877 return QDF_STATUS_E_FAILURE; 7878 7879 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 7880 WMITLV_SET_HDR(&cmd->tlv_header, 7881 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 7882 WMITLV_GET_STRUCT_TLVLEN( 7883 wmi_pdev_dfs_enable_cmd_fixed_param)); 7884 /* Reserved for future use */ 7885 cmd->reserved0 = 0; 7886 7887 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 7888 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7889 WMI_PDEV_DFS_ENABLE_CMDID); 7890 7891 if (ret != 0) { 7892 wmi_err("Sending PDEV DFS enable cmd failed"); 7893 wmi_buf_free(buf); 7894 } 7895 7896 return ret; 7897 } 7898 7899 /** 7900 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 7901 * to fw 7902 * @wmi_handle: wmi handle 7903 * @param: pointer to hold periodic chan stats param 7904 * 7905 * Return: 0 for success or error code 7906 */ 7907 static QDF_STATUS 7908 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 7909 struct periodic_chan_stats_params *param) 7910 { 7911 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 7912 wmi_buf_t buf; 7913 QDF_STATUS ret; 7914 int32_t len; 7915 7916 len = sizeof(*cmd); 7917 7918 buf = wmi_buf_alloc(wmi_handle, len); 7919 if (!buf) 7920 return QDF_STATUS_E_FAILURE; 7921 7922 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 7923 wmi_buf_data(buf); 7924 WMITLV_SET_HDR(&cmd->tlv_header, 7925 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 7926 WMITLV_GET_STRUCT_TLVLEN( 7927 wmi_set_periodic_channel_stats_config_fixed_param)); 7928 cmd->enable = param->enable; 7929 cmd->stats_period = param->stats_period; 7930 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7931 wmi_handle, 7932 param->pdev_id); 7933 7934 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 7935 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 7936 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 7937 7938 if (ret != 0) { 7939 wmi_err("Sending periodic chan stats config failed"); 7940 wmi_buf_free(buf); 7941 } 7942 7943 return ret; 7944 } 7945 7946 #ifdef WLAN_IOT_SIM_SUPPORT 7947 /** 7948 * send_simulation_test_cmd_tlv() - send simulation test command to fw 7949 * 7950 * @wmi_handle: wmi handle 7951 * @param: pointer to hold simulation test parameter 7952 * 7953 * Return: 0 for success or error code 7954 */ 7955 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 7956 struct simulation_test_params 7957 *param) 7958 { 7959 wmi_simulation_test_cmd_fixed_param *cmd; 7960 u32 wmi_buf_len; 7961 wmi_buf_t buf; 7962 u8 *buf_ptr; 7963 u32 aligned_len = 0; 7964 7965 wmi_buf_len = sizeof(*cmd); 7966 if (param->buf_len) { 7967 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 7968 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 7969 } 7970 7971 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 7972 if (!buf) { 7973 wmi_err("wmi_buf_alloc failed"); 7974 return QDF_STATUS_E_NOMEM; 7975 } 7976 7977 buf_ptr = wmi_buf_data(buf); 7978 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 7979 WMITLV_SET_HDR(&cmd->tlv_header, 7980 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 7981 WMITLV_GET_STRUCT_TLVLEN( 7982 wmi_simulation_test_cmd_fixed_param)); 7983 cmd->pdev_id = param->pdev_id; 7984 cmd->vdev_id = param->vdev_id; 7985 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 7986 cmd->test_cmd_type = param->test_cmd_type; 7987 cmd->test_subcmd_type = param->test_subcmd_type; 7988 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 7989 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 7990 param->frame_subtype); 7991 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 7992 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 7993 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 7994 cmd->buf_len = param->buf_len; 7995 7996 if (param->buf_len) { 7997 buf_ptr += sizeof(*cmd); 7998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 7999 buf_ptr += WMI_TLV_HDR_SIZE; 8000 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8001 } 8002 8003 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8004 WMI_SIMULATION_TEST_CMDID)) { 8005 wmi_err("Failed to send test simulation cmd"); 8006 wmi_buf_free(buf); 8007 return QDF_STATUS_E_FAILURE; 8008 } 8009 8010 return QDF_STATUS_SUCCESS; 8011 } 8012 #endif 8013 8014 #ifdef WLAN_FEATURE_11BE 8015 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8016 #else 8017 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8018 #endif 8019 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8020 { 8021 switch (wmi_width) { 8022 case WMI_CHAN_WIDTH_20: 8023 return CH_WIDTH_20MHZ; 8024 case WMI_CHAN_WIDTH_40: 8025 return CH_WIDTH_40MHZ; 8026 case WMI_CHAN_WIDTH_80: 8027 return CH_WIDTH_80MHZ; 8028 case WMI_CHAN_WIDTH_160: 8029 return CH_WIDTH_160MHZ; 8030 case WMI_CHAN_WIDTH_80P80: 8031 return CH_WIDTH_80P80MHZ; 8032 case WMI_CHAN_WIDTH_5: 8033 return CH_WIDTH_5MHZ; 8034 case WMI_CHAN_WIDTH_10: 8035 return CH_WIDTH_10MHZ; 8036 case WMI_CHAN_WIDTH_320: 8037 return WLAN_PHY_CH_WIDTH_320MHZ; 8038 default: 8039 return CH_WIDTH_INVALID; 8040 } 8041 } 8042 8043 /* 8044 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8045 * to wmi channel width 8046 * @chan_width: Host channel width 8047 * 8048 * Return: wmi channel width 8049 */ 8050 static 8051 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8052 { 8053 switch (chan_width) { 8054 case CH_WIDTH_20MHZ: 8055 return WMI_CHAN_WIDTH_20; 8056 case CH_WIDTH_40MHZ: 8057 return WMI_CHAN_WIDTH_40; 8058 case CH_WIDTH_80MHZ: 8059 return WMI_CHAN_WIDTH_80; 8060 case CH_WIDTH_160MHZ: 8061 return WMI_CHAN_WIDTH_160; 8062 case CH_WIDTH_80P80MHZ: 8063 return WMI_CHAN_WIDTH_80P80; 8064 case CH_WIDTH_5MHZ: 8065 return WMI_CHAN_WIDTH_5; 8066 case CH_WIDTH_10MHZ: 8067 return WMI_CHAN_WIDTH_10; 8068 #ifdef WLAN_FEATURE_11BE 8069 case CH_WIDTH_320MHZ: 8070 return WMI_CHAN_WIDTH_320; 8071 #endif 8072 default: 8073 return WMI_CHAN_WIDTH_MAX; 8074 } 8075 } 8076 8077 /** 8078 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8079 * command to fw 8080 * @wmi_handle: wmi handle 8081 * @param: pointer to hold spectral config parameter 8082 * 8083 * Return: 0 for success or error code 8084 */ 8085 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8086 struct vdev_spectral_configure_params *param) 8087 { 8088 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8089 wmi_buf_t buf; 8090 QDF_STATUS ret; 8091 int32_t len; 8092 8093 len = sizeof(*cmd); 8094 buf = wmi_buf_alloc(wmi_handle, len); 8095 if (!buf) 8096 return QDF_STATUS_E_FAILURE; 8097 8098 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8099 WMITLV_SET_HDR(&cmd->tlv_header, 8100 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8101 WMITLV_GET_STRUCT_TLVLEN( 8102 wmi_vdev_spectral_configure_cmd_fixed_param)); 8103 8104 cmd->vdev_id = param->vdev_id; 8105 cmd->spectral_scan_count = param->count; 8106 cmd->spectral_scan_period = param->period; 8107 cmd->spectral_scan_priority = param->spectral_pri; 8108 cmd->spectral_scan_fft_size = param->fft_size; 8109 cmd->spectral_scan_gc_ena = param->gc_enable; 8110 cmd->spectral_scan_restart_ena = param->restart_enable; 8111 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8112 cmd->spectral_scan_init_delay = param->init_delay; 8113 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8114 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8115 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8116 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8117 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8118 cmd->spectral_scan_pwr_format = param->pwr_format; 8119 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8120 cmd->spectral_scan_bin_scale = param->bin_scale; 8121 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8122 cmd->spectral_scan_chn_mask = param->chn_mask; 8123 cmd->spectral_scan_mode = param->mode; 8124 cmd->spectral_scan_center_freq1 = param->center_freq1; 8125 cmd->spectral_scan_center_freq2 = param->center_freq2; 8126 cmd->spectral_scan_chan_width = 8127 convert_host_to_target_ch_width(param->chan_width); 8128 cmd->recapture_sample_on_gain_change = param->fft_recap; 8129 /* Not used, fill with zeros */ 8130 cmd->spectral_scan_chan_freq = 0; 8131 8132 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8133 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8134 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8135 8136 if (ret != 0) { 8137 wmi_err("Sending set quiet cmd failed"); 8138 wmi_buf_free(buf); 8139 } 8140 8141 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8142 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8143 param->vdev_id, param->count); 8144 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8145 param->period, param->spectral_pri); 8146 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8147 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8148 param->fft_size, param->gc_enable); 8149 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8150 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8151 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8152 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8153 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8154 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8155 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8156 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8157 param->rssi_thr, param->pwr_format); 8158 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8159 param->rpt_mode, param->bin_scale); 8160 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8161 param->dbm_adj, param->chn_mask); 8162 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8163 param->mode, param->center_freq1); 8164 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8165 param->center_freq2, param->chan_freq); 8166 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8167 param->chan_width, ret); 8168 8169 return ret; 8170 } 8171 8172 /** 8173 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8174 * command to fw 8175 * @wmi_handle: wmi handle 8176 * @param: pointer to hold spectral enable parameter 8177 * 8178 * Return: 0 for success or error code 8179 */ 8180 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8181 struct vdev_spectral_enable_params *param) 8182 { 8183 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8184 wmi_buf_t buf; 8185 QDF_STATUS ret; 8186 int32_t len; 8187 8188 len = sizeof(*cmd); 8189 buf = wmi_buf_alloc(wmi_handle, len); 8190 if (!buf) 8191 return QDF_STATUS_E_FAILURE; 8192 8193 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8194 WMITLV_SET_HDR(&cmd->tlv_header, 8195 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8196 WMITLV_GET_STRUCT_TLVLEN( 8197 wmi_vdev_spectral_enable_cmd_fixed_param)); 8198 8199 cmd->vdev_id = param->vdev_id; 8200 8201 if (param->active_valid) { 8202 cmd->trigger_cmd = param->active ? 1 : 2; 8203 /* 1: Trigger, 2: Clear Trigger */ 8204 } else { 8205 cmd->trigger_cmd = 0; /* 0: Ignore */ 8206 } 8207 8208 if (param->enabled_valid) { 8209 cmd->enable_cmd = param->enabled ? 1 : 2; 8210 /* 1: Enable 2: Disable */ 8211 } else { 8212 cmd->enable_cmd = 0; /* 0: Ignore */ 8213 } 8214 cmd->spectral_scan_mode = param->mode; 8215 8216 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8217 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8218 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8219 8220 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8221 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8222 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8223 8224 if (ret != 0) { 8225 wmi_err("Sending scan enable CMD failed"); 8226 wmi_buf_free(buf); 8227 } 8228 8229 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8230 ret); 8231 8232 return ret; 8233 } 8234 8235 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8236 static QDF_STATUS 8237 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8238 wmi_unified_t wmi_handle, 8239 uint8_t *event, struct spectral_startscan_resp_params *param) 8240 { 8241 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8242 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8243 8244 if (!wmi_handle) { 8245 wmi_err("WMI handle is null"); 8246 return QDF_STATUS_E_INVAL; 8247 } 8248 8249 if (!event) { 8250 wmi_err("WMI event is null"); 8251 return QDF_STATUS_E_INVAL; 8252 } 8253 8254 if (!param) { 8255 wmi_err("Spectral startscan response params is null"); 8256 return QDF_STATUS_E_INVAL; 8257 } 8258 8259 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8260 if (!param_buf) 8261 return QDF_STATUS_E_INVAL; 8262 8263 ev = param_buf->fixed_param; 8264 if (!ev) 8265 return QDF_STATUS_E_INVAL; 8266 8267 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8268 wmi_handle, 8269 ev->pdev_id); 8270 param->smode = ev->spectral_scan_mode; 8271 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8272 param->num_det_info = param_buf->num_det_info; 8273 8274 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8275 ev->pdev_id, ev->spectral_scan_mode, 8276 param_buf->num_fft_bin_index, param_buf->num_det_info); 8277 8278 return QDF_STATUS_SUCCESS; 8279 } 8280 8281 static QDF_STATUS 8282 extract_pdev_sscan_fft_bin_index_tlv( 8283 wmi_unified_t wmi_handle, uint8_t *event, 8284 struct spectral_fft_bin_markers_160_165mhz *param) 8285 { 8286 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8287 wmi_pdev_sscan_fft_bin_index *ev; 8288 8289 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8290 if (!param_buf) 8291 return QDF_STATUS_E_INVAL; 8292 8293 ev = param_buf->fft_bin_index; 8294 if (!ev) 8295 return QDF_STATUS_E_INVAL; 8296 8297 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8298 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8299 param->start_pri80 + 1; 8300 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8301 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8302 param->start_sec80 + 1; 8303 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8304 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8305 param->start_5mhz + 1; 8306 param->is_valid = true; 8307 8308 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8309 param->start_pri80, param->num_pri80, 8310 param->start_sec80, param->num_sec80, 8311 param->start_5mhz, param->num_5mhz); 8312 8313 return QDF_STATUS_SUCCESS; 8314 } 8315 8316 /** 8317 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 8318 * for a spectral scan session 8319 * @wmi_handle: handle to WMI. 8320 * @event: Event buffer 8321 * @chan_info: Spectral session channel information data structure to be filled 8322 * by this API 8323 * 8324 * Return: QDF_STATUS of operation 8325 */ 8326 static QDF_STATUS 8327 extract_pdev_spectral_session_chan_info_tlv( 8328 wmi_unified_t wmi_handle, void *event, 8329 struct spectral_session_chan_info *chan_info) 8330 { 8331 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8332 wmi_pdev_sscan_chan_info *chan_info_tlv; 8333 8334 if (!param_buf) { 8335 wmi_err("param_buf is NULL"); 8336 return QDF_STATUS_E_NULL_VALUE; 8337 } 8338 8339 if (!chan_info) { 8340 wmi_err("chan_info is NULL"); 8341 return QDF_STATUS_E_NULL_VALUE; 8342 } 8343 8344 chan_info_tlv = param_buf->chan_info; 8345 if (!chan_info_tlv) { 8346 wmi_err("chan_info tlv is not present in the event"); 8347 return QDF_STATUS_E_NULL_VALUE; 8348 } 8349 8350 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 8351 "operating_cfreq2:%u operating_bw:%u" 8352 "operating_puncture_20mhz_bitmap:%u" 8353 "sscan_cfreq1:%u sscan_cfreq2:%u" 8354 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 8355 chan_info_tlv->operating_pri20_freq, 8356 chan_info_tlv->operating_cfreq1, 8357 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 8358 chan_info_tlv->operating_puncture_20mhz_bitmap, 8359 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 8360 chan_info_tlv->sscan_bw, 8361 chan_info_tlv->sscan_puncture_20mhz_bitmap); 8362 8363 chan_info->operating_pri20_freq = 8364 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 8365 chan_info->operating_cfreq1 = 8366 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 8367 chan_info->operating_cfreq2 = 8368 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 8369 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 8370 chan_info->operating_puncture_20mhz_bitmap = 8371 chan_info_tlv->operating_puncture_20mhz_bitmap; 8372 8373 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 8374 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 8375 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 8376 chan_info->sscan_puncture_20mhz_bitmap = 8377 chan_info_tlv->sscan_puncture_20mhz_bitmap; 8378 8379 return QDF_STATUS_SUCCESS; 8380 } 8381 8382 static QDF_STATUS 8383 extract_pdev_spectral_session_detector_info_tlv( 8384 wmi_unified_t wmi_handle, void *event, 8385 struct spectral_session_det_info *det_info, uint8_t idx) 8386 { 8387 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 8388 wmi_pdev_sscan_per_detector_info *det_info_tlv; 8389 8390 if (!param_buf) { 8391 wmi_err("param_buf is NULL"); 8392 return QDF_STATUS_E_NULL_VALUE; 8393 } 8394 8395 if (!det_info) { 8396 wmi_err("chan_info is NULL"); 8397 return QDF_STATUS_E_NULL_VALUE; 8398 } 8399 8400 if (!param_buf->det_info) { 8401 wmi_err("det_info tlv is not present in the event"); 8402 return QDF_STATUS_E_NULL_VALUE; 8403 } 8404 8405 if (idx >= param_buf->num_det_info) { 8406 wmi_err("det_info index(%u) is greater than or equal to %u", 8407 idx, param_buf->num_det_info); 8408 return QDF_STATUS_E_FAILURE; 8409 } 8410 8411 det_info_tlv = ¶m_buf->det_info[idx]; 8412 8413 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 8414 idx, det_info_tlv->detector_id, 8415 det_info_tlv->start_freq, det_info_tlv->end_freq); 8416 8417 det_info->det_id = det_info_tlv->detector_id; 8418 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 8419 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 8420 8421 return QDF_STATUS_SUCCESS; 8422 } 8423 8424 /** 8425 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 8426 * capabilities WMI event 8427 * @wmi_handle: handle to WMI. 8428 * @event: Event buffer 8429 * @param: Spectral capabilities event parameters data structure to be filled 8430 * by this API 8431 * 8432 * Return: QDF_STATUS of operation 8433 */ 8434 static QDF_STATUS 8435 extract_spectral_caps_fixed_param_tlv( 8436 wmi_unified_t wmi_handle, void *event, 8437 struct spectral_capabilities_event_params *params) 8438 { 8439 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8440 8441 if (!param_buf) { 8442 wmi_err("param_buf is NULL"); 8443 return QDF_STATUS_E_NULL_VALUE; 8444 } 8445 8446 if (!params) { 8447 wmi_err("event parameters is NULL"); 8448 return QDF_STATUS_E_NULL_VALUE; 8449 } 8450 8451 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 8452 params->num_fft_size_caps = param_buf->num_fft_size_caps; 8453 8454 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 8455 params->num_sscan_bw_caps, params->num_fft_size_caps); 8456 8457 return QDF_STATUS_SUCCESS; 8458 } 8459 8460 /** 8461 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 8462 * Spectral capabilities WMI event 8463 * @wmi_handle: handle to WMI. 8464 * @event: Event buffer 8465 * @bw_caps: Data structure to be populated by this API after extraction 8466 * 8467 * Return: QDF_STATUS of operation 8468 */ 8469 static QDF_STATUS 8470 extract_spectral_scan_bw_caps_tlv( 8471 wmi_unified_t wmi_handle, void *event, 8472 struct spectral_scan_bw_capabilities *bw_caps) 8473 { 8474 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8475 int idx; 8476 8477 if (!param_buf) { 8478 wmi_err("param_buf is NULL"); 8479 return QDF_STATUS_E_NULL_VALUE; 8480 } 8481 8482 if (!bw_caps) { 8483 wmi_err("bw_caps is null"); 8484 return QDF_STATUS_E_NULL_VALUE; 8485 } 8486 8487 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 8488 bw_caps[idx].pdev_id = 8489 wmi_handle->ops->convert_pdev_id_target_to_host( 8490 wmi_handle, 8491 param_buf->sscan_bw_caps[idx].pdev_id); 8492 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 8493 bw_caps[idx].operating_bw = wmi_map_ch_width( 8494 param_buf->sscan_bw_caps[idx].operating_bw); 8495 bw_caps[idx].supported_bws = 8496 param_buf->sscan_bw_caps[idx].supported_flags; 8497 8498 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 8499 "operating_bw:%u supported_flags:0x%x", 8500 idx, param_buf->sscan_bw_caps[idx].pdev_id, 8501 param_buf->sscan_bw_caps[idx].sscan_mode, 8502 param_buf->sscan_bw_caps[idx].operating_bw, 8503 param_buf->sscan_bw_caps[idx].supported_flags); 8504 } 8505 8506 return QDF_STATUS_SUCCESS; 8507 } 8508 8509 /** 8510 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 8511 * Spectral capabilities WMI event 8512 * @wmi_handle: handle to WMI. 8513 * @event: Event buffer 8514 * @fft_size_caps: Data structure to be populated by this API after extraction 8515 * 8516 * Return: QDF_STATUS of operation 8517 */ 8518 static QDF_STATUS 8519 extract_spectral_fft_size_caps_tlv( 8520 wmi_unified_t wmi_handle, void *event, 8521 struct spectral_fft_size_capabilities *fft_size_caps) 8522 { 8523 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 8524 int idx; 8525 8526 if (!param_buf) { 8527 wmi_err("param_buf is NULL"); 8528 return QDF_STATUS_E_NULL_VALUE; 8529 } 8530 8531 if (!fft_size_caps) { 8532 wmi_err("fft size caps is NULL"); 8533 return QDF_STATUS_E_NULL_VALUE; 8534 } 8535 8536 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 8537 fft_size_caps[idx].pdev_id = 8538 wmi_handle->ops->convert_pdev_id_target_to_host( 8539 wmi_handle, 8540 param_buf->fft_size_caps[idx].pdev_id); 8541 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 8542 param_buf->fft_size_caps[idx].sscan_bw); 8543 fft_size_caps[idx].supports_fft_sizes = 8544 param_buf->fft_size_caps[idx].supported_flags; 8545 8546 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 8547 "supported_flags:0x%x", 8548 idx, param_buf->fft_size_caps[idx].pdev_id, 8549 param_buf->fft_size_caps[idx].sscan_bw, 8550 param_buf->fft_size_caps[idx].supported_flags); 8551 } 8552 8553 return QDF_STATUS_SUCCESS; 8554 } 8555 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 8556 8557 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 8558 static inline void 8559 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8560 struct thermal_mitigation_params *param) 8561 { 8562 tt_conf->client_id = param->client_id; 8563 tt_conf->priority = param->priority; 8564 } 8565 #else 8566 static inline void 8567 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 8568 struct thermal_mitigation_params *param) 8569 { 8570 } 8571 #endif 8572 8573 /** 8574 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 8575 * @param wmi_handle : handle to WMI. 8576 * @param param : pointer to hold thermal mitigation param 8577 * 8578 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 8579 */ 8580 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 8581 wmi_unified_t wmi_handle, 8582 struct thermal_mitigation_params *param) 8583 { 8584 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 8585 wmi_therm_throt_level_config_info *lvl_conf = NULL; 8586 wmi_buf_t buf = NULL; 8587 uint8_t *buf_ptr = NULL; 8588 int error; 8589 int32_t len; 8590 int i; 8591 8592 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 8593 param->num_thermal_conf * 8594 sizeof(wmi_therm_throt_level_config_info); 8595 8596 buf = wmi_buf_alloc(wmi_handle, len); 8597 if (!buf) 8598 return QDF_STATUS_E_NOMEM; 8599 8600 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 8601 8602 /* init fixed params */ 8603 WMITLV_SET_HDR(tt_conf, 8604 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 8605 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 8606 8607 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8608 wmi_handle, 8609 param->pdev_id); 8610 tt_conf->enable = param->enable; 8611 tt_conf->dc = param->dc; 8612 tt_conf->dc_per_event = param->dc_per_event; 8613 tt_conf->therm_throt_levels = param->num_thermal_conf; 8614 wmi_fill_client_id_priority(tt_conf, param); 8615 buf_ptr = (uint8_t *) ++tt_conf; 8616 /* init TLV params */ 8617 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8618 (param->num_thermal_conf * 8619 sizeof(wmi_therm_throt_level_config_info))); 8620 8621 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 8622 for (i = 0; i < param->num_thermal_conf; i++) { 8623 WMITLV_SET_HDR(&lvl_conf->tlv_header, 8624 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 8625 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 8626 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 8627 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 8628 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 8629 lvl_conf->prio = param->levelconf[i].priority; 8630 lvl_conf++; 8631 } 8632 8633 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 8634 error = wmi_unified_cmd_send(wmi_handle, buf, len, 8635 WMI_THERM_THROT_SET_CONF_CMDID); 8636 if (QDF_IS_STATUS_ERROR(error)) { 8637 wmi_buf_free(buf); 8638 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 8639 } 8640 8641 return error; 8642 } 8643 8644 /** 8645 * send_coex_config_cmd_tlv() - send coex config command to fw 8646 * @wmi_handle: wmi handle 8647 * @param: pointer to coex config param 8648 * 8649 * Return: 0 for success or error code 8650 */ 8651 static QDF_STATUS 8652 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 8653 struct coex_config_params *param) 8654 { 8655 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 8656 wmi_buf_t buf; 8657 QDF_STATUS ret; 8658 int32_t len; 8659 8660 len = sizeof(*cmd); 8661 buf = wmi_buf_alloc(wmi_handle, len); 8662 if (!buf) 8663 return QDF_STATUS_E_FAILURE; 8664 8665 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 8666 WMITLV_SET_HDR(&cmd->tlv_header, 8667 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 8668 WMITLV_GET_STRUCT_TLVLEN( 8669 WMI_COEX_CONFIG_CMD_fixed_param)); 8670 8671 cmd->vdev_id = param->vdev_id; 8672 cmd->config_type = param->config_type; 8673 cmd->config_arg1 = param->config_arg1; 8674 cmd->config_arg2 = param->config_arg2; 8675 cmd->config_arg3 = param->config_arg3; 8676 cmd->config_arg4 = param->config_arg4; 8677 cmd->config_arg5 = param->config_arg5; 8678 cmd->config_arg6 = param->config_arg6; 8679 8680 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 8681 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8682 WMI_COEX_CONFIG_CMDID); 8683 8684 if (ret != 0) { 8685 wmi_err("Sending COEX CONFIG CMD failed"); 8686 wmi_buf_free(buf); 8687 } 8688 8689 return ret; 8690 } 8691 8692 #ifdef WLAN_FEATURE_DBAM_CONFIG 8693 8694 static enum wmi_coex_dbam_mode_type 8695 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 8696 { 8697 switch (mode) { 8698 case COEX_DBAM_ENABLE: 8699 return WMI_COEX_DBAM_ENABLE; 8700 case COEX_DBAM_FORCE_ENABLE: 8701 return WMI_COEX_DBAM_FORCED; 8702 case COEX_DBAM_DISABLE: 8703 default: 8704 return WMI_COEX_DBAM_DISABLE; 8705 } 8706 } 8707 8708 /** 8709 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 8710 * @wmi_handle: wmi handle 8711 * @param: pointer to coex dbam config param 8712 * 8713 * Return: 0 for success or error code 8714 */ 8715 static QDF_STATUS 8716 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 8717 struct coex_dbam_config_params *param) 8718 { 8719 wmi_coex_dbam_cmd_fixed_param *cmd; 8720 wmi_buf_t buf; 8721 void *buf_ptr; 8722 QDF_STATUS ret; 8723 int32_t len; 8724 8725 len = sizeof(*cmd); 8726 buf = wmi_buf_alloc(wmi_handle, len); 8727 if (!buf) { 8728 wmi_err_rl("Failed to allocate wmi buffer"); 8729 return QDF_STATUS_E_NOMEM; 8730 } 8731 8732 buf_ptr = wmi_buf_data(buf); 8733 cmd = buf_ptr; 8734 WMITLV_SET_HDR(&cmd->tlv_header, 8735 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 8736 WMITLV_GET_STRUCT_TLVLEN( 8737 wmi_coex_dbam_cmd_fixed_param)); 8738 8739 cmd->vdev_id = param->vdev_id; 8740 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 8741 8742 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 8743 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8744 WMI_COEX_DBAM_CMDID); 8745 8746 if (QDF_IS_STATUS_ERROR(ret)) { 8747 wmi_err("Sending DBAM CONFIG CMD failed"); 8748 wmi_buf_free(buf); 8749 return QDF_STATUS_E_FAILURE; 8750 } 8751 8752 return ret; 8753 } 8754 8755 static enum coex_dbam_comp_status 8756 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 8757 { 8758 switch (status) { 8759 case WMI_COEX_DBAM_COMP_SUCCESS: 8760 case WMI_COEX_DBAM_COMP_ONGOING: 8761 case WMI_COEX_DBAM_COMP_DELAYED: 8762 return COEX_DBAM_COMP_SUCCESS; 8763 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 8764 return COEX_DBAM_COMP_NOT_SUPPORT; 8765 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 8766 case WMI_COEX_DBAM_COMP_FAIL: 8767 default: 8768 return COEX_DBAM_COMP_FAIL; 8769 } 8770 } 8771 8772 /** 8773 * extract_dbam_comp_status_event_tlv() - extract dbam complete status event 8774 * @wmi_handle: WMI handle 8775 * @evt_buf: event buffer 8776 * @resp: pointer to coex dbam config response 8777 * 8778 * Return: QDF_STATUS 8779 */ 8780 static QDF_STATUS 8781 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 8782 struct coex_dbam_config_resp *resp) 8783 { 8784 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 8785 wmi_coex_dbam_complete_event_fixed_param *event; 8786 8787 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 8788 8789 event = param_buf->fixed_param; 8790 8791 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 8792 8793 return QDF_STATUS_SUCCESS; 8794 } 8795 #endif 8796 8797 #ifdef WLAN_SUPPORT_TWT 8798 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8799 target_resource_config *tgt_res_cfg) 8800 { 8801 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 8802 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 8803 } 8804 #else 8805 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 8806 target_resource_config *tgt_res_cfg) 8807 { 8808 resource_cfg->twt_ap_pdev_count = 0; 8809 resource_cfg->twt_ap_sta_count = 0; 8810 } 8811 #endif 8812 8813 #ifdef WLAN_FEATURE_NAN 8814 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8815 { 8816 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 8817 resource_cfg->host_service_flags, 1); 8818 } 8819 #else 8820 static inline 8821 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 8822 { 8823 } 8824 #endif 8825 8826 #if defined(CONFIG_AFC_SUPPORT) 8827 static 8828 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8829 target_resource_config *tgt_res_cfg) 8830 { 8831 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 8832 resource_cfg->host_service_flags, 8833 tgt_res_cfg->afc_indoor_support); 8834 8835 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 8836 resource_cfg->host_service_flags, 8837 tgt_res_cfg->afc_outdoor_support); 8838 } 8839 #else 8840 static 8841 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 8842 target_resource_config *tgt_res_cfg) 8843 { 8844 } 8845 #endif 8846 8847 static 8848 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 8849 target_resource_config *tgt_res_cfg) 8850 { 8851 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 8852 resource_cfg->num_peers = tgt_res_cfg->num_peers; 8853 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 8854 resource_cfg->num_offload_reorder_buffs = 8855 tgt_res_cfg->num_offload_reorder_buffs; 8856 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 8857 resource_cfg->num_tids = tgt_res_cfg->num_tids; 8858 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 8859 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 8860 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 8861 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 8862 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 8863 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 8864 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 8865 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 8866 resource_cfg->scan_max_pending_req = 8867 tgt_res_cfg->scan_max_pending_req; 8868 resource_cfg->bmiss_offload_max_vdev = 8869 tgt_res_cfg->bmiss_offload_max_vdev; 8870 resource_cfg->roam_offload_max_vdev = 8871 tgt_res_cfg->roam_offload_max_vdev; 8872 resource_cfg->roam_offload_max_ap_profiles = 8873 tgt_res_cfg->roam_offload_max_ap_profiles; 8874 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 8875 resource_cfg->num_mcast_table_elems = 8876 tgt_res_cfg->num_mcast_table_elems; 8877 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 8878 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 8879 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 8880 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 8881 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 8882 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 8883 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 8884 resource_cfg->vow_config = tgt_res_cfg->vow_config; 8885 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 8886 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 8887 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 8888 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 8889 resource_cfg->num_tdls_conn_table_entries = 8890 tgt_res_cfg->num_tdls_conn_table_entries; 8891 resource_cfg->beacon_tx_offload_max_vdev = 8892 tgt_res_cfg->beacon_tx_offload_max_vdev; 8893 resource_cfg->num_multicast_filter_entries = 8894 tgt_res_cfg->num_multicast_filter_entries; 8895 resource_cfg->num_wow_filters = 8896 tgt_res_cfg->num_wow_filters; 8897 resource_cfg->num_keep_alive_pattern = 8898 tgt_res_cfg->num_keep_alive_pattern; 8899 resource_cfg->keep_alive_pattern_size = 8900 tgt_res_cfg->keep_alive_pattern_size; 8901 resource_cfg->max_tdls_concurrent_sleep_sta = 8902 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 8903 resource_cfg->max_tdls_concurrent_buffer_sta = 8904 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 8905 resource_cfg->wmi_send_separate = 8906 tgt_res_cfg->wmi_send_separate; 8907 resource_cfg->num_ocb_vdevs = 8908 tgt_res_cfg->num_ocb_vdevs; 8909 resource_cfg->num_ocb_channels = 8910 tgt_res_cfg->num_ocb_channels; 8911 resource_cfg->num_ocb_schedules = 8912 tgt_res_cfg->num_ocb_schedules; 8913 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 8914 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 8915 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 8916 resource_cfg->max_num_dbs_scan_duty_cycle = 8917 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 8918 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 8919 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 8920 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 8921 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 8922 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 8923 /* Deferred AI: Max rnr neighbors supported in multisoc case 8924 * where in SoC can support 6ghz. During WMI init of a SoC 8925 * currently there is no way to figure if another SOC is plugged in 8926 * and it can support 6Ghz. 8927 */ 8928 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 8929 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 8930 resource_cfg->ema_max_profile_period = 8931 tgt_res_cfg->ema_max_profile_period; 8932 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 8933 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 8934 8935 if (tgt_res_cfg->max_ndp_sessions) 8936 resource_cfg->max_ndp_sessions = 8937 tgt_res_cfg->max_ndp_sessions; 8938 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 8939 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 8940 8941 if (tgt_res_cfg->atf_config) 8942 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 8943 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 8944 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 8945 resource_cfg->flag1, 1); 8946 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 8947 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 8948 resource_cfg->flag1, 1); 8949 if (tgt_res_cfg->cce_disable) 8950 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 8951 if (tgt_res_cfg->enable_pci_gen) 8952 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 8953 resource_cfg->flag1, 1); 8954 if (tgt_res_cfg->eapol_minrate_set) { 8955 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 8956 resource_cfg->flag1, 1); 8957 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 8958 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 8959 resource_cfg->flag1, 1); 8960 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 8961 resource_cfg->flag1, 8962 tgt_res_cfg->eapol_minrate_ac_set); 8963 } 8964 } 8965 if (tgt_res_cfg->new_htt_msg_format) { 8966 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 8967 resource_cfg->flag1, 1); 8968 } 8969 8970 if (tgt_res_cfg->peer_unmap_conf_support) 8971 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 8972 resource_cfg->flag1, 1); 8973 8974 if (tgt_res_cfg->tstamp64_en) 8975 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 8976 resource_cfg->flag1, 1); 8977 8978 if (tgt_res_cfg->three_way_coex_config_legacy_en) 8979 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 8980 resource_cfg->flag1, 1); 8981 if (tgt_res_cfg->pktcapture_support) 8982 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 8983 resource_cfg->flag1, 1); 8984 8985 /* 8986 * Control padding using config param/ini of iphdr_pad_config 8987 */ 8988 if (tgt_res_cfg->iphdr_pad_config) 8989 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 8990 resource_cfg->flag1, 1); 8991 8992 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 8993 tgt_res_cfg->ipa_disable); 8994 8995 if (tgt_res_cfg->time_sync_ftm) 8996 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 8997 1); 8998 8999 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9000 resource_cfg->peer_map_unmap_versions = 9001 tgt_res_cfg->peer_map_unmap_version; 9002 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9003 if (tgt_res_cfg->re_ul_resp) 9004 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9005 tgt_res_cfg->re_ul_resp); 9006 9007 /* 9008 * Enable Service Aware Wifi 9009 */ 9010 if (tgt_res_cfg->sawf) 9011 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9012 tgt_res_cfg->sawf); 9013 9014 /* 9015 * Enable ast flow override per peer 9016 */ 9017 resource_cfg->msdu_flow_override_config0 = 0; 9018 WMI_MSDU_FLOW_AST_ENABLE_SET( 9019 resource_cfg->msdu_flow_override_config0, 9020 WMI_CONFIG_MSDU_AST_INDEX_1, 9021 tgt_res_cfg->ast_1_valid_mask_enable); 9022 9023 WMI_MSDU_FLOW_AST_ENABLE_SET( 9024 resource_cfg->msdu_flow_override_config0, 9025 WMI_CONFIG_MSDU_AST_INDEX_2, 9026 tgt_res_cfg->ast_2_valid_mask_enable); 9027 9028 WMI_MSDU_FLOW_AST_ENABLE_SET( 9029 resource_cfg->msdu_flow_override_config0, 9030 WMI_CONFIG_MSDU_AST_INDEX_3, 9031 tgt_res_cfg->ast_3_valid_mask_enable); 9032 9033 /* 9034 * Enable ast flow mask and TID valid mask configurations 9035 */ 9036 resource_cfg->msdu_flow_override_config1 = 0; 9037 9038 /*Enable UDP flow for Ast index 0*/ 9039 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9040 resource_cfg->msdu_flow_override_config1, 9041 WMI_CONFIG_MSDU_AST_INDEX_0, 9042 tgt_res_cfg->ast_0_flow_mask_enable); 9043 9044 /*Enable Non UDP flow for Ast index 1*/ 9045 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9046 resource_cfg->msdu_flow_override_config1, 9047 WMI_CONFIG_MSDU_AST_INDEX_1, 9048 tgt_res_cfg->ast_1_flow_mask_enable); 9049 9050 /*Enable Hi-Priority flow for Ast index 2*/ 9051 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9052 resource_cfg->msdu_flow_override_config1, 9053 WMI_CONFIG_MSDU_AST_INDEX_2, 9054 tgt_res_cfg->ast_2_flow_mask_enable); 9055 9056 /*Enable Low-Priority flow for Ast index 3*/ 9057 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9058 resource_cfg->msdu_flow_override_config1, 9059 WMI_CONFIG_MSDU_AST_INDEX_3, 9060 tgt_res_cfg->ast_3_flow_mask_enable); 9061 9062 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9063 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9064 resource_cfg->msdu_flow_override_config1, 9065 tgt_res_cfg->ast_tid_high_mask_enable); 9066 9067 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9068 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9069 resource_cfg->msdu_flow_override_config1, 9070 tgt_res_cfg->ast_tid_low_mask_enable); 9071 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9072 resource_cfg->host_service_flags, 9073 tgt_res_cfg->nan_separate_iface_support); 9074 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9075 resource_cfg->host_service_flags, 1); 9076 9077 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9078 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9079 9080 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9081 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9082 resource_cfg->flags2, 1); 9083 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9084 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9085 resource_cfg->flags2, 1); 9086 9087 if (tgt_res_cfg->sae_eapol_offload) 9088 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9089 resource_cfg->host_service_flags, 1); 9090 9091 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9092 resource_cfg->host_service_flags, 9093 tgt_res_cfg->is_reg_cc_ext_event_supported); 9094 9095 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9096 resource_cfg->host_service_flags, 9097 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9098 9099 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9100 resource_cfg->host_service_flags, 9101 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9102 9103 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9104 resource_cfg->host_service_flags, 9105 tgt_res_cfg->afc_timer_check_disable); 9106 9107 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9108 resource_cfg->host_service_flags, 9109 tgt_res_cfg->afc_req_id_check_disable); 9110 9111 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9112 9113 wmi_set_nan_channel_support(resource_cfg); 9114 9115 if (tgt_res_cfg->twt_ack_support_cap) 9116 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9117 resource_cfg->host_service_flags, 1); 9118 9119 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9120 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9121 resource_cfg->host_service_flags, 1); 9122 9123 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 9124 tgt_res_cfg->target_cap_flags); 9125 if (tgt_res_cfg->notify_frame_support) 9126 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9127 resource_cfg->flags2, 1); 9128 9129 } 9130 9131 #ifdef FEATURE_SET 9132 /** 9133 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9134 * requirement2 version to target vendor1 requirement2 version 9135 * @vendor1_req2_ver: Host vendor1 requirement2 version 9136 * 9137 * Return: Target vendor1 requirement2 version 9138 */ 9139 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9140 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9141 { 9142 switch (vendor1_req2_ver) { 9143 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9144 return WMI_VENDOR1_REQ2_VERSION_3_00; 9145 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9146 return WMI_VENDOR1_REQ2_VERSION_3_01; 9147 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9148 return WMI_VENDOR1_REQ2_VERSION_3_20; 9149 default: 9150 return WMI_VENDOR1_REQ2_VERSION_3_00; 9151 } 9152 } 9153 9154 /** 9155 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9156 * requirement1 version to target vendor1 requirement1 version 9157 * @vendor1_req1_ver: Host vendor1 requirement1 version 9158 * 9159 * Return: Target vendor1 requirement1 version 9160 */ 9161 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9162 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9163 { 9164 switch (vendor1_req1_ver) { 9165 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9166 return WMI_VENDOR1_REQ1_VERSION_3_00; 9167 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9168 return WMI_VENDOR1_REQ1_VERSION_3_01; 9169 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9170 return WMI_VENDOR1_REQ1_VERSION_3_20; 9171 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9172 return WMI_VENDOR1_REQ1_VERSION_3_30; 9173 default: 9174 return WMI_VENDOR1_REQ1_VERSION_3_00; 9175 } 9176 } 9177 9178 /** 9179 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9180 * target wifi standard 9181 * @wifi_standard: Host wifi standard 9182 * 9183 * Return: Target wifi standard 9184 */ 9185 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9186 WMI_HOST_WIFI_STANDARD wifi_standard) 9187 { 9188 switch (wifi_standard) { 9189 case WMI_HOST_WIFI_STANDARD_4: 9190 return WMI_WIFI_STANDARD_4; 9191 case WMI_HOST_WIFI_STANDARD_5: 9192 return WMI_WIFI_STANDARD_5; 9193 case WMI_HOST_WIFI_STANDARD_6: 9194 return WMI_WIFI_STANDARD_6; 9195 case WMI_HOST_WIFI_STANDARD_6E: 9196 return WMI_WIFI_STANDARD_6E; 9197 case WMI_HOST_WIFI_STANDARD_7: 9198 return WMI_WIFI_STANDARD_7; 9199 default: 9200 return WMI_WIFI_STANDARD_4; 9201 } 9202 } 9203 9204 /** 9205 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 9206 * target band concurrency 9207 * @band_concurrency: Host Band concurrency 9208 * 9209 * Return: Target band concurrency 9210 */ 9211 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 9212 WMI_HOST_BAND_CONCURRENCY band_concurrency) 9213 { 9214 switch (band_concurrency) { 9215 case WMI_HOST_BAND_CONCURRENCY_DBS: 9216 return WMI_HOST_DBS; 9217 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 9218 return WMI_HOST_DBS_SBS; 9219 default: 9220 return WMI_HOST_NONE; 9221 } 9222 } 9223 9224 /** 9225 * convert_host_to_target_num_antennas() -Convert host num antennas to 9226 * target num antennas 9227 * @num_antennas: Host num antennas 9228 * 9229 * Return: Target num antennas 9230 */ 9231 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 9232 WMI_HOST_NUM_ANTENNAS num_antennas) 9233 { 9234 switch (num_antennas) { 9235 case WMI_HOST_SISO: 9236 return WMI_SISO; 9237 case WMI_HOST_MIMO_2X2: 9238 return WMI_MIMO_2X2; 9239 default: 9240 return WMI_SISO; 9241 } 9242 } 9243 9244 /** 9245 * convert_host_to_target_band_capability() -Convert host band capability to 9246 * target band capability 9247 * @host_band_capability: Host band capability 9248 * 9249 * Return: Target band capability bitmap 9250 */ 9251 static uint8_t 9252 convert_host_to_target_band_capability(uint32_t host_band_capability) 9253 { 9254 uint8_t band_capability; 9255 9256 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 9257 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 9258 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 9259 return band_capability; 9260 } 9261 9262 /** 9263 * copy_feature_set_info() -Copy feature set info from host to target 9264 * @feature_set_bitmap: Target feature set pointer 9265 * @feature_set: Host feature set structure 9266 * 9267 * Return: None 9268 */ 9269 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 9270 struct target_feature_set *feature_set) 9271 { 9272 WMI_NUM_ANTENNAS num_antennas; 9273 WMI_BAND_CONCURRENCY band_concurrency; 9274 WMI_WIFI_STANDARD wifi_standard; 9275 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 9276 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 9277 uint8_t band_capability; 9278 9279 num_antennas = convert_host_to_target_num_antennas( 9280 feature_set->num_antennas); 9281 band_concurrency = convert_host_to_target_band_concurrency( 9282 feature_set->concurrency_support); 9283 wifi_standard = convert_host_to_target_wifi_standard( 9284 feature_set->wifi_standard); 9285 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 9286 feature_set->vendor_req_1_version); 9287 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 9288 feature_set->vendor_req_2_version); 9289 9290 band_capability = 9291 convert_host_to_target_band_capability( 9292 feature_set->band_capability); 9293 9294 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 9295 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 9296 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 9297 feature_set->pno_in_unassoc_state); 9298 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 9299 feature_set->pno_in_assoc_state); 9300 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 9301 feature_set->enable_twt); 9302 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 9303 feature_set->enable_twt_requester); 9304 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 9305 feature_set->enable_twt_broadcast); 9306 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 9307 feature_set->enable_twt_flexible); 9308 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 9309 feature_set->enable_wifi_optimizer); 9310 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 9311 feature_set->enable_rfc835); 9312 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 9313 feature_set->sap_5g_supported); 9314 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 9315 feature_set->sap_6g_supported); 9316 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 9317 feature_set->sap_max_num_clients); 9318 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 9319 feature_set_bitmap, 9320 feature_set->set_country_code_hal_supported); 9321 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 9322 feature_set_bitmap, 9323 feature_set->get_valid_channel_supported); 9324 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 9325 feature_set->supported_dot11mode); 9326 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 9327 feature_set->sap_wpa3_support); 9328 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 9329 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 9330 feature_set_bitmap, 9331 feature_set->roaming_high_cu_roam_trigger); 9332 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 9333 feature_set_bitmap, 9334 feature_set->roaming_emergency_trigger); 9335 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 9336 feature_set->roaming_btm_trihgger); 9337 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 9338 feature_set->roaming_idle_trigger); 9339 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 9340 feature_set->roaming_wtc_trigger); 9341 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 9342 feature_set->roaming_btcoex_trigger); 9343 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 9344 feature_set->roaming_btw_wpa_wpa2); 9345 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 9346 feature_set_bitmap, 9347 feature_set->roaming_manage_chan_list_api); 9348 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 9349 feature_set->roaming_adaptive_11r); 9350 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 9351 feature_set->roaming_ctrl_api_get_set); 9352 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 9353 feature_set->roaming_ctrl_api_reassoc); 9354 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 9355 feature_set->roaming_ctrl_get_cu); 9356 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 9357 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 9358 feature_set_bitmap, 9359 feature_set->assurance_disconnect_reason_api); 9360 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 9361 feature_set->frame_pcap_log_mgmt); 9362 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 9363 feature_set->frame_pcap_log_ctrl); 9364 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 9365 feature_set->frame_pcap_log_data); 9366 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 9367 feature_set->security_wpa3_sae_h2e); 9368 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 9369 feature_set->security_wpa3_sae_ft); 9370 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 9371 feature_set_bitmap, 9372 feature_set->security_wpa3_enterp_suitb); 9373 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 9374 feature_set_bitmap, 9375 feature_set->security_wpa3_enterp_suitb_192bit); 9376 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 9377 feature_set->security_fills_sha_256); 9378 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 9379 feature_set->security_fills_sha_384); 9380 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 9381 feature_set->security_fills_sha_256_FT); 9382 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 9383 feature_set->security_fills_sha_384_FT); 9384 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 9385 feature_set->security_enhanced_open); 9386 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 9387 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 9388 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 9389 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 9390 feature_set->enable_tdls_offchannel); 9391 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 9392 feature_set->enable_tdls_capability_enhance); 9393 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 9394 feature_set->max_tdls_peers); 9395 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 9396 feature_set->sta_dual_p2p_support); 9397 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 9398 feature_set_bitmap, 9399 feature_set->peer_bigdata_getbssinfo_support); 9400 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 9401 feature_set_bitmap, 9402 feature_set->peer_bigdata_assocreject_info_support); 9403 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 9404 feature_set_bitmap, 9405 feature_set->peer_getstainfo_support); 9406 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 9407 feature_set->feature_set_version); 9408 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 9409 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 9410 } 9411 9412 /** 9413 * feature_set_cmd_send_tlv() -Send feature set command 9414 * @wmi_handle: WMI handle 9415 * @feature_set: Feature set structure 9416 * 9417 * Return: QDF_STATUS_SUCCESS on success else return failure 9418 */ 9419 static QDF_STATUS feature_set_cmd_send_tlv( 9420 struct wmi_unified *wmi_handle, 9421 struct target_feature_set *feature_set) 9422 { 9423 wmi_pdev_featureset_cmd_fixed_param *cmd; 9424 wmi_buf_t buf; 9425 uint16_t len; 9426 QDF_STATUS ret; 9427 uint8_t *buf_ptr; 9428 uint32_t *feature_set_bitmap; 9429 9430 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9431 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 9432 buf = wmi_buf_alloc(wmi_handle, len); 9433 9434 if (!buf) 9435 return QDF_STATUS_E_NOMEM; 9436 9437 wmi_debug("Send feature set param"); 9438 9439 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9440 9441 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 9442 9443 WMITLV_SET_HDR(&cmd->tlv_header, 9444 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 9445 WMITLV_GET_STRUCT_TLVLEN( 9446 wmi_pdev_featureset_cmd_fixed_param)); 9447 9448 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 9449 WMI_TLV_HDR_SIZE); 9450 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 9451 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 9452 copy_feature_set_info(feature_set_bitmap, feature_set); 9453 9454 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 9455 feature_set_bitmap, 9456 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 9457 sizeof(uint32_t)); 9458 9459 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 9460 9461 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9462 WMI_PDEV_FEATURESET_CMDID); 9463 if (QDF_IS_STATUS_ERROR(ret)) 9464 wmi_buf_free(buf); 9465 9466 return ret; 9467 } 9468 #endif 9469 9470 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 9471 * @wmi_handle: pointer to wmi handle 9472 * @buf_ptr: pointer to current position in init command buffer 9473 * @len: pointer to length. This will be updated with current length of cmd 9474 * @param: point host parameters for init command 9475 * 9476 * Return: Updated pointer of buf_ptr. 9477 */ 9478 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 9479 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 9480 { 9481 uint16_t idx; 9482 9483 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 9484 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 9485 wmi_pdev_band_to_mac *band_to_mac; 9486 9487 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 9488 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 9489 sizeof(wmi_resource_config) + 9490 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 9491 sizeof(wlan_host_memory_chunk))); 9492 9493 WMITLV_SET_HDR(&hw_mode->tlv_header, 9494 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 9495 (WMITLV_GET_STRUCT_TLVLEN 9496 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 9497 9498 hw_mode->hw_mode_index = param->hw_mode_id; 9499 hw_mode->num_band_to_mac = param->num_band_to_mac; 9500 9501 buf_ptr = (uint8_t *) (hw_mode + 1); 9502 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 9503 WMI_TLV_HDR_SIZE); 9504 for (idx = 0; idx < param->num_band_to_mac; idx++) { 9505 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 9506 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 9507 WMITLV_GET_STRUCT_TLVLEN 9508 (wmi_pdev_band_to_mac)); 9509 band_to_mac[idx].pdev_id = 9510 wmi_handle->ops->convert_pdev_id_host_to_target( 9511 wmi_handle, 9512 param->band_to_mac[idx].pdev_id); 9513 band_to_mac[idx].start_freq = 9514 param->band_to_mac[idx].start_freq; 9515 band_to_mac[idx].end_freq = 9516 param->band_to_mac[idx].end_freq; 9517 } 9518 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9519 (param->num_band_to_mac * 9520 sizeof(wmi_pdev_band_to_mac)) + 9521 WMI_TLV_HDR_SIZE; 9522 9523 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9524 (param->num_band_to_mac * 9525 sizeof(wmi_pdev_band_to_mac))); 9526 } 9527 9528 return buf_ptr; 9529 } 9530 9531 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 9532 wmi_init_cmd_fixed_param *cmd) 9533 { 9534 int num_allowlist; 9535 wmi_abi_version my_vers; 9536 9537 num_allowlist = sizeof(version_whitelist) / 9538 sizeof(wmi_whitelist_version_info); 9539 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 9540 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 9541 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 9542 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 9543 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 9544 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 9545 9546 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 9547 &my_vers, 9548 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 9549 &cmd->host_abi_vers); 9550 9551 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 9552 __func__, 9553 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 9554 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 9555 cmd->host_abi_vers.abi_version_ns_0, 9556 cmd->host_abi_vers.abi_version_ns_1, 9557 cmd->host_abi_vers.abi_version_ns_2, 9558 cmd->host_abi_vers.abi_version_ns_3); 9559 9560 /* Save version sent from host - 9561 * Will be used to check ready event 9562 */ 9563 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 9564 sizeof(wmi_abi_version)); 9565 } 9566 9567 /* 9568 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 9569 * @wmi_handle: Pointer to WMi handle 9570 * @ie_data: Pointer for ie data 9571 * 9572 * This function sends action frame tb ppdu cfg to FW 9573 * 9574 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9575 * 9576 */ 9577 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 9578 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 9579 { 9580 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 9581 wmi_buf_t buf; 9582 uint8_t *buf_ptr; 9583 uint32_t len, frm_len_aligned; 9584 QDF_STATUS ret; 9585 9586 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 9587 /* Allocate memory for the WMI command */ 9588 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 9589 9590 buf = wmi_buf_alloc(wmi_handle, len); 9591 if (!buf) 9592 return QDF_STATUS_E_NOMEM; 9593 9594 buf_ptr = wmi_buf_data(buf); 9595 qdf_mem_zero(buf_ptr, len); 9596 9597 /* Populate the WMI command */ 9598 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 9599 9600 WMITLV_SET_HDR(&cmd->tlv_header, 9601 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 9602 WMITLV_GET_STRUCT_TLVLEN( 9603 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 9604 cmd->enable = cfg_msg->cfg; 9605 cmd->data_len = cfg_msg->frm_len; 9606 9607 buf_ptr += sizeof(*cmd); 9608 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 9609 buf_ptr += WMI_TLV_HDR_SIZE; 9610 9611 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 9612 9613 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9614 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 9615 if (QDF_IS_STATUS_ERROR(ret)) { 9616 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 9617 wmi_buf_free(buf); 9618 } 9619 9620 return ret; 9621 } 9622 9623 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9624 { 9625 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9626 wmi_service_ready_event_fixed_param *ev; 9627 9628 9629 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9630 9631 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9632 if (!ev) 9633 return QDF_STATUS_E_FAILURE; 9634 9635 /*Save fw version from service ready message */ 9636 /*This will be used while sending INIT message */ 9637 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9638 sizeof(wmi_handle->fw_abi_version)); 9639 9640 return QDF_STATUS_SUCCESS; 9641 } 9642 9643 /** 9644 * wmi_unified_save_fw_version_cmd() - save fw version 9645 * @wmi_handle: pointer to wmi handle 9646 * @res_cfg: resource config 9647 * @num_mem_chunks: no of mem chunk 9648 * @mem_chunk: pointer to mem chunk structure 9649 * 9650 * This function sends IE information to firmware 9651 * 9652 * Return: QDF_STATUS_SUCCESS for success otherwise failure 9653 * 9654 */ 9655 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 9656 void *evt_buf) 9657 { 9658 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9659 wmi_ready_event_fixed_param *ev = NULL; 9660 9661 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9662 ev = param_buf->fixed_param; 9663 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 9664 &wmi_handle->final_abi_vers, 9665 &ev->fw_abi_vers)) { 9666 /* 9667 * Error: Our host version and the given firmware version 9668 * are incompatible. 9669 **/ 9670 wmi_debug("Error: Incompatible WMI version." 9671 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 9672 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 9673 abi_version_0), 9674 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 9675 abi_version_0), 9676 wmi_handle->final_abi_vers.abi_version_ns_0, 9677 wmi_handle->final_abi_vers.abi_version_ns_1, 9678 wmi_handle->final_abi_vers.abi_version_ns_2, 9679 wmi_handle->final_abi_vers.abi_version_ns_3, 9680 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 9681 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 9682 ev->fw_abi_vers.abi_version_ns_0, 9683 ev->fw_abi_vers.abi_version_ns_1, 9684 ev->fw_abi_vers.abi_version_ns_2, 9685 ev->fw_abi_vers.abi_version_ns_3); 9686 9687 return QDF_STATUS_E_FAILURE; 9688 } 9689 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 9690 sizeof(wmi_abi_version)); 9691 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9692 sizeof(wmi_abi_version)); 9693 9694 return QDF_STATUS_SUCCESS; 9695 } 9696 9697 /** 9698 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 9699 * @handle: wmi handle 9700 * @event: Event received from FW 9701 * @len: Length of the event 9702 * 9703 * Enables the low frequency events and disables the high frequency 9704 * events. Bit 17 indicates if the event if low/high frequency. 9705 * 1 - high frequency, 0 - low frequency 9706 * 9707 * Return: 0 on successfully enabling/disabling the events 9708 */ 9709 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 9710 uint8_t *event, 9711 uint32_t len) 9712 { 9713 uint32_t num_of_diag_events_logs; 9714 wmi_diag_event_log_config_fixed_param *cmd; 9715 wmi_buf_t buf; 9716 uint8_t *buf_ptr; 9717 uint32_t *cmd_args, *evt_args; 9718 uint32_t buf_len, i; 9719 9720 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 9721 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 9722 9723 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 9724 9725 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 9726 if (!param_buf) { 9727 wmi_err("Invalid log supported event buffer"); 9728 return QDF_STATUS_E_INVAL; 9729 } 9730 wmi_event = param_buf->fixed_param; 9731 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 9732 9733 if (num_of_diag_events_logs > 9734 param_buf->num_diag_events_logs_list) { 9735 wmi_err("message number of events %d is more than tlv hdr content %d", 9736 num_of_diag_events_logs, 9737 param_buf->num_diag_events_logs_list); 9738 return QDF_STATUS_E_INVAL; 9739 } 9740 9741 evt_args = param_buf->diag_events_logs_list; 9742 if (!evt_args) { 9743 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 9744 num_of_diag_events_logs); 9745 return QDF_STATUS_E_INVAL; 9746 } 9747 9748 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 9749 9750 /* Free any previous allocation */ 9751 if (wmi_handle->events_logs_list) { 9752 qdf_mem_free(wmi_handle->events_logs_list); 9753 wmi_handle->events_logs_list = NULL; 9754 } 9755 9756 if (num_of_diag_events_logs > 9757 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 9758 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 9759 QDF_ASSERT(0); 9760 return QDF_STATUS_E_INVAL; 9761 } 9762 /* Store the event list for run time enable/disable */ 9763 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 9764 sizeof(uint32_t)); 9765 if (!wmi_handle->events_logs_list) 9766 return QDF_STATUS_E_NOMEM; 9767 9768 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 9769 9770 /* Prepare the send buffer */ 9771 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9772 (num_of_diag_events_logs * sizeof(uint32_t)); 9773 9774 buf = wmi_buf_alloc(wmi_handle, buf_len); 9775 if (!buf) { 9776 qdf_mem_free(wmi_handle->events_logs_list); 9777 wmi_handle->events_logs_list = NULL; 9778 return QDF_STATUS_E_NOMEM; 9779 } 9780 9781 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9782 buf_ptr = (uint8_t *) cmd; 9783 9784 WMITLV_SET_HDR(&cmd->tlv_header, 9785 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9786 WMITLV_GET_STRUCT_TLVLEN( 9787 wmi_diag_event_log_config_fixed_param)); 9788 9789 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 9790 9791 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9792 9793 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9794 (num_of_diag_events_logs * sizeof(uint32_t))); 9795 9796 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9797 9798 /* Populate the events */ 9799 for (i = 0; i < num_of_diag_events_logs; i++) { 9800 /* Low freq (0) - Enable (1) the event 9801 * High freq (1) - Disable (0) the event 9802 */ 9803 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 9804 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 9805 /* Set the event ID */ 9806 WMI_DIAG_ID_SET(cmd_args[i], 9807 WMI_DIAG_ID_GET(evt_args[i])); 9808 /* Set the type */ 9809 WMI_DIAG_TYPE_SET(cmd_args[i], 9810 WMI_DIAG_TYPE_GET(evt_args[i])); 9811 /* Storing the event/log list in WMI */ 9812 wmi_handle->events_logs_list[i] = evt_args[i]; 9813 } 9814 9815 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9816 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 9817 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9818 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9819 wmi_buf_free(buf); 9820 /* Not clearing events_logs_list, though wmi cmd failed. 9821 * Host can still have this list 9822 */ 9823 return QDF_STATUS_E_INVAL; 9824 } 9825 9826 return 0; 9827 } 9828 9829 /** 9830 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 9831 * @wmi_handle: wmi handle 9832 * @start_log: Start logging related parameters 9833 * 9834 * Send the command to the FW based on which specific logging of diag 9835 * event/log id can be started/stopped 9836 * 9837 * Return: None 9838 */ 9839 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 9840 struct wmi_wifi_start_log *start_log) 9841 { 9842 wmi_diag_event_log_config_fixed_param *cmd; 9843 wmi_buf_t buf; 9844 uint8_t *buf_ptr; 9845 uint32_t len, count, log_level, i; 9846 uint32_t *cmd_args; 9847 uint32_t total_len; 9848 count = 0; 9849 9850 if (!wmi_handle->events_logs_list) { 9851 wmi_debug("Not received event/log list from FW, yet"); 9852 return QDF_STATUS_E_NOMEM; 9853 } 9854 /* total_len stores the number of events where BITS 17 and 18 are set. 9855 * i.e., events of high frequency (17) and for extended debugging (18) 9856 */ 9857 total_len = 0; 9858 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 9859 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 9860 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 9861 total_len++; 9862 } 9863 9864 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9865 (total_len * sizeof(uint32_t)); 9866 9867 buf = wmi_buf_alloc(wmi_handle, len); 9868 if (!buf) 9869 return QDF_STATUS_E_NOMEM; 9870 9871 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 9872 buf_ptr = (uint8_t *) cmd; 9873 9874 WMITLV_SET_HDR(&cmd->tlv_header, 9875 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 9876 WMITLV_GET_STRUCT_TLVLEN( 9877 wmi_diag_event_log_config_fixed_param)); 9878 9879 cmd->num_of_diag_events_logs = total_len; 9880 9881 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 9882 9883 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 9884 (total_len * sizeof(uint32_t))); 9885 9886 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 9887 9888 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 9889 log_level = 1; 9890 else 9891 log_level = 0; 9892 9893 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 9894 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 9895 uint32_t val = wmi_handle->events_logs_list[i]; 9896 if ((WMI_DIAG_FREQUENCY_GET(val)) && 9897 (WMI_DIAG_EXT_FEATURE_GET(val))) { 9898 9899 WMI_DIAG_ID_SET(cmd_args[count], 9900 WMI_DIAG_ID_GET(val)); 9901 WMI_DIAG_TYPE_SET(cmd_args[count], 9902 WMI_DIAG_TYPE_GET(val)); 9903 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 9904 log_level); 9905 wmi_debug("Idx:%d, val:%x", i, val); 9906 count++; 9907 } 9908 } 9909 9910 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 9911 if (wmi_unified_cmd_send(wmi_handle, buf, len, 9912 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 9913 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 9914 wmi_buf_free(buf); 9915 return QDF_STATUS_E_INVAL; 9916 } 9917 9918 return QDF_STATUS_SUCCESS; 9919 } 9920 9921 /** 9922 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 9923 * @wmi_handle: WMI handle 9924 * 9925 * This function is used to send the flush command to the FW, 9926 * that will flush the fw logs that are residue in the FW 9927 * 9928 * Return: None 9929 */ 9930 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 9931 { 9932 wmi_debug_mesg_flush_fixed_param *cmd; 9933 wmi_buf_t buf; 9934 int len = sizeof(*cmd); 9935 QDF_STATUS ret; 9936 9937 buf = wmi_buf_alloc(wmi_handle, len); 9938 if (!buf) 9939 return QDF_STATUS_E_NOMEM; 9940 9941 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 9942 WMITLV_SET_HDR(&cmd->tlv_header, 9943 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 9944 WMITLV_GET_STRUCT_TLVLEN( 9945 wmi_debug_mesg_flush_fixed_param)); 9946 cmd->reserved0 = 0; 9947 9948 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 9949 ret = wmi_unified_cmd_send(wmi_handle, 9950 buf, 9951 len, 9952 WMI_DEBUG_MESG_FLUSH_CMDID); 9953 if (QDF_IS_STATUS_ERROR(ret)) { 9954 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 9955 wmi_buf_free(buf); 9956 return QDF_STATUS_E_INVAL; 9957 } 9958 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 9959 9960 return ret; 9961 } 9962 9963 #ifdef BIG_ENDIAN_HOST 9964 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 9965 /** 9966 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 9967 * @param - fips extend param related parameters 9968 * 9969 * Return: QDF_STATUS - success or error status 9970 */ 9971 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 9972 struct fips_extend_params *param) 9973 { 9974 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 9975 int c; 9976 u_int8_t *key_aligned = NULL; 9977 u_int8_t *nonce_iv_aligned = NULL; 9978 u_int8_t *data_aligned = NULL; 9979 int ret = QDF_STATUS_SUCCESS; 9980 9981 /* Assigning unaligned space to copy the key */ 9982 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 9983 param->cmd_params.key_len + FIPS_ALIGN); 9984 /* Checking if kmalloc is successful to allocate space */ 9985 if (!key_unaligned) 9986 return QDF_STATUS_E_INVAL; 9987 9988 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 9989 FIPS_ALIGN); 9990 /* Checking if kmalloc is successful to allocate space */ 9991 if (!data_unaligned) { 9992 ret = QDF_STATUS_E_INVAL; 9993 goto fips_align_fail_data; 9994 } 9995 9996 /* Checking if space is aligned */ 9997 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 9998 /* align to 4 */ 9999 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10000 FIPS_ALIGN); 10001 } else { 10002 key_aligned = (u_int8_t *)key_unaligned; 10003 } 10004 10005 /* memset and copy content from key to key aligned */ 10006 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10007 OS_MEMCPY(key_aligned, param->cmd_params.key, 10008 param->cmd_params.key_len); 10009 10010 /* print a hexdump for host debug */ 10011 wmi_debug("Aligned and Copied Key: "); 10012 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10013 key_aligned, param->cmd_params.key_len); 10014 10015 /* Checking of space is aligned */ 10016 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10017 /* align to 4 */ 10018 data_aligned = 10019 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10020 } else { 10021 data_aligned = (u_int8_t *)data_unaligned; 10022 } 10023 10024 /* memset and copy content from data to data aligned */ 10025 OS_MEMSET(data_aligned, 0, param->data_len); 10026 OS_MEMCPY(data_aligned, param->data, param->data_len); 10027 10028 /* print a hexdump for host debug */ 10029 wmi_debug("\t Properly Aligned and Copied Data: "); 10030 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10031 data_aligned, param->data_len); 10032 10033 /* converting to little Endian */ 10034 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10035 *((u_int32_t *)key_aligned + c) = 10036 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10037 } 10038 for (c = 0; c < param->data_len / 4; c++) { 10039 *((u_int32_t *)data_aligned + c) = 10040 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10041 } 10042 10043 /* update endian data */ 10044 OS_MEMCPY(param->cmd_params.key, key_aligned, 10045 param->cmd_params.key_len); 10046 OS_MEMCPY(param->data, data_aligned, param->data_len); 10047 10048 if (param->cmd_params.nonce_iv_len) { 10049 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10050 param->cmd_params.nonce_iv_len + 10051 FIPS_ALIGN); 10052 10053 /* Checking if kmalloc is successful to allocate space */ 10054 if (!nonce_iv_unaligned) { 10055 ret = QDF_STATUS_E_INVAL; 10056 goto fips_align_fail_nonce_iv; 10057 } 10058 /* Checking if space is aligned */ 10059 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10060 /* align to 4 */ 10061 nonce_iv_aligned = 10062 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10063 FIPS_ALIGN); 10064 } else { 10065 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10066 } 10067 10068 /* memset and copy content from iv to iv aligned */ 10069 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10070 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10071 param->cmd_params.nonce_iv_len); 10072 10073 /* print a hexdump for host debug */ 10074 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10075 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10076 nonce_iv_aligned, 10077 param->cmd_params.nonce_iv_len); 10078 10079 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10080 *((u_int32_t *)nonce_iv_aligned + c) = 10081 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10082 } 10083 } 10084 10085 /* clean up allocated spaces */ 10086 qdf_mem_free(nonce_iv_unaligned); 10087 nonce_iv_unaligned = NULL; 10088 nonce_iv_aligned = NULL; 10089 10090 fips_align_fail_nonce_iv: 10091 qdf_mem_free(data_unaligned); 10092 data_unaligned = NULL; 10093 data_aligned = NULL; 10094 10095 fips_align_fail_data: 10096 qdf_mem_free(key_unaligned); 10097 key_unaligned = NULL; 10098 key_aligned = NULL; 10099 10100 return ret; 10101 } 10102 #endif 10103 10104 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10105 struct fips_params *param) 10106 { 10107 unsigned char *key_unaligned, *data_unaligned; 10108 int c; 10109 u_int8_t *key_aligned = NULL; 10110 u_int8_t *data_aligned = NULL; 10111 10112 /* Assigning unaligned space to copy the key */ 10113 key_unaligned = qdf_mem_malloc( 10114 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10115 data_unaligned = qdf_mem_malloc( 10116 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10117 10118 /* Checking if kmalloc is successful to allocate space */ 10119 if (!key_unaligned) 10120 return QDF_STATUS_SUCCESS; 10121 /* Checking if space is aligned */ 10122 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10123 /* align to 4 */ 10124 key_aligned = 10125 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10126 FIPS_ALIGN); 10127 } else { 10128 key_aligned = (u_int8_t *)key_unaligned; 10129 } 10130 10131 /* memset and copy content from key to key aligned */ 10132 OS_MEMSET(key_aligned, 0, param->key_len); 10133 OS_MEMCPY(key_aligned, param->key, param->key_len); 10134 10135 /* print a hexdump for host debug */ 10136 print_hex_dump(KERN_DEBUG, 10137 "\t Aligned and Copied Key:@@@@ ", 10138 DUMP_PREFIX_NONE, 10139 16, 1, key_aligned, param->key_len, true); 10140 10141 /* Checking if kmalloc is successful to allocate space */ 10142 if (!data_unaligned) 10143 return QDF_STATUS_SUCCESS; 10144 /* Checking of space is aligned */ 10145 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10146 /* align to 4 */ 10147 data_aligned = 10148 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 10149 FIPS_ALIGN); 10150 } else { 10151 data_aligned = (u_int8_t *)data_unaligned; 10152 } 10153 10154 /* memset and copy content from data to data aligned */ 10155 OS_MEMSET(data_aligned, 0, param->data_len); 10156 OS_MEMCPY(data_aligned, param->data, param->data_len); 10157 10158 /* print a hexdump for host debug */ 10159 print_hex_dump(KERN_DEBUG, 10160 "\t Properly Aligned and Copied Data:@@@@ ", 10161 DUMP_PREFIX_NONE, 10162 16, 1, data_aligned, param->data_len, true); 10163 10164 /* converting to little Endian both key_aligned and 10165 * data_aligned*/ 10166 for (c = 0; c < param->key_len/4; c++) { 10167 *((u_int32_t *)key_aligned+c) = 10168 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 10169 } 10170 for (c = 0; c < param->data_len/4; c++) { 10171 *((u_int32_t *)data_aligned+c) = 10172 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 10173 } 10174 10175 /* update endian data to key and data vectors */ 10176 OS_MEMCPY(param->key, key_aligned, param->key_len); 10177 OS_MEMCPY(param->data, data_aligned, param->data_len); 10178 10179 /* clean up allocated spaces */ 10180 qdf_mem_free(key_unaligned); 10181 key_unaligned = NULL; 10182 key_aligned = NULL; 10183 10184 qdf_mem_free(data_unaligned); 10185 data_unaligned = NULL; 10186 data_aligned = NULL; 10187 10188 return QDF_STATUS_SUCCESS; 10189 } 10190 #else 10191 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10192 /** 10193 * fips_extend_align_data_be() - DUMMY for LE platform 10194 * 10195 * Return: QDF_STATUS - success 10196 */ 10197 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10198 struct fips_extend_params *param) 10199 { 10200 return QDF_STATUS_SUCCESS; 10201 } 10202 #endif 10203 10204 /** 10205 * fips_align_data_be() - DUMMY for LE platform 10206 * 10207 * Return: QDF_STATUS - success 10208 */ 10209 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10210 struct fips_params *param) 10211 { 10212 return QDF_STATUS_SUCCESS; 10213 } 10214 #endif 10215 10216 #ifdef WLAN_FEATURE_DISA 10217 /** 10218 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 10219 * @wmi_handle: wmi handle 10220 * @params: encrypt/decrypt params 10221 * 10222 * Return: QDF_STATUS_SUCCESS for success or error code 10223 */ 10224 static QDF_STATUS 10225 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 10226 struct disa_encrypt_decrypt_req_params 10227 *encrypt_decrypt_params) 10228 { 10229 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 10230 wmi_buf_t wmi_buf; 10231 uint8_t *buf_ptr; 10232 QDF_STATUS ret; 10233 uint32_t len; 10234 10235 wmi_debug("Send encrypt decrypt cmd"); 10236 10237 len = sizeof(*cmd) + 10238 encrypt_decrypt_params->data_len + 10239 WMI_TLV_HDR_SIZE; 10240 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10241 if (!wmi_buf) 10242 return QDF_STATUS_E_NOMEM; 10243 10244 buf_ptr = wmi_buf_data(wmi_buf); 10245 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 10246 10247 WMITLV_SET_HDR(&cmd->tlv_header, 10248 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 10249 WMITLV_GET_STRUCT_TLVLEN( 10250 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 10251 10252 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 10253 cmd->key_flag = encrypt_decrypt_params->key_flag; 10254 cmd->key_idx = encrypt_decrypt_params->key_idx; 10255 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 10256 cmd->key_len = encrypt_decrypt_params->key_len; 10257 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 10258 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 10259 10260 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 10261 encrypt_decrypt_params->key_len); 10262 10263 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 10264 MAX_MAC_HEADER_LEN); 10265 10266 cmd->data_len = encrypt_decrypt_params->data_len; 10267 10268 if (cmd->data_len) { 10269 buf_ptr += sizeof(*cmd); 10270 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10271 roundup(encrypt_decrypt_params->data_len, 10272 sizeof(uint32_t))); 10273 buf_ptr += WMI_TLV_HDR_SIZE; 10274 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 10275 encrypt_decrypt_params->data_len); 10276 } 10277 10278 /* This conversion is to facilitate data to FW in little endian */ 10279 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 10280 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 10281 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 10282 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 10283 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 10284 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 10285 10286 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 10287 ret = wmi_unified_cmd_send(wmi_handle, 10288 wmi_buf, len, 10289 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 10290 if (QDF_IS_STATUS_ERROR(ret)) { 10291 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 10292 wmi_buf_free(wmi_buf); 10293 } 10294 10295 return ret; 10296 } 10297 #endif /* WLAN_FEATURE_DISA */ 10298 10299 /** 10300 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 10301 * @wmi_handle: wmi handle 10302 * @param: pointer to hold pdev fips param 10303 * 10304 * Return: 0 for success or error code 10305 */ 10306 static QDF_STATUS 10307 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 10308 struct fips_params *param) 10309 { 10310 wmi_pdev_fips_cmd_fixed_param *cmd; 10311 wmi_buf_t buf; 10312 uint8_t *buf_ptr; 10313 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 10314 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10315 10316 /* Length TLV placeholder for array of bytes */ 10317 len += WMI_TLV_HDR_SIZE; 10318 if (param->data_len) 10319 len += (param->data_len*sizeof(uint8_t)); 10320 10321 /* 10322 * Data length must be multiples of 16 bytes - checked against 0xF - 10323 * and must be less than WMI_SVC_MSG_SIZE - static size of 10324 * wmi_pdev_fips_cmd structure 10325 */ 10326 10327 /* do sanity on the input */ 10328 if (!(((param->data_len & 0xF) == 0) && 10329 ((param->data_len > 0) && 10330 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 10331 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 10332 return QDF_STATUS_E_INVAL; 10333 } 10334 10335 buf = wmi_buf_alloc(wmi_handle, len); 10336 if (!buf) 10337 return QDF_STATUS_E_FAILURE; 10338 10339 buf_ptr = (uint8_t *) wmi_buf_data(buf); 10340 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 10341 WMITLV_SET_HDR(&cmd->tlv_header, 10342 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 10343 WMITLV_GET_STRUCT_TLVLEN 10344 (wmi_pdev_fips_cmd_fixed_param)); 10345 10346 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10347 wmi_handle, 10348 param->pdev_id); 10349 if (param->key && param->data) { 10350 cmd->key_len = param->key_len; 10351 cmd->data_len = param->data_len; 10352 cmd->fips_cmd = !!(param->op); 10353 10354 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 10355 return QDF_STATUS_E_FAILURE; 10356 10357 qdf_mem_copy(cmd->key, param->key, param->key_len); 10358 10359 if (param->mode == FIPS_ENGINE_AES_CTR || 10360 param->mode == FIPS_ENGINE_AES_MIC) { 10361 cmd->mode = param->mode; 10362 } else { 10363 cmd->mode = FIPS_ENGINE_AES_CTR; 10364 } 10365 qdf_print("Key len = %d, Data len = %d", 10366 cmd->key_len, cmd->data_len); 10367 10368 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 10369 cmd->key, cmd->key_len, true); 10370 buf_ptr += sizeof(*cmd); 10371 10372 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 10373 10374 buf_ptr += WMI_TLV_HDR_SIZE; 10375 if (param->data_len) 10376 qdf_mem_copy(buf_ptr, 10377 (uint8_t *) param->data, param->data_len); 10378 10379 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 10380 16, 1, buf_ptr, cmd->data_len, true); 10381 10382 buf_ptr += param->data_len; 10383 10384 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 10385 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10386 WMI_PDEV_FIPS_CMDID); 10387 qdf_print("%s return value %d", __func__, retval); 10388 } else { 10389 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 10390 wmi_buf_free(buf); 10391 retval = -QDF_STATUS_E_BADMSG; 10392 } 10393 10394 return retval; 10395 } 10396 10397 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10398 /** 10399 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 10400 * @wmi_handle: wmi handle 10401 * @param: pointer to hold pdev fips param 10402 * 10403 * Return: 0 for success or error code 10404 */ 10405 static QDF_STATUS 10406 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 10407 struct fips_extend_params *param) 10408 { 10409 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 10410 wmi_buf_t buf; 10411 uint8_t *buf_ptr; 10412 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 10413 uint32_t data_len_aligned; 10414 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10415 10416 len += WMI_TLV_HDR_SIZE; 10417 if (param->frag_idx == 0) 10418 len += sizeof(wmi_fips_extend_cmd_init_params); 10419 10420 /* Length TLV placeholder for array of bytes */ 10421 len += WMI_TLV_HDR_SIZE; 10422 if (param->data_len) { 10423 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 10424 len += (data_len_aligned * sizeof(uint8_t)); 10425 } 10426 10427 buf = wmi_buf_alloc(wmi_handle, len); 10428 if (!buf) 10429 return QDF_STATUS_E_FAILURE; 10430 10431 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10432 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 10433 WMITLV_SET_HDR(&cmd->tlv_header, 10434 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 10435 WMITLV_GET_STRUCT_TLVLEN 10436 (wmi_pdev_fips_extend_cmd_fixed_param)); 10437 10438 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10439 wmi_handle, 10440 param->pdev_id); 10441 10442 cmd->fips_cookie = param->cookie; 10443 cmd->frag_idx = param->frag_idx; 10444 cmd->more_bit = param->more_bit; 10445 cmd->data_len = param->data_len; 10446 10447 if (fips_extend_align_data_be(wmi_handle, param) != 10448 QDF_STATUS_SUCCESS) { 10449 wmi_buf_free(buf); 10450 return QDF_STATUS_E_FAILURE; 10451 } 10452 10453 buf_ptr = (uint8_t *)(cmd + 1); 10454 if (cmd->frag_idx == 0) { 10455 wmi_fips_extend_cmd_init_params *cmd_params; 10456 10457 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10458 sizeof(wmi_fips_extend_cmd_init_params)); 10459 buf_ptr += WMI_TLV_HDR_SIZE; 10460 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 10461 WMITLV_SET_HDR(buf_ptr, 10462 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 10463 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 10464 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 10465 cmd_params->key_cipher = param->cmd_params.key_cipher; 10466 cmd_params->key_len = param->cmd_params.key_len; 10467 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 10468 cmd_params->tag_len = param->cmd_params.tag_len; 10469 cmd_params->aad_len = param->cmd_params.aad_len; 10470 cmd_params->payload_len = param->cmd_params.payload_len; 10471 10472 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 10473 param->cmd_params.key_len); 10474 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 10475 param->cmd_params.nonce_iv_len); 10476 10477 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 10478 cmd_params->key_len, cmd_params->nonce_iv_len, 10479 cmd_params->tag_len, cmd_params->aad_len, 10480 cmd_params->payload_len); 10481 10482 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 10483 } else { 10484 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10485 buf_ptr += WMI_TLV_HDR_SIZE; 10486 } 10487 10488 if (param->data_len && param->data) { 10489 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 10490 data_len_aligned); 10491 10492 buf_ptr += WMI_TLV_HDR_SIZE; 10493 if (param->data_len) 10494 qdf_mem_copy(buf_ptr, 10495 (uint8_t *)param->data, param->data_len); 10496 10497 wmi_debug("Data: "); 10498 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10499 buf_ptr, cmd->data_len); 10500 10501 if (param->data_len) 10502 buf_ptr += param->data_len; 10503 } else { 10504 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 10505 buf_ptr += WMI_TLV_HDR_SIZE; 10506 } 10507 10508 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 10509 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10510 WMI_PDEV_FIPS_EXTEND_CMDID); 10511 10512 if (retval) { 10513 wmi_err("Failed to send FIPS cmd"); 10514 wmi_buf_free(buf); 10515 } 10516 10517 return retval; 10518 } 10519 10520 /** 10521 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 10522 * @wmi_handle: wmi handle 10523 * @param: pointer to hold pdev fips param 10524 * 10525 * Return: 0 for success or error code 10526 */ 10527 static QDF_STATUS 10528 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 10529 struct fips_mode_set_params *param) 10530 { 10531 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 10532 wmi_buf_t buf; 10533 uint8_t *buf_ptr; 10534 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 10535 QDF_STATUS retval = QDF_STATUS_SUCCESS; 10536 10537 buf = wmi_buf_alloc(wmi_handle, len); 10538 if (!buf) 10539 return QDF_STATUS_E_FAILURE; 10540 10541 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10542 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 10543 WMITLV_SET_HDR(&cmd->tlv_header, 10544 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 10545 WMITLV_GET_STRUCT_TLVLEN 10546 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 10547 10548 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 10549 wmi_handle, 10550 param->pdev_id); 10551 10552 cmd->fips_mode_set = param->mode; 10553 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 10554 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 10555 WMI_PDEV_FIPS_MODE_SET_CMDID); 10556 if (retval) { 10557 wmi_err("Failed to send FIPS mode enable cmd"); 10558 wmi_buf_free(buf); 10559 } 10560 return retval; 10561 } 10562 #endif 10563 10564 /** 10565 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 10566 * to fw 10567 * @wmi_handle: wmi handle 10568 * @param: pointer to wlan profile param 10569 * 10570 * Return: 0 for success or error code 10571 */ 10572 static QDF_STATUS 10573 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 10574 struct wlan_profile_params *param) 10575 { 10576 wmi_buf_t buf; 10577 uint16_t len; 10578 QDF_STATUS ret; 10579 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 10580 10581 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 10582 buf = wmi_buf_alloc(wmi_handle, len); 10583 if (!buf) { 10584 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 10585 return QDF_STATUS_E_NOMEM; 10586 } 10587 10588 profile_enable_cmd = 10589 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 10590 wmi_buf_data(buf); 10591 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 10592 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 10593 WMITLV_GET_STRUCT_TLVLEN 10594 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 10595 10596 profile_enable_cmd->profile_id = param->profile_id; 10597 profile_enable_cmd->enable = param->enable; 10598 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 10599 NO_SESSION, 0); 10600 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10601 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 10602 if (ret) { 10603 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 10604 wmi_buf_free(buf); 10605 } 10606 return ret; 10607 } 10608 10609 /** 10610 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 10611 * to fw 10612 * @wmi_handle: wmi handle 10613 * @param: pointer to wlan profile param 10614 * 10615 * Return: 0 for success or error code 10616 */ 10617 static QDF_STATUS 10618 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 10619 struct wlan_profile_params *param) 10620 { 10621 wmi_buf_t buf; 10622 uint16_t len; 10623 QDF_STATUS ret; 10624 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 10625 10626 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 10627 buf = wmi_buf_alloc(wmi_handle, len); 10628 if (!buf) { 10629 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10630 return QDF_STATUS_E_NOMEM; 10631 } 10632 10633 prof_trig_cmd = 10634 (wmi_wlan_profile_trigger_cmd_fixed_param *) 10635 wmi_buf_data(buf); 10636 10637 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 10638 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 10639 WMITLV_GET_STRUCT_TLVLEN 10640 (wmi_wlan_profile_trigger_cmd_fixed_param)); 10641 10642 prof_trig_cmd->enable = param->enable; 10643 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 10644 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10645 WMI_WLAN_PROFILE_TRIGGER_CMDID); 10646 if (ret) { 10647 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 10648 wmi_buf_free(buf); 10649 } 10650 return ret; 10651 } 10652 10653 /** 10654 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 10655 * to fw 10656 * @wmi_handle: wmi handle 10657 * @param: pointer to wlan profile param 10658 * 10659 * Return: 0 for success or error code 10660 */ 10661 static QDF_STATUS 10662 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 10663 struct wlan_profile_params *param) 10664 { 10665 wmi_buf_t buf; 10666 int32_t len = 0; 10667 QDF_STATUS ret; 10668 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 10669 10670 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 10671 buf = wmi_buf_alloc(wmi_handle, len); 10672 if (!buf) { 10673 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 10674 return QDF_STATUS_E_NOMEM; 10675 } 10676 10677 hist_intvl_cmd = 10678 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 10679 wmi_buf_data(buf); 10680 10681 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 10682 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 10683 WMITLV_GET_STRUCT_TLVLEN 10684 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 10685 10686 hist_intvl_cmd->profile_id = param->profile_id; 10687 hist_intvl_cmd->value = param->enable; 10688 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 10689 NO_SESSION, 0); 10690 10691 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10692 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 10693 if (ret) { 10694 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 10695 wmi_buf_free(buf); 10696 } 10697 return ret; 10698 } 10699 10700 /** 10701 * send_fw_test_cmd_tlv() - send fw test command to fw. 10702 * @wmi_handle: wmi handle 10703 * @wmi_fwtest: fw test command 10704 * 10705 * This function sends fw test command to fw. 10706 * 10707 * Return: CDF STATUS 10708 */ 10709 static 10710 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 10711 struct set_fwtest_params *wmi_fwtest) 10712 { 10713 wmi_fwtest_set_param_cmd_fixed_param *cmd; 10714 wmi_buf_t wmi_buf; 10715 uint16_t len; 10716 10717 len = sizeof(*cmd); 10718 10719 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10720 if (!wmi_buf) 10721 return QDF_STATUS_E_NOMEM; 10722 10723 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10724 WMITLV_SET_HDR(&cmd->tlv_header, 10725 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 10726 WMITLV_GET_STRUCT_TLVLEN( 10727 wmi_fwtest_set_param_cmd_fixed_param)); 10728 cmd->param_id = wmi_fwtest->arg; 10729 cmd->param_value = wmi_fwtest->value; 10730 10731 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 10732 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10733 WMI_FWTEST_CMDID)) { 10734 wmi_err("Failed to send fw test command"); 10735 wmi_buf_free(wmi_buf); 10736 return QDF_STATUS_E_FAILURE; 10737 } 10738 10739 return QDF_STATUS_SUCCESS; 10740 } 10741 10742 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 10743 { 10744 uint16_t len = 0; 10745 10746 if (config == WFA_CONFIG_RXNE) 10747 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 10748 else 10749 len += WMI_TLV_HDR_SIZE; 10750 10751 if (config == WFA_CONFIG_CSA) 10752 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 10753 else 10754 len += WMI_TLV_HDR_SIZE; 10755 10756 if (config == WFA_CONFIG_OCV) 10757 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 10758 else 10759 len += WMI_TLV_HDR_SIZE; 10760 10761 if (config == WFA_CONFIG_SA_QUERY) 10762 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 10763 else 10764 len += WMI_TLV_HDR_SIZE; 10765 10766 return len; 10767 } 10768 10769 /** 10770 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 10771 * @host_frmtype: Host defined OCV frame type 10772 * @ocv_frmtype: Pointer to hold WMI OCV frame type 10773 * 10774 * This function converts and fills host defined OCV frame type into WMI OCV 10775 * frame type. 10776 * 10777 * Return: CDF STATUS 10778 */ 10779 static QDF_STATUS 10780 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 10781 { 10782 switch (host_frmtype) { 10783 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 10784 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 10785 break; 10786 10787 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 10788 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 10789 break; 10790 10791 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 10792 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 10793 break; 10794 10795 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 10796 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 10797 break; 10798 10799 default: 10800 wmi_err("Invalid command type cmd %d", host_frmtype); 10801 return QDF_STATUS_E_FAILURE; 10802 } 10803 10804 return QDF_STATUS_SUCCESS; 10805 } 10806 10807 /** 10808 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 10809 * @wmi_handle: wmi handle 10810 * @wmi_wfatest: wfa test command 10811 * 10812 * This function sends wfa test command to fw. 10813 * 10814 * Return: CDF STATUS 10815 */ 10816 static 10817 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 10818 struct set_wfatest_params *wmi_wfatest) 10819 { 10820 wmi_wfa_config_cmd_fixed_param *cmd; 10821 wmi_wfa_config_rsnxe *rxne; 10822 wmi_wfa_config_csa *csa; 10823 wmi_wfa_config_ocv *ocv; 10824 wmi_wfa_config_saquery *saquery; 10825 wmi_buf_t wmi_buf; 10826 uint16_t len = sizeof(*cmd); 10827 uint8_t *buf_ptr; 10828 10829 len += wfa_config_param_len(wmi_wfatest->cmd); 10830 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10831 if (!wmi_buf) 10832 return QDF_STATUS_E_NOMEM; 10833 10834 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 10835 WMITLV_SET_HDR(&cmd->tlv_header, 10836 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 10837 WMITLV_GET_STRUCT_TLVLEN( 10838 wmi_wfa_config_cmd_fixed_param)); 10839 10840 cmd->vdev_id = wmi_wfatest->vdev_id; 10841 buf_ptr = (uint8_t *)(cmd + 1); 10842 10843 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 10844 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10845 sizeof(wmi_wfa_config_rsnxe)); 10846 buf_ptr += WMI_TLV_HDR_SIZE; 10847 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 10848 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 10849 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 10850 rxne->rsnxe_param = wmi_wfatest->value; 10851 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 10852 } else { 10853 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10854 buf_ptr += WMI_TLV_HDR_SIZE; 10855 } 10856 10857 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 10858 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10859 sizeof(wmi_wfa_config_csa)); 10860 buf_ptr += WMI_TLV_HDR_SIZE; 10861 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 10862 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 10863 csa = (wmi_wfa_config_csa *)buf_ptr; 10864 csa->ignore_csa = wmi_wfatest->value; 10865 buf_ptr += sizeof(wmi_wfa_config_csa); 10866 } else { 10867 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10868 buf_ptr += WMI_TLV_HDR_SIZE; 10869 } 10870 10871 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 10872 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10873 sizeof(wmi_wfa_config_ocv)); 10874 buf_ptr += WMI_TLV_HDR_SIZE; 10875 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 10876 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 10877 ocv = (wmi_wfa_config_ocv *)buf_ptr; 10878 10879 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 10880 &ocv->frame_types)) 10881 goto error; 10882 10883 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 10884 buf_ptr += sizeof(wmi_wfa_config_ocv); 10885 } else { 10886 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10887 buf_ptr += WMI_TLV_HDR_SIZE; 10888 } 10889 10890 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 10891 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10892 sizeof(wmi_wfa_config_saquery)); 10893 buf_ptr += WMI_TLV_HDR_SIZE; 10894 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 10895 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 10896 10897 saquery = (wmi_wfa_config_saquery *)buf_ptr; 10898 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 10899 } else { 10900 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 10901 buf_ptr += WMI_TLV_HDR_SIZE; 10902 } 10903 10904 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 10905 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10906 WMI_WFA_CONFIG_CMDID)) { 10907 wmi_err("Failed to send wfa test command"); 10908 goto error; 10909 } 10910 10911 return QDF_STATUS_SUCCESS; 10912 10913 error: 10914 wmi_buf_free(wmi_buf); 10915 return QDF_STATUS_E_FAILURE; 10916 } 10917 10918 /** 10919 * send_unit_test_cmd_tlv() - send unit test command to fw. 10920 * @wmi_handle: wmi handle 10921 * @wmi_utest: unit test command 10922 * 10923 * This function send unit test command to fw. 10924 * 10925 * Return: CDF STATUS 10926 */ 10927 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 10928 struct wmi_unit_test_cmd *wmi_utest) 10929 { 10930 wmi_unit_test_cmd_fixed_param *cmd; 10931 wmi_buf_t wmi_buf; 10932 uint8_t *buf_ptr; 10933 int i; 10934 uint16_t len, args_tlv_len; 10935 uint32_t *unit_test_cmd_args; 10936 10937 args_tlv_len = 10938 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 10939 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 10940 10941 wmi_buf = wmi_buf_alloc(wmi_handle, len); 10942 if (!wmi_buf) 10943 return QDF_STATUS_E_NOMEM; 10944 10945 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 10946 buf_ptr = (uint8_t *) cmd; 10947 WMITLV_SET_HDR(&cmd->tlv_header, 10948 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 10949 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 10950 cmd->vdev_id = wmi_utest->vdev_id; 10951 cmd->module_id = wmi_utest->module_id; 10952 cmd->num_args = wmi_utest->num_args; 10953 cmd->diag_token = wmi_utest->diag_token; 10954 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 10955 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10956 (wmi_utest->num_args * sizeof(uint32_t))); 10957 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10958 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 10959 cmd->vdev_id, cmd->module_id, cmd->diag_token); 10960 wmi_debug("%d num of args = ", wmi_utest->num_args); 10961 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 10962 unit_test_cmd_args[i] = wmi_utest->args[i]; 10963 wmi_debug("%d,", wmi_utest->args[i]); 10964 } 10965 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 10966 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 10967 WMI_UNIT_TEST_CMDID)) { 10968 wmi_err("Failed to send unit test command"); 10969 wmi_buf_free(wmi_buf); 10970 return QDF_STATUS_E_FAILURE; 10971 } 10972 10973 return QDF_STATUS_SUCCESS; 10974 } 10975 10976 /** 10977 * send_power_dbg_cmd_tlv() - send power debug commands 10978 * @wmi_handle: wmi handle 10979 * @param: wmi power debug parameter 10980 * 10981 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 10982 * 10983 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 10984 */ 10985 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 10986 struct wmi_power_dbg_params *param) 10987 { 10988 wmi_buf_t buf = NULL; 10989 QDF_STATUS status; 10990 int len, args_tlv_len; 10991 uint8_t *buf_ptr; 10992 uint8_t i; 10993 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 10994 uint32_t *cmd_args; 10995 10996 /* Prepare and send power debug cmd parameters */ 10997 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 10998 len = sizeof(*cmd) + args_tlv_len; 10999 buf = wmi_buf_alloc(wmi_handle, len); 11000 if (!buf) 11001 return QDF_STATUS_E_NOMEM; 11002 11003 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11004 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11005 WMITLV_SET_HDR(&cmd->tlv_header, 11006 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11007 WMITLV_GET_STRUCT_TLVLEN 11008 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11009 11010 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11011 wmi_handle, 11012 param->pdev_id); 11013 cmd->module_id = param->module_id; 11014 cmd->num_args = param->num_args; 11015 buf_ptr += sizeof(*cmd); 11016 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11017 (param->num_args * sizeof(uint32_t))); 11018 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11019 wmi_debug("%d num of args = ", param->num_args); 11020 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11021 cmd_args[i] = param->args[i]; 11022 wmi_debug("%d,", param->args[i]); 11023 } 11024 11025 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11026 status = wmi_unified_cmd_send(wmi_handle, buf, 11027 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11028 if (QDF_IS_STATUS_ERROR(status)) { 11029 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11030 status); 11031 goto error; 11032 } 11033 11034 return QDF_STATUS_SUCCESS; 11035 error: 11036 wmi_buf_free(buf); 11037 11038 return status; 11039 } 11040 11041 /** 11042 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11043 * @wmi_handle: wmi handle 11044 * @pdev_id: pdev id 11045 * 11046 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11047 * 11048 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11049 */ 11050 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11051 uint32_t pdev_id) 11052 { 11053 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11054 wmi_buf_t buf; 11055 uint16_t len; 11056 QDF_STATUS ret; 11057 11058 len = sizeof(*cmd); 11059 buf = wmi_buf_alloc(wmi_handle, len); 11060 11061 wmi_debug("pdev_id=%d", pdev_id); 11062 11063 if (!buf) 11064 return QDF_STATUS_E_NOMEM; 11065 11066 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11067 wmi_buf_data(buf); 11068 11069 WMITLV_SET_HDR(&cmd->tlv_header, 11070 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11071 WMITLV_GET_STRUCT_TLVLEN( 11072 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11073 11074 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11075 wmi_handle, 11076 pdev_id); 11077 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11078 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11079 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11080 if (QDF_IS_STATUS_ERROR(ret)) { 11081 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11082 ret, pdev_id); 11083 wmi_buf_free(buf); 11084 return QDF_STATUS_E_FAILURE; 11085 } 11086 11087 return QDF_STATUS_SUCCESS; 11088 } 11089 11090 /** 11091 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11092 * @wmi_handle: wmi handle 11093 * @pdev_id: pdev id 11094 * 11095 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11096 * 11097 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11098 */ 11099 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11100 uint32_t pdev_id) 11101 { 11102 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11103 wmi_buf_t buf; 11104 uint16_t len; 11105 QDF_STATUS ret; 11106 11107 len = sizeof(*cmd); 11108 buf = wmi_buf_alloc(wmi_handle, len); 11109 11110 wmi_debug("pdev_id=%d", pdev_id); 11111 11112 if (!buf) 11113 return QDF_STATUS_E_NOMEM; 11114 11115 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11116 wmi_buf_data(buf); 11117 11118 WMITLV_SET_HDR(&cmd->tlv_header, 11119 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11120 WMITLV_GET_STRUCT_TLVLEN( 11121 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11122 11123 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11124 wmi_handle, 11125 pdev_id); 11126 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11127 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11128 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11129 if (QDF_IS_STATUS_ERROR(ret)) { 11130 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11131 ret, pdev_id); 11132 wmi_buf_free(buf); 11133 return QDF_STATUS_E_FAILURE; 11134 } 11135 11136 return QDF_STATUS_SUCCESS; 11137 } 11138 11139 #ifdef QCA_SUPPORT_AGILE_DFS 11140 static 11141 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11142 struct vdev_adfs_ch_cfg_params *param) 11143 { 11144 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11145 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11146 wmi_buf_t buf; 11147 QDF_STATUS ret; 11148 uint16_t len; 11149 11150 len = sizeof(*cmd); 11151 buf = wmi_buf_alloc(wmi_handle, len); 11152 11153 if (!buf) { 11154 wmi_err("wmi_buf_alloc failed"); 11155 return QDF_STATUS_E_NOMEM; 11156 } 11157 11158 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 11159 wmi_buf_data(buf); 11160 11161 WMITLV_SET_HDR(&cmd->tlv_header, 11162 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 11163 WMITLV_GET_STRUCT_TLVLEN 11164 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 11165 11166 cmd->vdev_id = param->vdev_id; 11167 cmd->ocac_mode = param->ocac_mode; 11168 cmd->center_freq1 = param->center_freq1; 11169 cmd->center_freq2 = param->center_freq2; 11170 cmd->chan_freq = param->chan_freq; 11171 cmd->chan_width = param->chan_width; 11172 cmd->min_duration_ms = param->min_duration_ms; 11173 cmd->max_duration_ms = param->max_duration_ms; 11174 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 11175 cmd->vdev_id, cmd->ocac_mode, 11176 cmd->center_freq); 11177 11178 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 11179 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11180 WMI_VDEV_ADFS_CH_CFG_CMDID); 11181 11182 if (QDF_IS_STATUS_ERROR(ret)) { 11183 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11184 wmi_buf_free(buf); 11185 return QDF_STATUS_E_FAILURE; 11186 } 11187 11188 return QDF_STATUS_SUCCESS; 11189 } 11190 11191 static 11192 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 11193 struct vdev_adfs_abort_params *param) 11194 { 11195 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 11196 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 11197 wmi_buf_t buf; 11198 QDF_STATUS ret; 11199 uint16_t len; 11200 11201 len = sizeof(*cmd); 11202 buf = wmi_buf_alloc(wmi_handle, len); 11203 11204 if (!buf) { 11205 wmi_err("wmi_buf_alloc failed"); 11206 return QDF_STATUS_E_NOMEM; 11207 } 11208 11209 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 11210 wmi_buf_data(buf); 11211 11212 WMITLV_SET_HDR 11213 (&cmd->tlv_header, 11214 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 11215 WMITLV_GET_STRUCT_TLVLEN 11216 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 11217 11218 cmd->vdev_id = param->vdev_id; 11219 11220 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 11221 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11222 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 11223 11224 if (QDF_IS_STATUS_ERROR(ret)) { 11225 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11226 wmi_buf_free(buf); 11227 return QDF_STATUS_E_FAILURE; 11228 } 11229 11230 return QDF_STATUS_SUCCESS; 11231 } 11232 #endif 11233 11234 /** 11235 * init_cmd_send_tlv() - send initialization cmd to fw 11236 * @wmi_handle: wmi handle 11237 * @param param: pointer to wmi init param 11238 * 11239 * Return: QDF_STATUS_SUCCESS for success or error code 11240 */ 11241 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 11242 struct wmi_init_cmd_param *param) 11243 { 11244 wmi_buf_t buf; 11245 wmi_init_cmd_fixed_param *cmd; 11246 uint8_t *buf_ptr; 11247 wmi_resource_config *resource_cfg; 11248 wlan_host_memory_chunk *host_mem_chunks; 11249 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 11250 uint16_t idx; 11251 int len; 11252 QDF_STATUS ret; 11253 11254 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 11255 WMI_TLV_HDR_SIZE; 11256 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 11257 11258 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 11259 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 11260 WMI_TLV_HDR_SIZE + 11261 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 11262 11263 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 11264 if (!buf) 11265 return QDF_STATUS_E_FAILURE; 11266 11267 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11268 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 11269 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 11270 11271 host_mem_chunks = (wlan_host_memory_chunk *) 11272 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 11273 + WMI_TLV_HDR_SIZE); 11274 11275 WMITLV_SET_HDR(&cmd->tlv_header, 11276 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 11277 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 11278 wmi_copy_resource_config(resource_cfg, param->res_cfg); 11279 WMITLV_SET_HDR(&resource_cfg->tlv_header, 11280 WMITLV_TAG_STRUC_wmi_resource_config, 11281 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 11282 11283 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 11284 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 11285 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 11286 WMITLV_GET_STRUCT_TLVLEN 11287 (wlan_host_memory_chunk)); 11288 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 11289 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 11290 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 11291 if (is_service_enabled_tlv(wmi_handle, 11292 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 11293 host_mem_chunks[idx].ptr_high = 11294 qdf_get_upper_32_bits( 11295 param->mem_chunks[idx].paddr); 11296 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 11297 "chunk %d len %d requested ,ptr 0x%x ", 11298 idx, host_mem_chunks[idx].size, 11299 host_mem_chunks[idx].ptr); 11300 } 11301 cmd->num_host_mem_chunks = param->num_mem_chunks; 11302 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 11303 11304 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 11305 WMITLV_TAG_ARRAY_STRUC, 11306 (sizeof(wlan_host_memory_chunk) * 11307 param->num_mem_chunks)); 11308 11309 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", 11310 resource_cfg->num_peers, resource_cfg->num_offload_peers, 11311 resource_cfg->num_vdevs, resource_cfg->num_tids, 11312 resource_cfg->num_tdls_conn_table_entries, 11313 resource_cfg->num_tdls_vdevs); 11314 11315 /* Fill hw mode id config */ 11316 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 11317 11318 /* Fill fw_abi_vers */ 11319 copy_fw_abi_version_tlv(wmi_handle, cmd); 11320 11321 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 11322 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 11323 if (QDF_IS_STATUS_ERROR(ret)) { 11324 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 11325 ret); 11326 wmi_buf_free(buf); 11327 } 11328 11329 return ret; 11330 11331 } 11332 11333 /** 11334 * send_addba_send_cmd_tlv() - send addba send command to fw 11335 * @wmi_handle: wmi handle 11336 * @param: pointer to delba send params 11337 * @macaddr: peer mac address 11338 * 11339 * Send WMI_ADDBA_SEND_CMDID command to firmware 11340 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11341 */ 11342 static QDF_STATUS 11343 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 11344 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11345 struct addba_send_params *param) 11346 { 11347 wmi_addba_send_cmd_fixed_param *cmd; 11348 wmi_buf_t buf; 11349 uint16_t len; 11350 QDF_STATUS ret; 11351 11352 len = sizeof(*cmd); 11353 11354 buf = wmi_buf_alloc(wmi_handle, len); 11355 if (!buf) 11356 return QDF_STATUS_E_NOMEM; 11357 11358 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 11359 11360 WMITLV_SET_HDR(&cmd->tlv_header, 11361 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 11362 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 11363 11364 cmd->vdev_id = param->vdev_id; 11365 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11366 cmd->tid = param->tidno; 11367 cmd->buffersize = param->buffersize; 11368 11369 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 11370 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 11371 if (QDF_IS_STATUS_ERROR(ret)) { 11372 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11373 wmi_buf_free(buf); 11374 return QDF_STATUS_E_FAILURE; 11375 } 11376 11377 return QDF_STATUS_SUCCESS; 11378 } 11379 11380 /** 11381 * send_delba_send_cmd_tlv() - send delba send command to fw 11382 * @wmi_handle: wmi handle 11383 * @param: pointer to delba send params 11384 * @macaddr: peer mac address 11385 * 11386 * Send WMI_DELBA_SEND_CMDID command to firmware 11387 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 11388 */ 11389 static QDF_STATUS 11390 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 11391 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11392 struct delba_send_params *param) 11393 { 11394 wmi_delba_send_cmd_fixed_param *cmd; 11395 wmi_buf_t buf; 11396 uint16_t len; 11397 QDF_STATUS ret; 11398 11399 len = sizeof(*cmd); 11400 11401 buf = wmi_buf_alloc(wmi_handle, len); 11402 if (!buf) 11403 return QDF_STATUS_E_NOMEM; 11404 11405 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 11406 11407 WMITLV_SET_HDR(&cmd->tlv_header, 11408 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 11409 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 11410 11411 cmd->vdev_id = param->vdev_id; 11412 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11413 cmd->tid = param->tidno; 11414 cmd->initiator = param->initiator; 11415 cmd->reasoncode = param->reasoncode; 11416 11417 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 11418 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 11419 if (QDF_IS_STATUS_ERROR(ret)) { 11420 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11421 wmi_buf_free(buf); 11422 return QDF_STATUS_E_FAILURE; 11423 } 11424 11425 return QDF_STATUS_SUCCESS; 11426 } 11427 11428 /** 11429 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 11430 * to fw 11431 * @wmi_handle: wmi handle 11432 * @param: pointer to addba clearresp params 11433 * @macaddr: peer mac address 11434 * Return: 0 for success or error code 11435 */ 11436 static QDF_STATUS 11437 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 11438 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 11439 struct addba_clearresponse_params *param) 11440 { 11441 wmi_addba_clear_resp_cmd_fixed_param *cmd; 11442 wmi_buf_t buf; 11443 uint16_t len; 11444 QDF_STATUS ret; 11445 11446 len = sizeof(*cmd); 11447 11448 buf = wmi_buf_alloc(wmi_handle, len); 11449 if (!buf) 11450 return QDF_STATUS_E_FAILURE; 11451 11452 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 11453 11454 WMITLV_SET_HDR(&cmd->tlv_header, 11455 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 11456 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 11457 11458 cmd->vdev_id = param->vdev_id; 11459 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 11460 11461 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 11462 ret = wmi_unified_cmd_send(wmi_handle, 11463 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 11464 if (QDF_IS_STATUS_ERROR(ret)) { 11465 wmi_err("Failed to send cmd to fw, ret=%d", ret); 11466 wmi_buf_free(buf); 11467 return QDF_STATUS_E_FAILURE; 11468 } 11469 11470 return QDF_STATUS_SUCCESS; 11471 } 11472 11473 #ifdef OBSS_PD 11474 /** 11475 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 11476 * def thresh to fw 11477 * @wmi_handle: wmi handle 11478 * @thresh: pointer to obss_spatial_reuse_def_thresh 11479 * 11480 * Return: QDF_STATUS_SUCCESS for success or error code 11481 */ 11482 static 11483 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 11484 wmi_unified_t wmi_handle, 11485 struct wmi_host_obss_spatial_reuse_set_def_thresh 11486 *thresh) 11487 { 11488 wmi_buf_t buf; 11489 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 11490 QDF_STATUS ret; 11491 uint32_t cmd_len; 11492 uint32_t tlv_len; 11493 11494 cmd_len = sizeof(*cmd); 11495 11496 buf = wmi_buf_alloc(wmi_handle, cmd_len); 11497 if (!buf) 11498 return QDF_STATUS_E_NOMEM; 11499 11500 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 11501 wmi_buf_data(buf); 11502 11503 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 11504 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 11505 11506 WMITLV_SET_HDR(&cmd->tlv_header, 11507 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 11508 tlv_len); 11509 11510 cmd->obss_min = thresh->obss_min; 11511 cmd->obss_max = thresh->obss_max; 11512 cmd->vdev_type = thresh->vdev_type; 11513 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 11514 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 11515 if (QDF_IS_STATUS_ERROR(ret)) 11516 wmi_buf_free(buf); 11517 11518 return ret; 11519 } 11520 11521 /** 11522 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 11523 * @wmi_handle: wmi handle 11524 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 11525 * 11526 * Return: QDF_STATUS_SUCCESS for success or error code 11527 */ 11528 static 11529 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 11530 struct wmi_host_obss_spatial_reuse_set_param 11531 *obss_spatial_reuse_param) 11532 { 11533 wmi_buf_t buf; 11534 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 11535 QDF_STATUS ret; 11536 uint32_t len; 11537 11538 len = sizeof(*cmd); 11539 11540 buf = wmi_buf_alloc(wmi_handle, len); 11541 if (!buf) 11542 return QDF_STATUS_E_FAILURE; 11543 11544 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 11545 WMITLV_SET_HDR(&cmd->tlv_header, 11546 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 11547 WMITLV_GET_STRUCT_TLVLEN 11548 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 11549 11550 cmd->enable = obss_spatial_reuse_param->enable; 11551 cmd->obss_min = obss_spatial_reuse_param->obss_min; 11552 cmd->obss_max = obss_spatial_reuse_param->obss_max; 11553 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 11554 11555 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11556 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 11557 11558 if (QDF_IS_STATUS_ERROR(ret)) { 11559 wmi_err( 11560 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 11561 ret); 11562 wmi_buf_free(buf); 11563 } 11564 11565 return ret; 11566 } 11567 11568 /** 11569 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 11570 * to be used by SRG based Spatial Reuse feature to the FW 11571 * @wmi_handle: wmi handle 11572 * @bitmap_0: lower 32 bits in BSS color bitmap 11573 * @bitmap_1: upper 32 bits in BSS color bitmap 11574 * @pdev_id: pdev ID 11575 * 11576 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11577 */ 11578 static QDF_STATUS 11579 send_self_srg_bss_color_bitmap_set_cmd_tlv( 11580 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11581 uint32_t bitmap_1, uint8_t pdev_id) 11582 { 11583 wmi_buf_t buf; 11584 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 11585 QDF_STATUS ret; 11586 uint32_t len; 11587 11588 len = sizeof(*cmd); 11589 11590 buf = wmi_buf_alloc(wmi_handle, len); 11591 if (!buf) 11592 return QDF_STATUS_E_FAILURE; 11593 11594 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 11595 wmi_buf_data(buf); 11596 11597 WMITLV_SET_HDR( 11598 &cmd->tlv_header, 11599 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 11600 WMITLV_GET_STRUCT_TLVLEN 11601 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 11602 11603 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11604 wmi_handle, pdev_id); 11605 cmd->srg_bss_color_bitmap[0] = bitmap_0; 11606 cmd->srg_bss_color_bitmap[1] = bitmap_1; 11607 11608 ret = wmi_unified_cmd_send( 11609 wmi_handle, buf, len, 11610 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 11611 11612 if (QDF_IS_STATUS_ERROR(ret)) { 11613 wmi_err( 11614 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 11615 ret); 11616 wmi_buf_free(buf); 11617 } 11618 11619 return ret; 11620 } 11621 11622 /** 11623 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 11624 * bitmap to be used by SRG based Spatial Reuse feature to the FW 11625 * @wmi_handle: wmi handle 11626 * @bitmap_0: lower 32 bits in partial BSSID bitmap 11627 * @bitmap_1: upper 32 bits in partial BSSID bitmap 11628 * @pdev_id: pdev ID 11629 * 11630 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11631 */ 11632 static QDF_STATUS 11633 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 11634 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11635 uint32_t bitmap_1, uint8_t pdev_id) 11636 { 11637 wmi_buf_t buf; 11638 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 11639 QDF_STATUS ret; 11640 uint32_t len; 11641 11642 len = sizeof(*cmd); 11643 11644 buf = wmi_buf_alloc(wmi_handle, len); 11645 if (!buf) 11646 return QDF_STATUS_E_FAILURE; 11647 11648 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 11649 wmi_buf_data(buf); 11650 11651 WMITLV_SET_HDR( 11652 &cmd->tlv_header, 11653 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 11654 WMITLV_GET_STRUCT_TLVLEN 11655 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 11656 11657 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11658 wmi_handle, pdev_id); 11659 11660 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 11661 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 11662 11663 ret = wmi_unified_cmd_send( 11664 wmi_handle, buf, len, 11665 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 11666 11667 if (QDF_IS_STATUS_ERROR(ret)) { 11668 wmi_err( 11669 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 11670 ret); 11671 wmi_buf_free(buf); 11672 } 11673 11674 return ret; 11675 } 11676 11677 /** 11678 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11679 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11680 * @wmi_handle: wmi handle 11681 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11682 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11683 * @pdev_id: pdev ID 11684 * 11685 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11686 */ 11687 static QDF_STATUS 11688 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 11689 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11690 uint32_t bitmap_1, uint8_t pdev_id) 11691 { 11692 wmi_buf_t buf; 11693 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11694 QDF_STATUS ret; 11695 uint32_t len; 11696 11697 len = sizeof(*cmd); 11698 11699 buf = wmi_buf_alloc(wmi_handle, len); 11700 if (!buf) 11701 return QDF_STATUS_E_FAILURE; 11702 11703 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11704 wmi_buf_data(buf); 11705 11706 WMITLV_SET_HDR( 11707 &cmd->tlv_header, 11708 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 11709 WMITLV_GET_STRUCT_TLVLEN 11710 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11711 11712 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11713 wmi_handle, pdev_id); 11714 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 11715 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 11716 11717 ret = wmi_unified_cmd_send( 11718 wmi_handle, buf, len, 11719 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11720 11721 if (QDF_IS_STATUS_ERROR(ret)) { 11722 wmi_err( 11723 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11724 ret); 11725 wmi_buf_free(buf); 11726 } 11727 11728 return ret; 11729 } 11730 11731 /** 11732 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11733 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 11734 * @wmi_handle: wmi handle 11735 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11736 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11737 * @pdev_id: pdev ID 11738 * 11739 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11740 */ 11741 static QDF_STATUS 11742 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 11743 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11744 uint32_t bitmap_1, uint8_t pdev_id) 11745 { 11746 wmi_buf_t buf; 11747 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11748 QDF_STATUS ret; 11749 uint32_t len; 11750 11751 len = sizeof(*cmd); 11752 11753 buf = wmi_buf_alloc(wmi_handle, len); 11754 if (!buf) 11755 return QDF_STATUS_E_FAILURE; 11756 11757 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11758 wmi_buf_data(buf); 11759 11760 WMITLV_SET_HDR( 11761 &cmd->tlv_header, 11762 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11763 WMITLV_GET_STRUCT_TLVLEN 11764 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11765 11766 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11767 wmi_handle, pdev_id); 11768 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 11769 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 11770 11771 ret = wmi_unified_cmd_send( 11772 wmi_handle, buf, len, 11773 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11774 11775 if (QDF_IS_STATUS_ERROR(ret)) { 11776 wmi_err( 11777 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11778 ret); 11779 wmi_buf_free(buf); 11780 } 11781 11782 return ret; 11783 } 11784 11785 /** 11786 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 11787 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11788 * @wmi_handle: wmi handle 11789 * @bitmap_0: lower 32 bits in BSS color enable bitmap 11790 * @bitmap_1: upper 32 bits in BSS color enable bitmap 11791 * @pdev_id: pdev ID 11792 * 11793 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11794 */ 11795 static QDF_STATUS 11796 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 11797 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11798 uint32_t bitmap_1, uint8_t pdev_id) 11799 { 11800 wmi_buf_t buf; 11801 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 11802 QDF_STATUS ret; 11803 uint32_t len; 11804 11805 len = sizeof(*cmd); 11806 11807 buf = wmi_buf_alloc(wmi_handle, len); 11808 if (!buf) 11809 return QDF_STATUS_E_FAILURE; 11810 11811 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 11812 wmi_buf_data(buf); 11813 11814 WMITLV_SET_HDR( 11815 &cmd->tlv_header, 11816 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 11817 WMITLV_GET_STRUCT_TLVLEN 11818 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 11819 11820 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11821 wmi_handle, pdev_id); 11822 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 11823 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 11824 11825 ret = wmi_unified_cmd_send( 11826 wmi_handle, buf, len, 11827 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 11828 11829 if (QDF_IS_STATUS_ERROR(ret)) { 11830 wmi_err( 11831 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 11832 ret); 11833 wmi_buf_free(buf); 11834 } 11835 11836 return ret; 11837 } 11838 11839 /** 11840 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 11841 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 11842 * @wmi_handle: wmi handle 11843 * @bitmap_0: lower 32 bits in BSSID enable bitmap 11844 * @bitmap_1: upper 32 bits in BSSID enable bitmap 11845 * @pdev_id: pdev ID 11846 * 11847 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 11848 */ 11849 static QDF_STATUS 11850 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 11851 wmi_unified_t wmi_handle, uint32_t bitmap_0, 11852 uint32_t bitmap_1, uint8_t pdev_id) 11853 { 11854 wmi_buf_t buf; 11855 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 11856 QDF_STATUS ret; 11857 uint32_t len; 11858 11859 len = sizeof(*cmd); 11860 11861 buf = wmi_buf_alloc(wmi_handle, len); 11862 if (!buf) 11863 return QDF_STATUS_E_FAILURE; 11864 11865 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 11866 wmi_buf_data(buf); 11867 11868 WMITLV_SET_HDR( 11869 &cmd->tlv_header, 11870 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 11871 WMITLV_GET_STRUCT_TLVLEN 11872 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 11873 11874 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11875 wmi_handle, pdev_id); 11876 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 11877 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 11878 11879 ret = wmi_unified_cmd_send( 11880 wmi_handle, buf, len, 11881 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 11882 11883 if (QDF_IS_STATUS_ERROR(ret)) { 11884 wmi_err( 11885 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 11886 ret); 11887 wmi_buf_free(buf); 11888 } 11889 11890 return ret; 11891 } 11892 #endif 11893 11894 static 11895 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 11896 struct wmi_host_injector_frame_params *inject_config_params) 11897 { 11898 wmi_buf_t buf; 11899 wmi_frame_inject_cmd_fixed_param *cmd; 11900 QDF_STATUS ret; 11901 uint32_t len; 11902 11903 len = sizeof(*cmd); 11904 11905 buf = wmi_buf_alloc(wmi_handle, len); 11906 if (!buf) 11907 return QDF_STATUS_E_NOMEM; 11908 11909 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 11910 WMITLV_SET_HDR(&cmd->tlv_header, 11911 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 11912 WMITLV_GET_STRUCT_TLVLEN 11913 (wmi_frame_inject_cmd_fixed_param)); 11914 11915 cmd->vdev_id = inject_config_params->vdev_id; 11916 cmd->enable = inject_config_params->enable; 11917 cmd->frame_type = inject_config_params->frame_type; 11918 cmd->frame_inject_period = inject_config_params->frame_inject_period; 11919 cmd->fc_duration = inject_config_params->frame_duration; 11920 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 11921 &cmd->frame_addr1); 11922 11923 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11924 WMI_PDEV_FRAME_INJECT_CMDID); 11925 11926 if (QDF_IS_STATUS_ERROR(ret)) { 11927 wmi_err( 11928 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 11929 ret); 11930 wmi_buf_free(buf); 11931 } 11932 11933 return ret; 11934 } 11935 #ifdef QCA_SUPPORT_CP_STATS 11936 /** 11937 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 11938 * @wmi_handle: wma handle 11939 * @evt_buf: event buffer 11940 * @out_buff: buffer to populated after stats extraction 11941 * 11942 * Return: status of operation 11943 */ 11944 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 11945 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 11946 { 11947 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11948 wmi_congestion_stats *congestion_stats; 11949 11950 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 11951 congestion_stats = param_buf->congestion_stats; 11952 if (!congestion_stats) 11953 return QDF_STATUS_E_INVAL; 11954 11955 out_buff->vdev_id = congestion_stats->vdev_id; 11956 out_buff->congestion = congestion_stats->congestion; 11957 11958 wmi_debug("cca stats event processed"); 11959 return QDF_STATUS_SUCCESS; 11960 } 11961 #endif /* QCA_SUPPORT_CP_STATS */ 11962 11963 /** 11964 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 11965 * event 11966 * @wmi_handle: wmi handle 11967 * @param evt_buf: pointer to event buffer 11968 * @param param: Pointer to hold peer ctl data 11969 * 11970 * Return: QDF_STATUS_SUCCESS for success or error code 11971 */ 11972 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 11973 wmi_unified_t wmi_handle, 11974 void *evt_buf, 11975 struct wmi_host_pdev_ctl_failsafe_event *param) 11976 { 11977 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 11978 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 11979 11980 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 11981 if (!param_buf) { 11982 wmi_err("Invalid ctl_failsafe event buffer"); 11983 return QDF_STATUS_E_INVAL; 11984 } 11985 11986 fix_param = param_buf->fixed_param; 11987 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 11988 11989 return QDF_STATUS_SUCCESS; 11990 } 11991 11992 /** 11993 * save_service_bitmap_tlv() - save service bitmap 11994 * @wmi_handle: wmi handle 11995 * @param evt_buf: pointer to event buffer 11996 * @param bitmap_buf: bitmap buffer, for converged legacy support 11997 * 11998 * Return: QDF_STATUS 11999 */ 12000 static 12001 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12002 void *bitmap_buf) 12003 { 12004 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12005 struct wmi_soc *soc = wmi_handle->soc; 12006 12007 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12008 12009 /* If it is already allocated, use that buffer. This can happen 12010 * during target stop/start scenarios where host allocation is skipped. 12011 */ 12012 if (!soc->wmi_service_bitmap) { 12013 soc->wmi_service_bitmap = 12014 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12015 if (!soc->wmi_service_bitmap) 12016 return QDF_STATUS_E_NOMEM; 12017 } 12018 12019 qdf_mem_copy(soc->wmi_service_bitmap, 12020 param_buf->wmi_service_bitmap, 12021 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12022 12023 if (bitmap_buf) 12024 qdf_mem_copy(bitmap_buf, 12025 param_buf->wmi_service_bitmap, 12026 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12027 12028 return QDF_STATUS_SUCCESS; 12029 } 12030 12031 /** 12032 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12033 * @wmi_handle: wmi handle 12034 * @param evt_buf: pointer to event buffer 12035 * @param bitmap_buf: bitmap buffer, for converged legacy support 12036 * 12037 * Return: QDF_STATUS 12038 */ 12039 static 12040 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12041 void *bitmap_buf) 12042 { 12043 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12044 wmi_service_available_event_fixed_param *ev; 12045 struct wmi_soc *soc = wmi_handle->soc; 12046 uint32_t i = 0; 12047 12048 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12049 12050 ev = param_buf->fixed_param; 12051 12052 /* If it is already allocated, use that buffer. This can happen 12053 * during target stop/start scenarios where host allocation is skipped. 12054 */ 12055 if (!soc->wmi_ext_service_bitmap) { 12056 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12057 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12058 if (!soc->wmi_ext_service_bitmap) 12059 return QDF_STATUS_E_NOMEM; 12060 } 12061 12062 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12063 ev->wmi_service_segment_bitmap, 12064 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12065 12066 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12067 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12068 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12069 12070 if (bitmap_buf) 12071 qdf_mem_copy(bitmap_buf, 12072 soc->wmi_ext_service_bitmap, 12073 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12074 12075 if (!param_buf->wmi_service_ext_bitmap) { 12076 wmi_debug("wmi_service_ext_bitmap not available"); 12077 return QDF_STATUS_SUCCESS; 12078 } 12079 12080 if (!soc->wmi_ext2_service_bitmap) { 12081 soc->wmi_ext2_service_bitmap = 12082 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12083 sizeof(uint32_t)); 12084 if (!soc->wmi_ext2_service_bitmap) 12085 return QDF_STATUS_E_NOMEM; 12086 } 12087 12088 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12089 param_buf->wmi_service_ext_bitmap, 12090 (param_buf->num_wmi_service_ext_bitmap * 12091 sizeof(uint32_t))); 12092 12093 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12094 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12095 i, soc->wmi_ext2_service_bitmap[i]); 12096 } 12097 12098 return QDF_STATUS_SUCCESS; 12099 } 12100 12101 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12102 struct wlan_psoc_target_capability_info *cap) 12103 { 12104 /* except LDPC all flags are common between legacy and here 12105 * also IBFEER is not defined for TLV 12106 */ 12107 cap->ht_cap_info |= ev_target_cap & ( 12108 WMI_HT_CAP_ENABLED 12109 | WMI_HT_CAP_HT20_SGI 12110 | WMI_HT_CAP_DYNAMIC_SMPS 12111 | WMI_HT_CAP_TX_STBC 12112 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12113 | WMI_HT_CAP_RX_STBC 12114 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12115 | WMI_HT_CAP_LDPC 12116 | WMI_HT_CAP_L_SIG_TXOP_PROT 12117 | WMI_HT_CAP_MPDU_DENSITY 12118 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12119 | WMI_HT_CAP_HT40_SGI); 12120 if (ev_target_cap & WMI_HT_CAP_LDPC) 12121 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12122 WMI_HOST_HT_CAP_TX_LDPC; 12123 } 12124 /** 12125 * extract_service_ready_tlv() - extract service ready event 12126 * @wmi_handle: wmi handle 12127 * @param evt_buf: pointer to received event buffer 12128 * @param cap: pointer to hold target capability information extracted from even 12129 * 12130 * Return: QDF_STATUS_SUCCESS for success or error code 12131 */ 12132 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12133 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12134 { 12135 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12136 wmi_service_ready_event_fixed_param *ev; 12137 12138 12139 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12140 12141 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12142 if (!ev) { 12143 qdf_print("%s: wmi_buf_alloc failed", __func__); 12144 return QDF_STATUS_E_FAILURE; 12145 } 12146 12147 cap->phy_capability = ev->phy_capability; 12148 cap->max_frag_entry = ev->max_frag_entry; 12149 cap->num_rf_chains = ev->num_rf_chains; 12150 copy_ht_cap_info(ev->ht_cap_info, cap); 12151 cap->vht_cap_info = ev->vht_cap_info; 12152 cap->vht_supp_mcs = ev->vht_supp_mcs; 12153 cap->hw_min_tx_power = ev->hw_min_tx_power; 12154 cap->hw_max_tx_power = ev->hw_max_tx_power; 12155 cap->sys_cap_info = ev->sys_cap_info; 12156 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 12157 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 12158 cap->max_num_scan_channels = ev->max_num_scan_channels; 12159 cap->max_supported_macs = ev->max_supported_macs; 12160 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 12161 cap->txrx_chainmask = ev->txrx_chainmask; 12162 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 12163 cap->num_msdu_desc = ev->num_msdu_desc; 12164 cap->fw_version = ev->fw_build_vers; 12165 /* fw_version_1 is not available in TLV. */ 12166 cap->fw_version_1 = 0; 12167 12168 return QDF_STATUS_SUCCESS; 12169 } 12170 12171 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 12172 * to host internal HOST_REGDMN_MODE values. 12173 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 12174 * host currently. Add this in the future if required. 12175 * 11AX (Phase II) : 11ax related values are not currently 12176 * advertised separately by FW. As part of phase II regulatory bring-up, 12177 * finalize the advertisement mechanism. 12178 * @target_wireless_mode: target wireless mode received in message 12179 * 12180 * Return: returns the host internal wireless mode. 12181 */ 12182 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 12183 { 12184 12185 uint32_t wireless_modes = 0; 12186 12187 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 12188 12189 if (target_wireless_mode & REGDMN_MODE_11A) 12190 wireless_modes |= HOST_REGDMN_MODE_11A; 12191 12192 if (target_wireless_mode & REGDMN_MODE_TURBO) 12193 wireless_modes |= HOST_REGDMN_MODE_TURBO; 12194 12195 if (target_wireless_mode & REGDMN_MODE_11B) 12196 wireless_modes |= HOST_REGDMN_MODE_11B; 12197 12198 if (target_wireless_mode & REGDMN_MODE_PUREG) 12199 wireless_modes |= HOST_REGDMN_MODE_PUREG; 12200 12201 if (target_wireless_mode & REGDMN_MODE_11G) 12202 wireless_modes |= HOST_REGDMN_MODE_11G; 12203 12204 if (target_wireless_mode & REGDMN_MODE_108G) 12205 wireless_modes |= HOST_REGDMN_MODE_108G; 12206 12207 if (target_wireless_mode & REGDMN_MODE_108A) 12208 wireless_modes |= HOST_REGDMN_MODE_108A; 12209 12210 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 12211 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 12212 12213 if (target_wireless_mode & REGDMN_MODE_XR) 12214 wireless_modes |= HOST_REGDMN_MODE_XR; 12215 12216 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 12217 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 12218 12219 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 12220 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 12221 12222 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 12223 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 12224 12225 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 12226 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 12227 12228 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 12229 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 12230 12231 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 12232 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 12233 12234 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 12235 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 12236 12237 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 12238 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 12239 12240 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 12241 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 12242 12243 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 12244 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 12245 12246 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 12247 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 12248 12249 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 12250 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 12251 12252 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 12253 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 12254 12255 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 12256 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 12257 12258 return wireless_modes; 12259 } 12260 12261 /** 12262 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 12263 * to regulatory flags. 12264 * @target_phybitmap: target phybitmap. 12265 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 12266 * phybitmap. 12267 * 12268 * Return: None 12269 */ 12270 12271 #ifdef WLAN_FEATURE_11BE 12272 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12273 uint32_t *phybitmap) 12274 { 12275 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 12276 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 12277 } 12278 #else 12279 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 12280 uint32_t *phybitmap) 12281 { 12282 } 12283 #endif 12284 12285 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 12286 * target to host internal REGULATORY_PHYMODE values. 12287 * 12288 * @target_target_phybitmap: target phybitmap received in the message. 12289 * 12290 * Return: returns the host internal REGULATORY_PHYMODE. 12291 */ 12292 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 12293 { 12294 uint32_t phybitmap = 0; 12295 12296 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 12297 12298 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 12299 phybitmap |= REGULATORY_PHYMODE_NO11A; 12300 12301 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 12302 phybitmap |= REGULATORY_PHYMODE_NO11B; 12303 12304 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 12305 phybitmap |= REGULATORY_PHYMODE_NO11G; 12306 12307 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 12308 phybitmap |= REGULATORY_CHAN_NO11N; 12309 12310 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 12311 phybitmap |= REGULATORY_PHYMODE_NO11AC; 12312 12313 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 12314 phybitmap |= REGULATORY_PHYMODE_NO11AX; 12315 12316 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 12317 12318 return phybitmap; 12319 } 12320 12321 /** 12322 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 12323 * advertised by the target to wireless mode ext flags. 12324 * @target_wireless_modes_ext: Target wireless mode 12325 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 12326 * 12327 * Return: None 12328 */ 12329 #ifdef WLAN_FEATURE_11BE 12330 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12331 uint64_t *wireless_modes_ext) 12332 { 12333 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 12334 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 12335 12336 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 12337 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 12338 12339 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 12340 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 12341 12342 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 12343 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 12344 12345 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 12346 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 12347 12348 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 12349 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 12350 12351 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 12352 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 12353 12354 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 12355 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 12356 12357 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 12358 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 12359 } 12360 #else 12361 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 12362 uint64_t *wireless_modes_ext) 12363 { 12364 } 12365 #endif 12366 12367 static inline uint64_t convert_wireless_modes_ext_tlv( 12368 uint32_t target_wireless_modes_ext) 12369 { 12370 uint64_t wireless_modes_ext = 0; 12371 12372 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 12373 12374 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 12375 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 12376 12377 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 12378 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 12379 12380 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 12381 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 12382 12383 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 12384 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 12385 12386 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 12387 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 12388 12389 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 12390 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 12391 12392 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 12393 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 12394 12395 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 12396 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 12397 12398 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 12399 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 12400 12401 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 12402 &wireless_modes_ext); 12403 12404 return wireless_modes_ext; 12405 } 12406 12407 /** 12408 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 12409 * @wmi_handle: wmi handle 12410 * @param evt_buf: Pointer to event buffer 12411 * @param cap: pointer to hold HAL reg capabilities 12412 * 12413 * Return: QDF_STATUS_SUCCESS for success or error code 12414 */ 12415 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 12416 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 12417 { 12418 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12419 12420 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12421 if (!param_buf || !param_buf->hal_reg_capabilities) { 12422 wmi_err("Invalid arguments"); 12423 return QDF_STATUS_E_FAILURE; 12424 } 12425 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 12426 sizeof(uint32_t)), 12427 sizeof(struct wlan_psoc_hal_reg_capability)); 12428 12429 cap->wireless_modes = convert_wireless_modes_tlv( 12430 param_buf->hal_reg_capabilities->wireless_modes); 12431 12432 return QDF_STATUS_SUCCESS; 12433 } 12434 12435 /** 12436 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 12437 * @wmi_handle: wmi handle 12438 * @param evt_buf: Pointer to event buffer 12439 * @param cap: pointer to hold HAL reg capabilities 12440 * 12441 * Return: QDF_STATUS_SUCCESS for success or error code 12442 */ 12443 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 12444 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 12445 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 12446 { 12447 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12448 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 12449 12450 if (!evt_buf) { 12451 wmi_err("null evt_buf"); 12452 return QDF_STATUS_E_INVAL; 12453 } 12454 12455 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 12456 12457 if (!param_buf->num_hal_reg_caps) 12458 return QDF_STATUS_SUCCESS; 12459 12460 if (phy_idx >= param_buf->num_hal_reg_caps) 12461 return QDF_STATUS_E_INVAL; 12462 12463 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 12464 12465 param->phy_id = reg_caps->phy_id; 12466 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 12467 reg_caps->wireless_modes_ext); 12468 12469 return QDF_STATUS_SUCCESS; 12470 } 12471 12472 /** 12473 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 12474 * @wmi_handle: wmi handle 12475 * @evt_buf: pointer to event buffer 12476 * 12477 * Return: Number of entries requested 12478 */ 12479 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 12480 void *evt_buf) 12481 { 12482 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12483 wmi_service_ready_event_fixed_param *ev; 12484 12485 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12486 12487 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12488 if (!ev) { 12489 qdf_print("%s: wmi_buf_alloc failed", __func__); 12490 return 0; 12491 } 12492 12493 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 12494 wmi_err("Invalid num_mem_reqs %d:%d", 12495 ev->num_mem_reqs, param_buf->num_mem_reqs); 12496 return 0; 12497 } 12498 12499 return ev->num_mem_reqs; 12500 } 12501 12502 /** 12503 * extract_host_mem_req_tlv() - Extract host memory required from 12504 * service ready event 12505 * @wmi_handle: wmi handle 12506 * @evt_buf: pointer to event buffer 12507 * @mem_reqs: pointer to host memory request structure 12508 * @num_active_peers: number of active peers for peer cache 12509 * @num_peers: number of peers 12510 * @fw_prio: FW priority 12511 * @idx: index for memory request 12512 * 12513 * Return: Host memory request parameters requested by target 12514 */ 12515 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 12516 void *evt_buf, 12517 host_mem_req *mem_reqs, 12518 uint32_t num_active_peers, 12519 uint32_t num_peers, 12520 enum wmi_fw_mem_prio fw_prio, 12521 uint16_t idx) 12522 { 12523 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12524 12525 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 12526 12527 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 12528 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 12529 mem_reqs->num_unit_info = 12530 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 12531 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 12532 mem_reqs->tgt_num_units = 0; 12533 12534 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 12535 (mem_reqs->num_unit_info & 12536 REQ_TO_HOST_FOR_CONT_MEMORY)) || 12537 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 12538 (!(mem_reqs->num_unit_info & 12539 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 12540 /* First allocate the memory that requires contiguous memory */ 12541 mem_reqs->tgt_num_units = mem_reqs->num_units; 12542 if (mem_reqs->num_unit_info) { 12543 if (mem_reqs->num_unit_info & 12544 NUM_UNITS_IS_NUM_PEERS) { 12545 /* 12546 * number of units allocated is equal to number 12547 * of peers, 1 extra for self peer on target. 12548 * this needs to be fixed, host and target can 12549 * get out of sync 12550 */ 12551 mem_reqs->tgt_num_units = num_peers + 1; 12552 } 12553 if (mem_reqs->num_unit_info & 12554 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 12555 /* 12556 * Requesting allocation of memory using 12557 * num_active_peers in qcache. if qcache is 12558 * disabled in host, then it should allocate 12559 * memory for num_peers instead of 12560 * num_active_peers. 12561 */ 12562 if (num_active_peers) 12563 mem_reqs->tgt_num_units = 12564 num_active_peers + 1; 12565 else 12566 mem_reqs->tgt_num_units = 12567 num_peers + 1; 12568 } 12569 } 12570 12571 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 12572 "unit size %d actual units %d", 12573 idx, mem_reqs->req_id, 12574 mem_reqs->num_units, 12575 mem_reqs->num_unit_info, 12576 mem_reqs->unit_size, 12577 mem_reqs->tgt_num_units); 12578 } 12579 12580 return QDF_STATUS_SUCCESS; 12581 } 12582 12583 /** 12584 * save_fw_version_in_service_ready_tlv() - Save fw version in service 12585 * ready function 12586 * @wmi_handle: wmi handle 12587 * @param evt_buf: pointer to event buffer 12588 * 12589 * Return: QDF_STATUS_SUCCESS for success or error code 12590 */ 12591 static QDF_STATUS 12592 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 12593 { 12594 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12595 wmi_service_ready_event_fixed_param *ev; 12596 12597 12598 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12599 12600 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12601 if (!ev) { 12602 qdf_print("%s: wmi_buf_alloc failed", __func__); 12603 return QDF_STATUS_E_FAILURE; 12604 } 12605 12606 /*Save fw version from service ready message */ 12607 /*This will be used while sending INIT message */ 12608 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 12609 sizeof(wmi_handle->fw_abi_version)); 12610 12611 return QDF_STATUS_SUCCESS; 12612 } 12613 12614 /** 12615 * ready_extract_init_status_tlv() - Extract init status from ready event 12616 * @wmi_handle: wmi handle 12617 * @param evt_buf: Pointer to event buffer 12618 * 12619 * Return: ready status 12620 */ 12621 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 12622 void *evt_buf) 12623 { 12624 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12625 wmi_ready_event_fixed_param *ev = NULL; 12626 12627 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12628 ev = param_buf->fixed_param; 12629 12630 qdf_print("%s:%d", __func__, ev->status); 12631 12632 return ev->status; 12633 } 12634 12635 /** 12636 * ready_extract_mac_addr_tlv() - extract mac address from ready event 12637 * @wmi_handle: wmi handle 12638 * @param evt_buf: pointer to event buffer 12639 * @param macaddr: Pointer to hold MAC address 12640 * 12641 * Return: QDF_STATUS_SUCCESS for success or error code 12642 */ 12643 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 12644 void *evt_buf, uint8_t *macaddr) 12645 { 12646 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12647 wmi_ready_event_fixed_param *ev = NULL; 12648 12649 12650 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12651 ev = param_buf->fixed_param; 12652 12653 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 12654 12655 return QDF_STATUS_SUCCESS; 12656 } 12657 12658 /** 12659 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 12660 * @wmi_handle: wmi handle 12661 * @param evt_buf: pointer to event buffer 12662 * @param macaddr: Pointer to hold number of MAC addresses 12663 * 12664 * Return: Pointer to addr list 12665 */ 12666 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 12667 void *evt_buf, uint8_t *num_mac) 12668 { 12669 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12670 wmi_ready_event_fixed_param *ev = NULL; 12671 12672 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12673 ev = param_buf->fixed_param; 12674 12675 *num_mac = ev->num_extra_mac_addr; 12676 12677 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 12678 } 12679 12680 /** 12681 * extract_ready_params_tlv() - Extract data from ready event apart from 12682 * status, macaddr and version. 12683 * @wmi_handle: Pointer to WMI handle. 12684 * @evt_buf: Pointer to Ready event buffer. 12685 * @ev_param: Pointer to host defined struct to copy the data from event. 12686 * 12687 * Return: QDF_STATUS_SUCCESS on success. 12688 */ 12689 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 12690 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 12691 { 12692 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 12693 wmi_ready_event_fixed_param *ev = NULL; 12694 12695 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 12696 ev = param_buf->fixed_param; 12697 12698 ev_param->status = ev->status; 12699 ev_param->num_dscp_table = ev->num_dscp_table; 12700 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 12701 ev_param->num_total_peer = ev->num_total_peers; 12702 ev_param->num_extra_peer = ev->num_extra_peers; 12703 /* Agile_capability in ready event is supported in TLV target, 12704 * as per aDFS FR 12705 */ 12706 ev_param->max_ast_index = ev->max_ast_index; 12707 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 12708 ev_param->agile_capability = 1; 12709 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 12710 12711 return QDF_STATUS_SUCCESS; 12712 } 12713 12714 /** 12715 * extract_dbglog_data_len_tlv() - extract debuglog data length 12716 * @wmi_handle: wmi handle 12717 * @param evt_buf: pointer to event buffer 12718 * 12719 * Return: length 12720 */ 12721 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 12722 void *evt_buf, uint32_t *len) 12723 { 12724 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 12725 12726 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 12727 12728 *len = param_buf->num_bufp; 12729 12730 return param_buf->bufp; 12731 } 12732 12733 12734 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 12735 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 12736 #else 12737 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 12738 ((_status) & WMI_RXERR_DECRYPT) 12739 #endif 12740 12741 /** 12742 * extract_mgmt_rx_params_tlv() - extract management rx params from event 12743 * @wmi_handle: wmi handle 12744 * @param evt_buf: pointer to event buffer 12745 * @param hdr: Pointer to hold header 12746 * @param bufp: Pointer to hold pointer to rx param buffer 12747 * 12748 * Return: QDF_STATUS_SUCCESS for success or error code 12749 */ 12750 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 12751 void *evt_buf, struct mgmt_rx_event_params *hdr, 12752 uint8_t **bufp) 12753 { 12754 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 12755 wmi_mgmt_rx_hdr *ev_hdr = NULL; 12756 int i; 12757 12758 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12759 if (!param_tlvs) { 12760 wmi_err("Get NULL point message from FW"); 12761 return QDF_STATUS_E_INVAL; 12762 } 12763 12764 ev_hdr = param_tlvs->hdr; 12765 if (!hdr) { 12766 wmi_err("Rx event is NULL"); 12767 return QDF_STATUS_E_INVAL; 12768 } 12769 12770 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 12771 wmi_err("RX mgmt frame decrypt error, discard it"); 12772 return QDF_STATUS_E_INVAL; 12773 } 12774 12775 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 12776 wmi_err("Rx mgmt frame length mismatch, discard it"); 12777 return QDF_STATUS_E_INVAL; 12778 } 12779 12780 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12781 wmi_handle, 12782 ev_hdr->pdev_id); 12783 hdr->chan_freq = ev_hdr->chan_freq; 12784 hdr->channel = ev_hdr->channel; 12785 hdr->snr = ev_hdr->snr; 12786 hdr->rate = ev_hdr->rate; 12787 hdr->phy_mode = ev_hdr->phy_mode; 12788 hdr->buf_len = ev_hdr->buf_len; 12789 hdr->status = ev_hdr->status; 12790 hdr->flags = ev_hdr->flags; 12791 hdr->rssi = ev_hdr->rssi; 12792 hdr->tsf_delta = ev_hdr->tsf_delta; 12793 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 12794 for (i = 0; i < ATH_MAX_ANTENNA; i++) 12795 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 12796 12797 *bufp = param_tlvs->bufp; 12798 12799 return QDF_STATUS_SUCCESS; 12800 } 12801 12802 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 12803 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 12804 { 12805 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12806 wmi_mgmt_rx_params_ext *ext_params_tlv; 12807 wmi_mgmt_rx_hdr *ev_hdr; 12808 12809 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 12810 if (!param_tlvs) { 12811 wmi_err("param_tlvs is NULL"); 12812 return QDF_STATUS_E_INVAL; 12813 } 12814 12815 ev_hdr = param_tlvs->hdr; 12816 if (!ev_hdr) { 12817 wmi_err("Rx event is NULL"); 12818 return QDF_STATUS_E_INVAL; 12819 } 12820 12821 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 12822 if (ext_params_tlv) { 12823 ext_params->ba_win_size = WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 12824 ext_params_tlv->mgmt_rx_params_ext_dword1); 12825 if (ext_params->ba_win_size > 1024) { 12826 wmi_err("ba win size from TLV is Invalid"); 12827 return QDF_STATUS_E_INVAL; 12828 } 12829 12830 ext_params->reo_win_size = WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 12831 ext_params_tlv->mgmt_rx_params_ext_dword1); 12832 if (ext_params->reo_win_size > 2048) { 12833 wmi_err("reo win size from TLV is Invalid"); 12834 return QDF_STATUS_E_INVAL; 12835 } 12836 } else { 12837 ext_params->ba_win_size = 0; 12838 ext_params->reo_win_size = 0; 12839 } 12840 12841 return QDF_STATUS_SUCCESS; 12842 } 12843 12844 #ifdef WLAN_MGMT_RX_REO_SUPPORT 12845 /** 12846 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 12847 * @wmi_handle: wmi handle 12848 * @evt_buf: pointer to event buffer 12849 * @params: Pointer to MGMT Rx REO parameters 12850 * 12851 * Return: QDF_STATUS_SUCCESS for success or error code 12852 */ 12853 static QDF_STATUS 12854 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 12855 void *evt_buf, 12856 struct mgmt_rx_reo_params *params) 12857 { 12858 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 12859 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 12860 12861 param_tlvs = evt_buf; 12862 if (!param_tlvs) { 12863 wmi_err("param_tlvs is NULL"); 12864 return QDF_STATUS_E_INVAL; 12865 } 12866 12867 ev_hdr = param_tlvs->hdr; 12868 if (!params) { 12869 wmi_err("Rx REO parameters is NULL"); 12870 return QDF_STATUS_E_INVAL; 12871 } 12872 12873 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12874 wmi_handle, 12875 ev_hdr->pdev_id); 12876 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 12877 ev_hdr->mgmt_pkt_ctr_info); 12878 params->global_timestamp = ev_hdr->global_timestamp; 12879 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 12880 ev_hdr->mgmt_pkt_ctr_info); 12881 params->duration_us = ev_hdr->rx_ppdu_duration_us; 12882 params->start_timestamp = params->global_timestamp; 12883 params->end_timestamp = params->start_timestamp + 12884 params->duration_us; 12885 12886 return QDF_STATUS_SUCCESS; 12887 } 12888 12889 /** 12890 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 12891 * MGMT_RX_EVENT_ID 12892 * @wmi_handle: wmi handle 12893 * @evt_buf: pointer to event buffer 12894 * @params: Pointer to MGMT Rx REO parameters 12895 * 12896 * Return: QDF_STATUS_SUCCESS for success or error code 12897 */ 12898 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 12899 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 12900 { 12901 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 12902 wmi_mgmt_rx_reo_params *reo_params_tlv; 12903 wmi_mgmt_rx_hdr *ev_hdr; 12904 12905 param_tlvs = evt_buf; 12906 if (!param_tlvs) { 12907 wmi_err("param_tlvs is NULL"); 12908 return QDF_STATUS_E_INVAL; 12909 } 12910 12911 ev_hdr = param_tlvs->hdr; 12912 if (!ev_hdr) { 12913 wmi_err("Rx event is NULL"); 12914 return QDF_STATUS_E_INVAL; 12915 } 12916 12917 reo_params_tlv = param_tlvs->reo_params; 12918 if (!reo_params_tlv) { 12919 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 12920 return QDF_STATUS_E_INVAL; 12921 } 12922 12923 if (!reo_params) { 12924 wmi_err("MGMT Rx REO params is NULL"); 12925 return QDF_STATUS_E_INVAL; 12926 } 12927 12928 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12929 wmi_handle, 12930 ev_hdr->pdev_id); 12931 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 12932 reo_params_tlv->mgmt_pkt_ctr_link_info); 12933 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 12934 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 12935 reo_params_tlv->mgmt_pkt_ctr_link_info); 12936 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 12937 reo_params->start_timestamp = reo_params->global_timestamp; 12938 reo_params->end_timestamp = reo_params->start_timestamp + 12939 reo_params->duration_us; 12940 12941 return QDF_STATUS_SUCCESS; 12942 } 12943 12944 /** 12945 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 12946 * configuration command 12947 * @wmi_handle: wmi handle 12948 * @pdev_id: pdev ID of the radio 12949 * @filter: Pointer to MGMT Rx REO filter 12950 * 12951 * Return: QDF_STATUS_SUCCESS for success or error code 12952 */ 12953 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 12954 wmi_unified_t wmi_handle, 12955 uint8_t pdev_id, 12956 struct mgmt_rx_reo_filter *filter) 12957 { 12958 QDF_STATUS ret; 12959 wmi_buf_t buf; 12960 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 12961 size_t len = sizeof(*cmd); 12962 12963 if (!filter) { 12964 wmi_err("mgmt_rx_reo_filter is NULL"); 12965 return QDF_STATUS_E_INVAL; 12966 } 12967 12968 buf = wmi_buf_alloc(wmi_handle, len); 12969 if (!buf) { 12970 wmi_err("wmi_buf_alloc failed"); 12971 return QDF_STATUS_E_NOMEM; 12972 } 12973 12974 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 12975 wmi_buf_data(buf); 12976 12977 WMITLV_SET_HDR(&cmd->tlv_header, 12978 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 12979 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 12980 12981 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 12982 wmi_handle, 12983 pdev_id); 12984 cmd->filter_low = filter->low; 12985 cmd->filter_high = filter->high; 12986 12987 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 12988 ret = wmi_unified_cmd_send( 12989 wmi_handle, buf, len, 12990 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 12991 12992 if (QDF_IS_STATUS_ERROR(ret)) { 12993 wmi_err("Failed to send WMI command"); 12994 wmi_buf_free(buf); 12995 } 12996 12997 return ret; 12998 } 12999 #endif 13000 13001 /** 13002 * extract_frame_pn_params_tlv() - extract PN params from event 13003 * @wmi_handle: wmi handle 13004 * @evt_buf: pointer to event buffer 13005 * @pn_params: Pointer to Frame PN params 13006 * 13007 * Return: QDF_STATUS_SUCCESS for success or error code 13008 */ 13009 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13010 void *evt_buf, 13011 struct frame_pn_params *pn_params) 13012 { 13013 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13014 wmi_frame_pn_params *pn_params_tlv; 13015 13016 if (!is_service_enabled_tlv(wmi_handle, 13017 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13018 return QDF_STATUS_SUCCESS; 13019 13020 param_tlvs = evt_buf; 13021 if (!param_tlvs) { 13022 wmi_err("Got NULL point message from FW"); 13023 return QDF_STATUS_E_INVAL; 13024 } 13025 13026 if (!pn_params) { 13027 wmi_err("PN Params is NULL"); 13028 return QDF_STATUS_E_INVAL; 13029 } 13030 13031 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13032 * found by target 13033 */ 13034 pn_params_tlv = param_tlvs->pn_params; 13035 if (!pn_params_tlv) 13036 return QDF_STATUS_SUCCESS; 13037 13038 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13039 sizeof(pn_params->curr_pn)); 13040 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13041 sizeof(pn_params->prev_pn)); 13042 13043 return QDF_STATUS_SUCCESS; 13044 } 13045 13046 /** 13047 * extract_is_conn_ap_param_tlv() - extract is_conn_ap_frame param from event 13048 * @wmi_handle: wmi handle 13049 * @evt_buf: pointer to event buffer 13050 * @is_conn_ap: Pointer for is_conn_ap frame 13051 * 13052 * Return: QDF_STATUS_SUCCESS for success or error code 13053 */ 13054 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13055 wmi_unified_t wmi_handle, 13056 void *evt_buf, 13057 struct frm_conn_ap *is_conn_ap) 13058 { 13059 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13060 wmi_is_my_mgmt_frame *my_frame_tlv; 13061 13062 param_tlvs = evt_buf; 13063 if (!param_tlvs) { 13064 wmi_err("Got NULL point message from FW"); 13065 return QDF_STATUS_E_INVAL; 13066 } 13067 13068 if (!is_conn_ap) { 13069 wmi_err(" is connected ap param is NULL"); 13070 return QDF_STATUS_E_INVAL; 13071 } 13072 13073 my_frame_tlv = param_tlvs->my_frame; 13074 if (!my_frame_tlv) 13075 return QDF_STATUS_SUCCESS; 13076 13077 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13078 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13079 13080 return QDF_STATUS_SUCCESS; 13081 } 13082 13083 /** 13084 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13085 * @wmi_handle: wmi handle 13086 * @param evt_buf: pointer to event buffer 13087 * @param param: Pointer to hold roam param 13088 * 13089 * Return: QDF_STATUS_SUCCESS for success or error code 13090 */ 13091 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13092 void *evt_buf, wmi_host_roam_event *param) 13093 { 13094 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13095 wmi_roam_event_fixed_param *evt; 13096 13097 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13098 if (!param_buf) { 13099 wmi_err("Invalid roam event buffer"); 13100 return QDF_STATUS_E_INVAL; 13101 } 13102 13103 evt = param_buf->fixed_param; 13104 qdf_mem_zero(param, sizeof(*param)); 13105 13106 param->vdev_id = evt->vdev_id; 13107 param->reason = evt->reason; 13108 param->rssi = evt->rssi; 13109 13110 return QDF_STATUS_SUCCESS; 13111 } 13112 13113 /** 13114 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 13115 * @wmi_handle: wmi handle 13116 * @param evt_buf: pointer to event buffer 13117 * @param param: Pointer to hold vdev scan param 13118 * 13119 * Return: QDF_STATUS_SUCCESS for success or error code 13120 */ 13121 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 13122 void *evt_buf, struct scan_event *param) 13123 { 13124 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 13125 wmi_scan_event_fixed_param *evt = NULL; 13126 13127 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 13128 evt = param_buf->fixed_param; 13129 13130 qdf_mem_zero(param, sizeof(*param)); 13131 13132 switch (evt->event) { 13133 case WMI_SCAN_EVENT_STARTED: 13134 param->type = SCAN_EVENT_TYPE_STARTED; 13135 break; 13136 case WMI_SCAN_EVENT_COMPLETED: 13137 param->type = SCAN_EVENT_TYPE_COMPLETED; 13138 break; 13139 case WMI_SCAN_EVENT_BSS_CHANNEL: 13140 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 13141 break; 13142 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 13143 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 13144 break; 13145 case WMI_SCAN_EVENT_DEQUEUED: 13146 param->type = SCAN_EVENT_TYPE_DEQUEUED; 13147 break; 13148 case WMI_SCAN_EVENT_PREEMPTED: 13149 param->type = SCAN_EVENT_TYPE_PREEMPTED; 13150 break; 13151 case WMI_SCAN_EVENT_START_FAILED: 13152 param->type = SCAN_EVENT_TYPE_START_FAILED; 13153 break; 13154 case WMI_SCAN_EVENT_RESTARTED: 13155 param->type = SCAN_EVENT_TYPE_RESTARTED; 13156 break; 13157 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 13158 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 13159 break; 13160 case WMI_SCAN_EVENT_MAX: 13161 default: 13162 param->type = SCAN_EVENT_TYPE_MAX; 13163 break; 13164 }; 13165 13166 switch (evt->reason) { 13167 case WMI_SCAN_REASON_NONE: 13168 param->reason = SCAN_REASON_NONE; 13169 break; 13170 case WMI_SCAN_REASON_COMPLETED: 13171 param->reason = SCAN_REASON_COMPLETED; 13172 break; 13173 case WMI_SCAN_REASON_CANCELLED: 13174 param->reason = SCAN_REASON_CANCELLED; 13175 break; 13176 case WMI_SCAN_REASON_PREEMPTED: 13177 param->reason = SCAN_REASON_PREEMPTED; 13178 break; 13179 case WMI_SCAN_REASON_TIMEDOUT: 13180 param->reason = SCAN_REASON_TIMEDOUT; 13181 break; 13182 case WMI_SCAN_REASON_INTERNAL_FAILURE: 13183 param->reason = SCAN_REASON_INTERNAL_FAILURE; 13184 break; 13185 case WMI_SCAN_REASON_SUSPENDED: 13186 param->reason = SCAN_REASON_SUSPENDED; 13187 break; 13188 case WMI_SCAN_REASON_DFS_VIOLATION: 13189 param->reason = SCAN_REASON_DFS_VIOLATION; 13190 break; 13191 case WMI_SCAN_REASON_MAX: 13192 param->reason = SCAN_REASON_MAX; 13193 break; 13194 default: 13195 param->reason = SCAN_REASON_MAX; 13196 break; 13197 }; 13198 13199 param->chan_freq = evt->channel_freq; 13200 param->requester = evt->requestor; 13201 param->scan_id = evt->scan_id; 13202 param->vdev_id = evt->vdev_id; 13203 param->timestamp = evt->tsf_timestamp; 13204 13205 return QDF_STATUS_SUCCESS; 13206 } 13207 13208 #ifdef FEATURE_WLAN_SCAN_PNO 13209 /** 13210 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 13211 * @wmi_handle: pointer to WMI handle 13212 * @evt_buf: pointer to WMI event buffer 13213 * @param: pointer to scan event param for NLO match 13214 * 13215 * Return: QDF_STATUS_SUCCESS for success or error code 13216 */ 13217 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 13218 void *evt_buf, 13219 struct scan_event *param) 13220 { 13221 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 13222 wmi_nlo_event *evt = param_buf->fixed_param; 13223 13224 qdf_mem_zero(param, sizeof(*param)); 13225 13226 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 13227 param->vdev_id = evt->vdev_id; 13228 13229 return QDF_STATUS_SUCCESS; 13230 } 13231 13232 /** 13233 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 13234 * @wmi_handle: pointer to WMI handle 13235 * @evt_buf: pointer to WMI event buffer 13236 * @param: pointer to scan event param for NLO complete 13237 * 13238 * Return: QDF_STATUS_SUCCESS for success or error code 13239 */ 13240 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 13241 void *evt_buf, 13242 struct scan_event *param) 13243 { 13244 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 13245 wmi_nlo_event *evt = param_buf->fixed_param; 13246 13247 qdf_mem_zero(param, sizeof(*param)); 13248 13249 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 13250 param->vdev_id = evt->vdev_id; 13251 13252 return QDF_STATUS_SUCCESS; 13253 } 13254 #endif 13255 13256 /** 13257 * extract_unit_test_tlv() - extract unit test data 13258 * @wmi_handle: wmi handle 13259 * @param evt_buf: pointer to event buffer 13260 * @param unit_test: pointer to hold unit test data 13261 * @param maxspace: Amount of space in evt_buf 13262 * 13263 * Return: QDF_STATUS_SUCCESS for success or error code 13264 */ 13265 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 13266 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 13267 { 13268 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 13269 wmi_unit_test_event_fixed_param *ev_param; 13270 uint32_t num_bufp; 13271 uint32_t copy_size; 13272 uint8_t *bufp; 13273 13274 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 13275 ev_param = param_buf->fixed_param; 13276 bufp = param_buf->bufp; 13277 num_bufp = param_buf->num_bufp; 13278 unit_test->vdev_id = ev_param->vdev_id; 13279 unit_test->module_id = ev_param->module_id; 13280 unit_test->diag_token = ev_param->diag_token; 13281 unit_test->flag = ev_param->flag; 13282 unit_test->payload_len = ev_param->payload_len; 13283 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 13284 ev_param->vdev_id, 13285 ev_param->module_id, 13286 ev_param->diag_token, 13287 ev_param->flag); 13288 wmi_debug("Unit-test data given below %d", num_bufp); 13289 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 13290 bufp, num_bufp); 13291 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 13292 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 13293 unit_test->buffer_len = copy_size; 13294 13295 return QDF_STATUS_SUCCESS; 13296 } 13297 13298 /** 13299 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 13300 * @wmi_handle: wmi handle 13301 * @param evt_buf: pointer to event buffer 13302 * @param index: Index into extended pdev stats 13303 * @param pdev_ext_stats: Pointer to hold extended pdev stats 13304 * 13305 * Return: QDF_STATUS_SUCCESS for success or error code 13306 */ 13307 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 13308 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 13309 { 13310 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13311 wmi_pdev_extd_stats *ev; 13312 13313 param_buf = evt_buf; 13314 if (!param_buf) 13315 return QDF_STATUS_E_FAILURE; 13316 13317 if (!param_buf->pdev_extd_stats) 13318 return QDF_STATUS_E_FAILURE; 13319 13320 ev = param_buf->pdev_extd_stats + index; 13321 13322 pdev_ext_stats->pdev_id = 13323 wmi_handle->ops->convert_target_pdev_id_to_host( 13324 wmi_handle, 13325 ev->pdev_id); 13326 pdev_ext_stats->my_rx_count = ev->my_rx_count; 13327 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 13328 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 13329 13330 return QDF_STATUS_SUCCESS; 13331 } 13332 13333 /** 13334 * extract_bcn_stats_tlv() - extract bcn stats from event 13335 * @wmi_handle: wmi handle 13336 * @param evt_buf: pointer to event buffer 13337 * @param index: Index into vdev stats 13338 * @param bcn_stats: Pointer to hold bcn stats 13339 * 13340 * Return: QDF_STATUS_SUCCESS for success or error code 13341 */ 13342 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 13343 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 13344 { 13345 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13346 wmi_stats_event_fixed_param *ev_param; 13347 uint8_t *data; 13348 13349 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13350 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13351 data = (uint8_t *) param_buf->data; 13352 13353 if (index < ev_param->num_bcn_stats) { 13354 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 13355 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13356 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13357 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13358 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 13359 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 13360 (index * sizeof(wmi_bcn_stats))); 13361 13362 bcn_stats->vdev_id = ev->vdev_id; 13363 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 13364 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 13365 } 13366 13367 return QDF_STATUS_SUCCESS; 13368 } 13369 13370 /** 13371 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 13372 * stats from event 13373 * @wmi_handle: wmi handle 13374 * @param evt_buf: pointer to event buffer 13375 * @param index: Index into vdev stats 13376 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 13377 * 13378 * Return: QDF_STATUS_SUCCESS for success or error code 13379 */ 13380 static QDF_STATUS 13381 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 13382 void *evt_buf, uint32_t index, 13383 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 13384 { 13385 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13386 wmi_vdev_extd_stats *ev; 13387 13388 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 13389 13390 if (param_buf->vdev_extd_stats) { 13391 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 13392 index); 13393 vdev_stats->vdev_id = ev->vdev_id; 13394 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 13395 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 13396 vdev_stats->unsolicited_prb_succ_cnt = 13397 ev->unsolicited_prb_succ_cnt; 13398 vdev_stats->unsolicited_prb_fail_cnt = 13399 ev->unsolicited_prb_fail_cnt; 13400 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 13401 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 13402 ev->unsolicited_prb_succ_cnt, 13403 ev->unsolicited_prb_fail_cnt); 13404 } 13405 13406 return QDF_STATUS_SUCCESS; 13407 } 13408 13409 /** 13410 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 13411 * @wmi_handle: wmi handle 13412 * @param evt_buf: pointer to event buffer 13413 * @param index: Index into bcn fault stats 13414 * @param bcnflt_stats: Pointer to hold bcn fault stats 13415 * 13416 * Return: QDF_STATUS_SUCCESS for success or error code 13417 */ 13418 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 13419 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 13420 { 13421 return QDF_STATUS_SUCCESS; 13422 } 13423 13424 /** 13425 * extract_chan_stats_tlv() - extract chan stats from event 13426 * @wmi_handle: wmi handle 13427 * @param evt_buf: pointer to event buffer 13428 * @param index: Index into chan stats 13429 * @param vdev_extd_stats: Pointer to hold chan stats 13430 * 13431 * Return: QDF_STATUS_SUCCESS for success or error code 13432 */ 13433 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 13434 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 13435 { 13436 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 13437 wmi_stats_event_fixed_param *ev_param; 13438 uint8_t *data; 13439 13440 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 13441 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 13442 data = (uint8_t *) param_buf->data; 13443 13444 if (index < ev_param->num_chan_stats) { 13445 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 13446 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 13447 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 13448 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 13449 (index * sizeof(wmi_chan_stats))); 13450 13451 13452 /* Non-TLV doesn't have num_chan_stats */ 13453 chan_stats->chan_mhz = ev->chan_mhz; 13454 chan_stats->sampling_period_us = ev->sampling_period_us; 13455 chan_stats->rx_clear_count = ev->rx_clear_count; 13456 chan_stats->tx_duration_us = ev->tx_duration_us; 13457 chan_stats->rx_duration_us = ev->rx_duration_us; 13458 } 13459 13460 return QDF_STATUS_SUCCESS; 13461 } 13462 13463 /** 13464 * extract_profile_ctx_tlv() - extract profile context from event 13465 * @wmi_handle: wmi handle 13466 * @param evt_buf: pointer to event buffer 13467 * @idx: profile stats index to extract 13468 * @param profile_ctx: Pointer to hold profile context 13469 * 13470 * Return: QDF_STATUS_SUCCESS for success or error code 13471 */ 13472 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 13473 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 13474 { 13475 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13476 13477 wmi_wlan_profile_ctx_t *ev; 13478 13479 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13480 if (!param_buf) { 13481 wmi_err("Invalid profile data event buf"); 13482 return QDF_STATUS_E_INVAL; 13483 } 13484 13485 ev = param_buf->profile_ctx; 13486 13487 profile_ctx->tot = ev->tot; 13488 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 13489 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 13490 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 13491 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 13492 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 13493 profile_ctx->bin_count = ev->bin_count; 13494 13495 return QDF_STATUS_SUCCESS; 13496 } 13497 13498 /** 13499 * extract_profile_data_tlv() - extract profile data from event 13500 * @wmi_handle: wmi handle 13501 * @param evt_buf: pointer to event buffer 13502 * @param profile_data: Pointer to hold profile data 13503 * 13504 * Return: QDF_STATUS_SUCCESS for success or error code 13505 */ 13506 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 13507 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 13508 { 13509 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 13510 wmi_wlan_profile_t *ev; 13511 13512 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 13513 if (!param_buf) { 13514 wmi_err("Invalid profile data event buf"); 13515 return QDF_STATUS_E_INVAL; 13516 } 13517 13518 ev = ¶m_buf->profile_data[idx]; 13519 profile_data->id = ev->id; 13520 profile_data->cnt = ev->cnt; 13521 profile_data->tot = ev->tot; 13522 profile_data->min = ev->min; 13523 profile_data->max = ev->max; 13524 profile_data->hist_intvl = ev->hist_intvl; 13525 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 13526 13527 return QDF_STATUS_SUCCESS; 13528 } 13529 13530 /** 13531 * extract_pdev_utf_event_tlv() - extract UTF data info from event 13532 * @wmi_handle: WMI handle 13533 * @param evt_buf: Pointer to event buffer 13534 * @param param: Pointer to hold data 13535 * 13536 * Return : QDF_STATUS_SUCCESS for success or error code 13537 */ 13538 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 13539 uint8_t *evt_buf, 13540 struct wmi_host_pdev_utf_event *event) 13541 { 13542 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 13543 struct wmi_host_utf_seg_header_info *seg_hdr; 13544 13545 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 13546 event->data = param_buf->data; 13547 event->datalen = param_buf->num_data; 13548 13549 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 13550 wmi_err("Invalid datalen: %d", event->datalen); 13551 return QDF_STATUS_E_INVAL; 13552 } 13553 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 13554 /* Set pdev_id=1 until FW adds support to include pdev_id */ 13555 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13556 wmi_handle, 13557 seg_hdr->pdev_id); 13558 13559 return QDF_STATUS_SUCCESS; 13560 } 13561 13562 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 13563 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13564 uint8_t *event, 13565 uint32_t *num_rf_characterization_entries) 13566 { 13567 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13568 13569 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13570 if (!param_buf) 13571 return QDF_STATUS_E_INVAL; 13572 13573 *num_rf_characterization_entries = 13574 param_buf->num_wmi_chan_rf_characterization_info; 13575 13576 return QDF_STATUS_SUCCESS; 13577 } 13578 13579 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 13580 uint8_t *event, 13581 uint32_t num_rf_characterization_entries, 13582 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 13583 { 13584 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 13585 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 13586 uint8_t ix; 13587 13588 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 13589 if (!param_buf) 13590 return QDF_STATUS_E_INVAL; 13591 13592 wmi_rf_characterization_entry = 13593 param_buf->wmi_chan_rf_characterization_info; 13594 if (!wmi_rf_characterization_entry) 13595 return QDF_STATUS_E_INVAL; 13596 13597 /* 13598 * Using num_wmi_chan_rf_characterization instead of param_buf value 13599 * since memory for rf_characterization_entries was allocated using 13600 * the former. 13601 */ 13602 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 13603 rf_characterization_entries[ix].freq = 13604 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 13605 &wmi_rf_characterization_entry[ix]); 13606 13607 rf_characterization_entries[ix].bw = 13608 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 13609 &wmi_rf_characterization_entry[ix]); 13610 13611 rf_characterization_entries[ix].chan_metric = 13612 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 13613 &wmi_rf_characterization_entry[ix]); 13614 13615 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 13616 "bw: %u, chan_metric: %u", 13617 ix, rf_characterization_entries[ix].freq, 13618 rf_characterization_entries[ix].bw, 13619 rf_characterization_entries[ix].chan_metric); 13620 } 13621 13622 return QDF_STATUS_SUCCESS; 13623 } 13624 #endif 13625 13626 #ifdef WLAN_FEATURE_11BE 13627 static void 13628 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13629 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13630 { 13631 cap->supports_chan_width_320 = 13632 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 13633 } 13634 #else 13635 static void 13636 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 13637 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 13638 { 13639 } 13640 #endif /* WLAN_FEATURE_11BE */ 13641 13642 /** 13643 * extract_chainmask_tables_tlv() - extract chain mask tables from event 13644 * @wmi_handle: wmi handle 13645 * @param evt_buf: pointer to event buffer 13646 * @param param: Pointer to hold evt buf 13647 * 13648 * Return: QDF_STATUS_SUCCESS for success or error code 13649 */ 13650 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 13651 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 13652 { 13653 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13654 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 13655 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13656 uint8_t i = 0, j = 0; 13657 uint32_t num_mac_phy_chainmask_caps = 0; 13658 13659 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13660 if (!param_buf) 13661 return QDF_STATUS_E_INVAL; 13662 13663 hw_caps = param_buf->soc_hw_mode_caps; 13664 if (!hw_caps) 13665 return QDF_STATUS_E_INVAL; 13666 13667 if ((!hw_caps->num_chainmask_tables) || 13668 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 13669 (hw_caps->num_chainmask_tables > 13670 param_buf->num_mac_phy_chainmask_combo)) 13671 return QDF_STATUS_E_INVAL; 13672 13673 chainmask_caps = param_buf->mac_phy_chainmask_caps; 13674 13675 if (!chainmask_caps) 13676 return QDF_STATUS_E_INVAL; 13677 13678 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13679 if (chainmask_table[i].num_valid_chainmasks > 13680 (UINT_MAX - num_mac_phy_chainmask_caps)) { 13681 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 13682 num_mac_phy_chainmask_caps, i, 13683 chainmask_table[i].num_valid_chainmasks); 13684 return QDF_STATUS_E_INVAL; 13685 } 13686 num_mac_phy_chainmask_caps += 13687 chainmask_table[i].num_valid_chainmasks; 13688 } 13689 13690 if (num_mac_phy_chainmask_caps > 13691 param_buf->num_mac_phy_chainmask_caps) { 13692 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 13693 num_mac_phy_chainmask_caps, 13694 param_buf->num_mac_phy_chainmask_caps); 13695 return QDF_STATUS_E_INVAL; 13696 } 13697 13698 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 13699 13700 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 13701 i); 13702 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 13703 13704 chainmask_table[i].cap_list[j].chainmask = 13705 chainmask_caps->chainmask; 13706 13707 chainmask_table[i].cap_list[j].supports_chan_width_20 = 13708 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 13709 13710 chainmask_table[i].cap_list[j].supports_chan_width_40 = 13711 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 13712 13713 chainmask_table[i].cap_list[j].supports_chan_width_80 = 13714 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 13715 13716 chainmask_table[i].cap_list[j].supports_chan_width_160 = 13717 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 13718 13719 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 13720 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 13721 13722 chainmask_table[i].cap_list[j].chain_mask_2G = 13723 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 13724 13725 chainmask_table[i].cap_list[j].chain_mask_5G = 13726 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 13727 13728 chainmask_table[i].cap_list[j].chain_mask_tx = 13729 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 13730 13731 chainmask_table[i].cap_list[j].chain_mask_rx = 13732 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 13733 13734 chainmask_table[i].cap_list[j].supports_aDFS = 13735 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 13736 13737 chainmask_table[i].cap_list[j].supports_aSpectral = 13738 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 13739 13740 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 13741 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 13742 13743 chainmask_table[i].cap_list[j].supports_aDFS_160 = 13744 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 13745 13746 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 13747 chainmask_caps); 13748 13749 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 13750 chainmask_caps->supported_flags, 13751 chainmask_caps->chainmask); 13752 chainmask_caps++; 13753 } 13754 } 13755 13756 return QDF_STATUS_SUCCESS; 13757 } 13758 13759 /** 13760 * extract_service_ready_ext_tlv() - extract basic extended service ready params 13761 * from event 13762 * @wmi_handle: wmi handle 13763 * @param evt_buf: pointer to event buffer 13764 * @param param: Pointer to hold evt buf 13765 * 13766 * Return: QDF_STATUS_SUCCESS for success or error code 13767 */ 13768 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 13769 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 13770 { 13771 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 13772 wmi_service_ready_ext_event_fixed_param *ev; 13773 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 13774 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 13775 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 13776 uint8_t i = 0; 13777 13778 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 13779 if (!param_buf) 13780 return QDF_STATUS_E_INVAL; 13781 13782 ev = param_buf->fixed_param; 13783 if (!ev) 13784 return QDF_STATUS_E_INVAL; 13785 13786 /* Move this to host based bitmap */ 13787 param->default_conc_scan_config_bits = 13788 ev->default_conc_scan_config_bits; 13789 param->default_fw_config_bits = ev->default_fw_config_bits; 13790 param->he_cap_info = ev->he_cap_info; 13791 param->mpdu_density = ev->mpdu_density; 13792 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 13793 param->fw_build_vers_ext = ev->fw_build_vers_ext; 13794 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13795 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 13796 param->max_bssid_indicator = ev->max_bssid_indicator; 13797 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 13798 13799 hw_caps = param_buf->soc_hw_mode_caps; 13800 if (hw_caps) 13801 param->num_hw_modes = hw_caps->num_hw_modes; 13802 else 13803 param->num_hw_modes = 0; 13804 13805 reg_caps = param_buf->soc_hal_reg_caps; 13806 if (reg_caps) 13807 param->num_phy = reg_caps->num_phy; 13808 else 13809 param->num_phy = 0; 13810 13811 if (hw_caps) { 13812 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 13813 wmi_nofl_debug("Num chain mask tables: %d", 13814 hw_caps->num_chainmask_tables); 13815 } else 13816 param->num_chainmask_tables = 0; 13817 13818 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 13819 param->num_chainmask_tables > 13820 param_buf->num_mac_phy_chainmask_combo) { 13821 wmi_err_rl("num_chainmask_tables is OOB: %u", 13822 param->num_chainmask_tables); 13823 return QDF_STATUS_E_INVAL; 13824 } 13825 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 13826 13827 if (!chain_mask_combo) 13828 return QDF_STATUS_SUCCESS; 13829 13830 wmi_nofl_debug("Dumping chain mask combo data"); 13831 13832 for (i = 0; i < param->num_chainmask_tables; i++) { 13833 13834 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 13835 chain_mask_combo->chainmask_table_id, 13836 chain_mask_combo->num_valid_chainmask); 13837 13838 param->chainmask_table[i].table_id = 13839 chain_mask_combo->chainmask_table_id; 13840 param->chainmask_table[i].num_valid_chainmasks = 13841 chain_mask_combo->num_valid_chainmask; 13842 chain_mask_combo++; 13843 } 13844 wmi_nofl_debug("chain mask combo end"); 13845 13846 return QDF_STATUS_SUCCESS; 13847 } 13848 13849 #if defined(CONFIG_AFC_SUPPORT) 13850 /** 13851 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 13852 * type from event 13853 * @ev: pointer to event fixed param 13854 * @param: Pointer to hold the params 13855 * 13856 * Return: void 13857 */ 13858 static void 13859 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 13860 struct wlan_psoc_host_service_ext2_param *param) 13861 { 13862 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 13863 enum reg_afc_dev_deploy_type reg_afc_dev_type; 13864 13865 tgt_afc_dev_type = ev->afc_deployment_type; 13866 switch (tgt_afc_dev_type) { 13867 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 13868 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 13869 break; 13870 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 13871 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 13872 break; 13873 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 13874 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 13875 break; 13876 default: 13877 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 13878 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 13879 break; 13880 } 13881 param->afc_dev_type = reg_afc_dev_type; 13882 13883 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 13884 } 13885 #else 13886 static inline void 13887 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 13888 struct wlan_psoc_host_service_ext2_param *param) 13889 { 13890 } 13891 #endif 13892 13893 /** 13894 * extract_ul_mumimo_support) - extract UL-MUMIMO capability from target cap 13895 * @param: Pointer to hold the params 13896 * 13897 * Return: Void 13898 */ 13899 static void 13900 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 13901 { 13902 uint32_t tgt_cap = param->target_cap_flags; 13903 13904 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 13905 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 13906 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 13907 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 13908 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 13909 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 13910 } 13911 13912 /** 13913 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 13914 * event 13915 * @wmi_handle: wmi handle 13916 * @event: pointer to event buffer 13917 * @param: Pointer to hold the params 13918 * 13919 * Return: QDF_STATUS_SUCCESS for success or error code 13920 */ 13921 static QDF_STATUS 13922 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 13923 struct wlan_psoc_host_service_ext2_param *param) 13924 { 13925 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13926 wmi_service_ready_ext2_event_fixed_param *ev; 13927 13928 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13929 if (!param_buf) 13930 return QDF_STATUS_E_INVAL; 13931 13932 ev = param_buf->fixed_param; 13933 if (!ev) 13934 return QDF_STATUS_E_INVAL; 13935 13936 param->reg_db_version_major = 13937 WMI_REG_DB_VERSION_MAJOR_GET( 13938 ev->reg_db_version); 13939 param->reg_db_version_minor = 13940 WMI_REG_DB_VERSION_MINOR_GET( 13941 ev->reg_db_version); 13942 param->bdf_reg_db_version_major = 13943 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 13944 ev->reg_db_version); 13945 param->bdf_reg_db_version_minor = 13946 WMI_BDF_REG_DB_VERSION_MINOR_GET( 13947 ev->reg_db_version); 13948 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 13949 13950 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 13951 13952 if (param_buf->nan_cap) 13953 param->max_ndp_sessions = 13954 param_buf->nan_cap->max_ndp_sessions; 13955 else 13956 param->max_ndp_sessions = 0; 13957 13958 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 13959 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 13960 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 13961 ev->max_user_per_ppdu_ofdma); 13962 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 13963 ev->max_user_per_ppdu_ofdma); 13964 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 13965 ev->max_user_per_ppdu_mumimo); 13966 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 13967 ev->max_user_per_ppdu_mumimo); 13968 param->target_cap_flags = ev->target_cap_flags; 13969 extract_ul_mumimo_support(param); 13970 wmi_debug("htt peer data :%d", ev->target_cap_flags); 13971 13972 extract_svc_rdy_ext2_afc_tlv(ev, param); 13973 13974 return QDF_STATUS_SUCCESS; 13975 } 13976 13977 /* 13978 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 13979 * service ready ext 2 13980 * 13981 * @wmi_handle: wmi handle 13982 * @event: pointer to event buffer 13983 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 13984 * it indicates async SBS mode is supported, and 13985 * lower-band/higher band to MAC mapping is 13986 * switch-able. unit: mhz. examples 5180, 5320 13987 * 13988 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 13989 */ 13990 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 13991 wmi_unified_t wmi_handle, uint8_t *event, 13992 uint32_t *sbs_lower_band_end_freq) 13993 { 13994 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13995 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 13996 13997 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 13998 if (!param_buf) 13999 return QDF_STATUS_E_INVAL; 14000 14001 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 14002 if (!dbs_or_sbs_caps) 14003 return QDF_STATUS_E_INVAL; 14004 14005 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 14006 14007 return QDF_STATUS_SUCCESS; 14008 } 14009 14010 /** 14011 * extract_sar_cap_service_ready_ext_tlv() - 14012 * extract SAR cap from service ready event 14013 * @wmi_handle: wmi handle 14014 * @event: pointer to event buffer 14015 * @ext_param: extended target info 14016 * 14017 * Return: QDF_STATUS_SUCCESS for success or error code 14018 */ 14019 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 14020 wmi_unified_t wmi_handle, 14021 uint8_t *event, 14022 struct wlan_psoc_host_service_ext_param *ext_param) 14023 { 14024 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14025 WMI_SAR_CAPABILITIES *sar_caps; 14026 14027 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14028 14029 if (!param_buf) 14030 return QDF_STATUS_E_INVAL; 14031 14032 sar_caps = param_buf->sar_caps; 14033 if (sar_caps) 14034 ext_param->sar_version = sar_caps->active_version; 14035 else 14036 ext_param->sar_version = 0; 14037 14038 return QDF_STATUS_SUCCESS; 14039 } 14040 14041 /** 14042 * extract_hw_mode_cap_service_ready_ext_tlv() - 14043 * extract HW mode cap from service ready event 14044 * @wmi_handle: wmi handle 14045 * @param evt_buf: pointer to event buffer 14046 * @param param: Pointer to hold evt buf 14047 * @param hw_mode_idx: hw mode idx should be less than num_mode 14048 * 14049 * Return: QDF_STATUS_SUCCESS for success or error code 14050 */ 14051 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 14052 wmi_unified_t wmi_handle, 14053 uint8_t *event, uint8_t hw_mode_idx, 14054 struct wlan_psoc_host_hw_mode_caps *param) 14055 { 14056 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14057 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14058 14059 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14060 if (!param_buf) 14061 return QDF_STATUS_E_INVAL; 14062 14063 hw_caps = param_buf->soc_hw_mode_caps; 14064 if (!hw_caps) 14065 return QDF_STATUS_E_INVAL; 14066 14067 if (!hw_caps->num_hw_modes || 14068 !param_buf->hw_mode_caps || 14069 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14070 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 14071 return QDF_STATUS_E_INVAL; 14072 14073 if (hw_mode_idx >= hw_caps->num_hw_modes) 14074 return QDF_STATUS_E_INVAL; 14075 14076 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 14077 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 14078 14079 param->hw_mode_config_type = 14080 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 14081 14082 return QDF_STATUS_SUCCESS; 14083 } 14084 14085 /** 14086 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 14087 * @param param: host mac phy capabilities 14088 * @param mac_phy_caps: mac phy capabilities 14089 * 14090 * Return: void 14091 */ 14092 #ifdef WLAN_FEATURE_11BE 14093 static void 14094 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14095 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14096 { 14097 param->supports_11be = 14098 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 14099 14100 wmi_debug("11be support %d", param->supports_11be); 14101 } 14102 #else 14103 static void 14104 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 14105 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14106 { 14107 } 14108 #endif 14109 14110 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 14111 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14112 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14113 { 14114 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 14115 } 14116 #else 14117 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 14118 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 14119 { 14120 } 14121 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 14122 14123 /** 14124 * extract_mac_phy_cap_service_ready_ext_tlv() - 14125 * extract MAC phy cap from service ready event 14126 * @wmi_handle: wmi handle 14127 * @param evt_buf: pointer to event buffer 14128 * @param param: Pointer to hold evt buf 14129 * @param hw_mode_idx: hw mode idx should be less than num_mode 14130 * @param phy_id: phy id within hw_mode 14131 * 14132 * Return: QDF_STATUS_SUCCESS for success or error code 14133 */ 14134 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 14135 wmi_unified_t wmi_handle, 14136 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14137 struct wlan_psoc_host_mac_phy_caps *param) 14138 { 14139 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14140 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 14141 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14142 uint32_t phy_map; 14143 uint8_t hw_idx, phy_idx = 0, pdev_id; 14144 14145 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14146 if (!param_buf) 14147 return QDF_STATUS_E_INVAL; 14148 14149 hw_caps = param_buf->soc_hw_mode_caps; 14150 if (!hw_caps) 14151 return QDF_STATUS_E_INVAL; 14152 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 14153 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 14154 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 14155 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 14156 return QDF_STATUS_E_INVAL; 14157 } 14158 14159 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 14160 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 14161 break; 14162 14163 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 14164 while (phy_map) { 14165 phy_map >>= 1; 14166 phy_idx++; 14167 } 14168 } 14169 14170 if (hw_idx == hw_caps->num_hw_modes) 14171 return QDF_STATUS_E_INVAL; 14172 14173 phy_idx += phy_id; 14174 if (phy_idx >= param_buf->num_mac_phy_caps) 14175 return QDF_STATUS_E_INVAL; 14176 14177 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14178 14179 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14180 param->phy_idx = phy_idx; 14181 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 14182 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14183 wmi_handle, 14184 pdev_id); 14185 param->tgt_pdev_id = pdev_id; 14186 extract_hw_link_id(param, mac_phy_caps); 14187 param->phy_id = mac_phy_caps->phy_id; 14188 param->supports_11b = 14189 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 14190 param->supports_11g = 14191 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 14192 param->supports_11a = 14193 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 14194 param->supports_11n = 14195 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 14196 param->supports_11ac = 14197 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 14198 param->supports_11ax = 14199 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 14200 14201 extract_service_ready_11be_support(param, mac_phy_caps); 14202 14203 param->supported_bands = mac_phy_caps->supported_bands; 14204 param->ampdu_density = mac_phy_caps->ampdu_density; 14205 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 14206 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 14207 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 14208 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 14209 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 14210 mac_phy_caps->he_cap_info_2G; 14211 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 14212 mac_phy_caps->he_cap_info_2G_ext; 14213 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 14214 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 14215 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 14216 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 14217 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 14218 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 14219 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 14220 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 14221 mac_phy_caps->he_cap_info_5G; 14222 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 14223 mac_phy_caps->he_cap_info_5G_ext; 14224 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 14225 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 14226 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 14227 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 14228 qdf_mem_copy(¶m->he_cap_phy_info_2G, 14229 &mac_phy_caps->he_cap_phy_info_2G, 14230 sizeof(param->he_cap_phy_info_2G)); 14231 qdf_mem_copy(¶m->he_cap_phy_info_5G, 14232 &mac_phy_caps->he_cap_phy_info_5G, 14233 sizeof(param->he_cap_phy_info_5G)); 14234 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 14235 sizeof(param->he_ppet2G)); 14236 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 14237 sizeof(param->he_ppet5G)); 14238 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 14239 param->lmac_id = mac_phy_caps->lmac_id; 14240 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 14241 (mac_phy_caps->wireless_modes); 14242 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 14243 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 14244 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 14245 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 14246 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 14247 mac_phy_caps->nss_ratio); 14248 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 14249 14250 return QDF_STATUS_SUCCESS; 14251 } 14252 14253 #ifdef WLAN_FEATURE_11BE_MLO 14254 /** 14255 * extract_mac_phy_emlcap() - API to extract EML Capabilities 14256 * @param: host ext2 mac phy capabilities 14257 * @mac_phy_caps: ext mac phy capabilities 14258 * 14259 * Return: void 14260 */ 14261 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14262 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14263 { 14264 if (!param || !mac_phy_caps) 14265 return; 14266 14267 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 14268 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 14269 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 14270 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 14271 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 14272 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 14273 } 14274 14275 /** 14276 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 14277 * @param: host ext2 mac phy capabilities 14278 * @mac_phy_caps: ext mac phy capabilities 14279 * 14280 * Return: void 14281 */ 14282 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14283 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14284 { 14285 if (!param || !mac_phy_caps) 14286 return; 14287 14288 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 14289 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 14290 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 14291 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 14292 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 14293 } 14294 #else 14295 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14296 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14297 { 14298 } 14299 14300 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14301 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14302 { 14303 } 14304 #endif 14305 14306 /** 14307 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 14308 * @param param: host ext2 mac phy capabilities 14309 * @param mac_phy_caps: ext mac phy capabilities 14310 * 14311 * Return: void 14312 */ 14313 #ifdef WLAN_FEATURE_11BE 14314 static void extract_mac_phy_cap_ehtcaps( 14315 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14316 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14317 { 14318 uint32_t i; 14319 14320 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 14321 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 14322 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 14323 14324 qdf_mem_copy(¶m->eht_cap_info_2G, 14325 &mac_phy_caps->eht_cap_mac_info_2G, 14326 sizeof(param->eht_cap_info_2G)); 14327 qdf_mem_copy(¶m->eht_cap_info_5G, 14328 &mac_phy_caps->eht_cap_mac_info_5G, 14329 sizeof(param->eht_cap_info_5G)); 14330 14331 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 14332 &mac_phy_caps->eht_cap_phy_info_2G, 14333 sizeof(param->eht_cap_phy_info_2G)); 14334 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 14335 &mac_phy_caps->eht_cap_phy_info_5G, 14336 sizeof(param->eht_cap_phy_info_5G)); 14337 14338 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 14339 &mac_phy_caps->eht_supp_mcs_ext_2G, 14340 sizeof(param->eht_supp_mcs_ext_2G)); 14341 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 14342 &mac_phy_caps->eht_supp_mcs_ext_5G, 14343 sizeof(param->eht_supp_mcs_ext_5G)); 14344 14345 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 14346 sizeof(param->eht_ppet2G)); 14347 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 14348 sizeof(param->eht_ppet5G)); 14349 14350 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", 14351 mac_phy_caps->eht_cap_mac_info_2G[0], 14352 mac_phy_caps->eht_cap_mac_info_5G[0], 14353 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 14354 mac_phy_caps->eht_cap_info_internal); 14355 14356 wmi_nofl_debug("EHT phy caps: "); 14357 14358 wmi_nofl_debug("2G:"); 14359 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14360 wmi_nofl_debug("index %d value %x", 14361 i, param->eht_cap_phy_info_2G[i]); 14362 } 14363 wmi_nofl_debug("5G:"); 14364 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 14365 wmi_nofl_debug("index %d value %x", 14366 i, param->eht_cap_phy_info_5G[i]); 14367 } 14368 wmi_nofl_debug("2G MCS ext Map:"); 14369 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 14370 wmi_nofl_debug("index %d value %x", 14371 i, param->eht_supp_mcs_ext_2G[i]); 14372 } 14373 wmi_nofl_debug("5G MCS ext Map:"); 14374 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 14375 wmi_nofl_debug("index %d value %x", 14376 i, param->eht_supp_mcs_ext_5G[i]); 14377 } 14378 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 14379 param->eht_ppet2G.numss_m1, 14380 param->eht_ppet2G.ru_bit_mask); 14381 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14382 wmi_nofl_debug("index %d value %x", 14383 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 14384 } 14385 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 14386 param->eht_ppet5G.numss_m1, 14387 param->eht_ppet5G.ru_bit_mask); 14388 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 14389 wmi_nofl_debug("index %d value %x", 14390 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 14391 } 14392 } 14393 #else 14394 static void extract_mac_phy_cap_ehtcaps( 14395 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 14396 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 14397 { 14398 } 14399 #endif 14400 14401 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 14402 wmi_unified_t wmi_handle, 14403 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 14404 uint8_t phy_idx, 14405 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 14406 { 14407 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14408 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 14409 14410 if (!event) { 14411 wmi_err("null evt_buf"); 14412 return QDF_STATUS_E_INVAL; 14413 } 14414 14415 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14416 14417 if (!param_buf->num_mac_phy_caps) 14418 return QDF_STATUS_SUCCESS; 14419 14420 if (phy_idx >= param_buf->num_mac_phy_caps) 14421 return QDF_STATUS_E_INVAL; 14422 14423 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 14424 14425 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 14426 (phy_id != mac_phy_caps->phy_id)) 14427 return QDF_STATUS_E_INVAL; 14428 14429 param->hw_mode_id = mac_phy_caps->hw_mode_id; 14430 param->phy_id = mac_phy_caps->phy_id; 14431 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14432 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 14433 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 14434 mac_phy_caps->wireless_modes_ext); 14435 14436 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 14437 extract_mac_phy_emlcap(param, mac_phy_caps); 14438 extract_mac_phy_mldcap(param, mac_phy_caps); 14439 14440 return QDF_STATUS_SUCCESS; 14441 } 14442 14443 /** 14444 * extract_reg_cap_service_ready_ext_tlv() - 14445 * extract REG cap from service ready event 14446 * @wmi_handle: wmi handle 14447 * @param evt_buf: pointer to event buffer 14448 * @param param: Pointer to hold evt buf 14449 * @param phy_idx: phy idx should be less than num_mode 14450 * 14451 * Return: QDF_STATUS_SUCCESS for success or error code 14452 */ 14453 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 14454 wmi_unified_t wmi_handle, 14455 uint8_t *event, uint8_t phy_idx, 14456 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 14457 { 14458 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14459 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14460 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 14461 14462 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14463 if (!param_buf) 14464 return QDF_STATUS_E_INVAL; 14465 14466 reg_caps = param_buf->soc_hal_reg_caps; 14467 if (!reg_caps) 14468 return QDF_STATUS_E_INVAL; 14469 14470 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 14471 return QDF_STATUS_E_INVAL; 14472 14473 if (phy_idx >= reg_caps->num_phy) 14474 return QDF_STATUS_E_INVAL; 14475 14476 if (!param_buf->hal_reg_caps) 14477 return QDF_STATUS_E_INVAL; 14478 14479 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 14480 14481 param->phy_id = ext_reg_cap->phy_id; 14482 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 14483 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 14484 param->regcap1 = ext_reg_cap->regcap1; 14485 param->regcap2 = ext_reg_cap->regcap2; 14486 param->wireless_modes = convert_wireless_modes_tlv( 14487 ext_reg_cap->wireless_modes); 14488 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 14489 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 14490 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 14491 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 14492 14493 return QDF_STATUS_SUCCESS; 14494 } 14495 14496 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 14497 uint8_t num_dma_ring_caps) 14498 { 14499 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 14500 if (!num_dma_ring_caps) { 14501 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 14502 return QDF_STATUS_E_INVAL; 14503 } 14504 if (idx >= num_dma_ring_caps) { 14505 wmi_err("Index %d exceeds range", idx); 14506 return QDF_STATUS_E_INVAL; 14507 } 14508 return QDF_STATUS_SUCCESS; 14509 } 14510 14511 static void 14512 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 14513 struct wlan_psoc_host_dbr_ring_caps *param, 14514 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 14515 { 14516 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 14517 wmi_handle, 14518 dbr_ring_caps->pdev_id); 14519 param->mod_id = dbr_ring_caps->mod_id; 14520 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 14521 param->min_buf_size = dbr_ring_caps->min_buf_size; 14522 param->min_buf_align = dbr_ring_caps->min_buf_align; 14523 } 14524 14525 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 14526 wmi_unified_t wmi_handle, 14527 uint8_t *event, uint8_t idx, 14528 struct wlan_psoc_host_dbr_ring_caps *param) 14529 { 14530 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14531 QDF_STATUS status; 14532 14533 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 14534 if (!param_buf) 14535 return QDF_STATUS_E_INVAL; 14536 14537 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14538 if (status != QDF_STATUS_SUCCESS) 14539 return status; 14540 14541 populate_dbr_ring_cap_elems(wmi_handle, param, 14542 ¶m_buf->dma_ring_caps[idx]); 14543 return QDF_STATUS_SUCCESS; 14544 } 14545 14546 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 14547 wmi_unified_t wmi_handle, 14548 uint8_t *event, uint8_t idx, 14549 struct wlan_psoc_host_dbr_ring_caps *param) 14550 { 14551 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14552 QDF_STATUS status; 14553 14554 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14555 if (!param_buf) 14556 return QDF_STATUS_E_INVAL; 14557 14558 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 14559 if (status != QDF_STATUS_SUCCESS) 14560 return status; 14561 14562 populate_dbr_ring_cap_elems(wmi_handle, param, 14563 ¶m_buf->dma_ring_caps[idx]); 14564 return QDF_STATUS_SUCCESS; 14565 } 14566 14567 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 14568 wmi_unified_t wmi_handle, 14569 uint8_t *event, uint8_t idx, 14570 struct wlan_psoc_host_scan_radio_caps *param) 14571 { 14572 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14573 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 14574 14575 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14576 if (!param_buf) 14577 return QDF_STATUS_E_INVAL; 14578 14579 if (idx >= param_buf->num_wmi_scan_radio_caps) 14580 return QDF_STATUS_E_INVAL; 14581 14582 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 14583 param->phy_id = scan_radio_caps->phy_id; 14584 param->scan_radio_supported = 14585 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 14586 param->dfs_en = 14587 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 14588 14589 return QDF_STATUS_SUCCESS; 14590 } 14591 14592 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 14593 uint8_t *event, 14594 struct wmi_host_sw_cal_ver *cal) 14595 { 14596 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14597 wmi_sw_cal_ver_cap *fw_cap; 14598 14599 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14600 if (!param_buf) 14601 return QDF_STATUS_E_INVAL; 14602 14603 fw_cap = param_buf->sw_cal_ver_cap; 14604 if (!fw_cap) 14605 return QDF_STATUS_E_INVAL; 14606 14607 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 14608 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 14609 cal->status = fw_cap->status; 14610 14611 return QDF_STATUS_SUCCESS; 14612 } 14613 14614 /** 14615 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 14616 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 14617 * 14618 * Return: host thermal throt level 14619 */ 14620 static enum thermal_throttle_level 14621 wmi_tgt_thermal_level_to_host(uint32_t level) 14622 { 14623 switch (level) { 14624 case WMI_THERMAL_FULLPERF: 14625 return THERMAL_FULLPERF; 14626 case WMI_THERMAL_MITIGATION: 14627 return THERMAL_MITIGATION; 14628 case WMI_THERMAL_SHUTOFF: 14629 return THERMAL_SHUTOFF; 14630 case WMI_THERMAL_SHUTDOWN_TGT: 14631 return THERMAL_SHUTDOWN_TARGET; 14632 default: 14633 return THERMAL_UNKNOWN; 14634 } 14635 } 14636 14637 #ifdef THERMAL_STATS_SUPPORT 14638 static void 14639 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14640 uint32_t *therm_throt_levels, 14641 struct thermal_throt_level_stats *tt_temp_range_stats) 14642 { 14643 uint8_t lvl_idx; 14644 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14645 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 14646 14647 tt_stats_event = param_buf->fixed_param; 14648 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 14649 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 14650 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 14651 tt_stats_event->therm_throt_levels; 14652 14653 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 14654 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 14655 *therm_throt_levels, 14656 param_buf->num_temp_range_stats); 14657 return; 14658 } 14659 14660 wmi_tt_stats = param_buf->temp_range_stats; 14661 if (!wmi_tt_stats) { 14662 wmi_err("wmi_tt_stats Null"); 14663 return; 14664 } 14665 14666 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 14667 tt_temp_range_stats[lvl_idx].start_temp_level = 14668 wmi_tt_stats[lvl_idx].start_temp_level; 14669 tt_temp_range_stats[lvl_idx].end_temp_level = 14670 wmi_tt_stats[lvl_idx].end_temp_level; 14671 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 14672 wmi_tt_stats[lvl_idx].total_time_ms_lo; 14673 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 14674 wmi_tt_stats[lvl_idx].total_time_ms_hi; 14675 tt_temp_range_stats[lvl_idx].num_entry = 14676 wmi_tt_stats[lvl_idx].num_entry; 14677 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 14678 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 14679 wmi_tt_stats[lvl_idx].end_temp_level, 14680 wmi_tt_stats[lvl_idx].total_time_ms_lo, 14681 wmi_tt_stats[lvl_idx].total_time_ms_hi, 14682 wmi_tt_stats[lvl_idx].num_entry); 14683 } 14684 } 14685 #else 14686 static void 14687 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 14688 uint32_t *therm_throt_levels, 14689 struct thermal_throt_level_stats *tt_temp_range_stats) 14690 { 14691 } 14692 #endif 14693 14694 /** 14695 * extract_thermal_stats_tlv() - extract thermal stats from event 14696 * @wmi_handle: wmi handle 14697 * @param evt_buf: Pointer to event buffer 14698 * @param temp: Pointer to hold extracted temperature 14699 * @param level: Pointer to hold extracted level in host enum 14700 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 14701 * range 14702 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 14703 * every level 14704 * 14705 * Return: 0 for success or error code 14706 */ 14707 static QDF_STATUS 14708 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 14709 void *evt_buf, uint32_t *temp, 14710 enum thermal_throttle_level *level, 14711 uint32_t *therm_throt_levels, 14712 struct thermal_throt_level_stats *tt_temp_range_stats_event, 14713 uint32_t *pdev_id) 14714 { 14715 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14716 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 14717 14718 param_buf = 14719 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14720 if (!param_buf) 14721 return QDF_STATUS_E_INVAL; 14722 14723 tt_stats_event = param_buf->fixed_param; 14724 wmi_debug("thermal temperature %d level %d", 14725 tt_stats_event->temp, tt_stats_event->level); 14726 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 14727 wmi_handle, 14728 tt_stats_event->pdev_id); 14729 *temp = tt_stats_event->temp; 14730 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 14731 14732 if (tt_stats_event->therm_throt_levels) 14733 populate_thermal_stats(param_buf, therm_throt_levels, 14734 tt_temp_range_stats_event); 14735 14736 return QDF_STATUS_SUCCESS; 14737 } 14738 14739 /** 14740 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 14741 * @wmi_handle: wmi handle 14742 * @param evt_buf: pointer to event buffer 14743 * @param idx: Index to level stats 14744 * @param levelcount: Pointer to hold levelcount 14745 * @param dccount: Pointer to hold dccount 14746 * 14747 * Return: 0 for success or error code 14748 */ 14749 static QDF_STATUS 14750 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 14751 void *evt_buf, uint8_t idx, uint32_t *levelcount, 14752 uint32_t *dccount) 14753 { 14754 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 14755 wmi_therm_throt_level_stats_info *tt_level_info; 14756 14757 param_buf = 14758 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 14759 if (!param_buf) 14760 return QDF_STATUS_E_INVAL; 14761 14762 tt_level_info = param_buf->therm_throt_level_stats_info; 14763 14764 if (idx < THERMAL_LEVELS) { 14765 *levelcount = tt_level_info[idx].level_count; 14766 *dccount = tt_level_info[idx].dc_count; 14767 return QDF_STATUS_SUCCESS; 14768 } 14769 14770 return QDF_STATUS_E_FAILURE; 14771 } 14772 #ifdef BIG_ENDIAN_HOST 14773 /** 14774 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 14775 * @param data_len - data length 14776 * @param data - pointer to data 14777 * 14778 * Return: QDF_STATUS - success or error status 14779 */ 14780 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14781 { 14782 uint8_t *data_aligned = NULL; 14783 int c; 14784 unsigned char *data_unaligned; 14785 14786 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 14787 FIPS_ALIGN)); 14788 /* Assigning unaligned space to copy the data */ 14789 /* Checking if kmalloc does successful allocation */ 14790 if (!data_unaligned) 14791 return QDF_STATUS_E_FAILURE; 14792 14793 /* Checking if space is aligned */ 14794 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 14795 /* align the data space */ 14796 data_aligned = 14797 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 14798 } else { 14799 data_aligned = (u_int8_t *)data_unaligned; 14800 } 14801 14802 /* memset and copy content from data to data aligned */ 14803 OS_MEMSET(data_aligned, 0, data_len); 14804 OS_MEMCPY(data_aligned, data, data_len); 14805 /* Endianness to LE */ 14806 for (c = 0; c < data_len/4; c++) { 14807 *((u_int32_t *)data_aligned + c) = 14808 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 14809 } 14810 14811 /* Copy content to event->data */ 14812 OS_MEMCPY(data, data_aligned, data_len); 14813 14814 /* clean up allocated space */ 14815 qdf_mem_free(data_unaligned); 14816 data_aligned = NULL; 14817 data_unaligned = NULL; 14818 14819 /*************************************************************/ 14820 14821 return QDF_STATUS_SUCCESS; 14822 } 14823 #else 14824 /** 14825 * fips_conv_data_be() - DUMMY for LE platform 14826 * 14827 * Return: QDF_STATUS - success 14828 */ 14829 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 14830 { 14831 return QDF_STATUS_SUCCESS; 14832 } 14833 #endif 14834 14835 /** 14836 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 14837 * @wmi_handle - wmi handle 14838 * @params - PN request params for peer 14839 * 14840 * Return: QDF_STATUS - success or error status 14841 */ 14842 static QDF_STATUS 14843 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 14844 struct peer_request_pn_param *params) 14845 { 14846 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 14847 wmi_buf_t buf; 14848 uint8_t *buf_ptr; 14849 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 14850 14851 buf = wmi_buf_alloc(wmi_handle, len); 14852 if (!buf) { 14853 wmi_err("wmi_buf_alloc failed"); 14854 return QDF_STATUS_E_FAILURE; 14855 } 14856 14857 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14858 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 14859 14860 WMITLV_SET_HDR(&cmd->tlv_header, 14861 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 14862 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 14863 14864 cmd->vdev_id = params->vdev_id; 14865 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14866 cmd->key_type = params->key_type; 14867 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14868 WMI_PEER_TX_PN_REQUEST_CMDID)) { 14869 wmi_err("Failed to send WMI command"); 14870 wmi_buf_free(buf); 14871 return QDF_STATUS_E_FAILURE; 14872 } 14873 return QDF_STATUS_SUCCESS; 14874 } 14875 14876 /** 14877 * extract_get_pn_data_tlv() - extract pn resp 14878 * @wmi_handle - wmi handle 14879 * @params - PN response params for peer 14880 * 14881 * Return: QDF_STATUS - success or error status 14882 */ 14883 static QDF_STATUS 14884 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14885 struct wmi_host_get_pn_event *param) 14886 { 14887 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14888 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 14889 14890 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 14891 event = 14892 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 14893 14894 param->vdev_id = event->vdev_id; 14895 param->key_type = event->key_type; 14896 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 14897 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 14898 14899 return QDF_STATUS_SUCCESS; 14900 } 14901 14902 /** 14903 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 14904 * @wmi_handle: wmi handle 14905 * @params: Rx PN request params for peer 14906 * 14907 * Return: QDF_STATUS - success or error status 14908 */ 14909 static QDF_STATUS 14910 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 14911 struct peer_request_rxpn_param *params) 14912 { 14913 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 14914 wmi_buf_t buf; 14915 uint8_t *buf_ptr; 14916 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 14917 14918 if (!is_service_enabled_tlv(wmi_handle, 14919 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 14920 wmi_err("Rx PN Replay Check not supported by target"); 14921 return QDF_STATUS_E_NOSUPPORT; 14922 } 14923 14924 buf = wmi_buf_alloc(wmi_handle, len); 14925 if (!buf) { 14926 wmi_err("wmi_buf_alloc failed"); 14927 return QDF_STATUS_E_FAILURE; 14928 } 14929 14930 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14931 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 14932 14933 WMITLV_SET_HDR(&cmd->tlv_header, 14934 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 14935 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 14936 14937 cmd->vdev_id = params->vdev_id; 14938 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 14939 cmd->key_ix = params->keyix; 14940 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14941 WMI_PEER_RX_PN_REQUEST_CMDID)) { 14942 wmi_err("Failed to send WMI command"); 14943 wmi_buf_free(buf); 14944 return QDF_STATUS_E_FAILURE; 14945 } 14946 return QDF_STATUS_SUCCESS; 14947 } 14948 14949 /** 14950 * extract_get_rxpn_data_tlv() - extract Rx PN resp 14951 * @wmi_handle: wmi handle 14952 * @params: Rx PN response params for peer 14953 * 14954 * Return: QDF_STATUS - success or error status 14955 */ 14956 static QDF_STATUS 14957 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14958 struct wmi_host_get_rxpn_event *params) 14959 { 14960 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 14961 wmi_peer_rx_pn_response_event_fixed_param *event; 14962 14963 param_buf = evt_buf; 14964 event = param_buf->fixed_param; 14965 14966 params->vdev_id = event->vdev_id; 14967 params->keyix = event->key_idx; 14968 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 14969 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 14970 14971 return QDF_STATUS_SUCCESS; 14972 } 14973 14974 /** 14975 * extract_fips_event_data_tlv() - extract fips event data 14976 * @wmi_handle: wmi handle 14977 * @param evt_buf: pointer to event buffer 14978 * @param param: pointer FIPS event params 14979 * 14980 * Return: 0 for success or error code 14981 */ 14982 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 14983 void *evt_buf, struct wmi_host_fips_event_param *param) 14984 { 14985 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 14986 wmi_pdev_fips_event_fixed_param *event; 14987 14988 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 14989 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 14990 14991 if (event->data_len > param_buf->num_data) 14992 return QDF_STATUS_E_FAILURE; 14993 14994 if (fips_conv_data_be(event->data_len, param_buf->data) != 14995 QDF_STATUS_SUCCESS) 14996 return QDF_STATUS_E_FAILURE; 14997 14998 param->data = (uint32_t *)param_buf->data; 14999 param->data_len = event->data_len; 15000 param->error_status = event->error_status; 15001 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15002 wmi_handle, 15003 event->pdev_id); 15004 15005 return QDF_STATUS_SUCCESS; 15006 } 15007 15008 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 15009 /** 15010 * extract_fips_extend_event_data_tlv() - extract fips event data 15011 * @wmi_handle: wmi handle 15012 * @param evt_buf: pointer to event buffer 15013 * @param param: pointer FIPS event params 15014 * 15015 * Return: 0 for success or error code 15016 */ 15017 static QDF_STATUS 15018 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 15019 void *evt_buf, 15020 struct wmi_host_fips_extend_event_param 15021 *param) 15022 { 15023 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 15024 wmi_pdev_fips_extend_event_fixed_param *event; 15025 15026 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 15027 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 15028 15029 if (fips_conv_data_be(event->data_len, param_buf->data) != 15030 QDF_STATUS_SUCCESS) 15031 return QDF_STATUS_E_FAILURE; 15032 15033 param->data = (uint32_t *)param_buf->data; 15034 param->data_len = event->data_len; 15035 param->error_status = event->error_status; 15036 param->fips_cookie = event->fips_cookie; 15037 param->cmd_frag_idx = event->cmd_frag_idx; 15038 param->more_bit = event->more_bit; 15039 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15040 wmi_handle, 15041 event->pdev_id); 15042 15043 return QDF_STATUS_SUCCESS; 15044 } 15045 #endif 15046 15047 #ifdef WLAN_FEATURE_DISA 15048 /** 15049 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 15050 * params from event 15051 * @wmi_handle: wmi handle 15052 * @evt_buf: pointer to event buffer 15053 * @resp: Pointer to hold resp parameters 15054 * 15055 * Return: QDF_STATUS_SUCCESS for success or error code 15056 */ 15057 static QDF_STATUS 15058 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 15059 void *evt_buf, 15060 struct disa_encrypt_decrypt_resp_params 15061 *resp) 15062 { 15063 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 15064 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 15065 15066 param_buf = evt_buf; 15067 if (!param_buf) { 15068 wmi_err("encrypt decrypt resp evt_buf is NULL"); 15069 return QDF_STATUS_E_INVAL; 15070 } 15071 15072 data_event = param_buf->fixed_param; 15073 15074 resp->vdev_id = data_event->vdev_id; 15075 resp->status = data_event->status; 15076 15077 if ((data_event->data_length > param_buf->num_enc80211_frame) || 15078 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 15079 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 15080 wmi_err("FW msg data_len %d more than TLV hdr %d", 15081 data_event->data_length, 15082 param_buf->num_enc80211_frame); 15083 return QDF_STATUS_E_INVAL; 15084 } 15085 15086 resp->data_len = data_event->data_length; 15087 15088 if (resp->data_len) 15089 resp->data = (uint8_t *)param_buf->enc80211_frame; 15090 15091 return QDF_STATUS_SUCCESS; 15092 } 15093 #endif /* WLAN_FEATURE_DISA */ 15094 15095 static bool is_management_record_tlv(uint32_t cmd_id) 15096 { 15097 switch (cmd_id) { 15098 case WMI_MGMT_TX_SEND_CMDID: 15099 case WMI_MGMT_TX_COMPLETION_EVENTID: 15100 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 15101 case WMI_MGMT_RX_EVENTID: 15102 return true; 15103 default: 15104 return false; 15105 } 15106 } 15107 15108 static bool is_diag_event_tlv(uint32_t event_id) 15109 { 15110 if (WMI_DIAG_EVENTID == event_id) 15111 return true; 15112 15113 return false; 15114 } 15115 15116 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 15117 { 15118 uint16_t tag = 0; 15119 15120 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 15121 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 15122 __func__); 15123 return tag; 15124 } 15125 15126 if (wmi_handle->tag_crash_inject) 15127 tag = HTC_TX_PACKET_TAG_AUTO_PM; 15128 15129 wmi_handle->tag_crash_inject = false; 15130 return tag; 15131 } 15132 15133 /** 15134 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 15135 * @wmi_handle: WMI handle 15136 * @buf: WMI buffer 15137 * @cmd_id: WMI command Id 15138 * 15139 * Return htc_tx_tag 15140 */ 15141 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 15142 wmi_buf_t buf, 15143 uint32_t cmd_id) 15144 { 15145 uint16_t htc_tx_tag = 0; 15146 15147 switch (cmd_id) { 15148 case WMI_WOW_ENABLE_CMDID: 15149 case WMI_PDEV_SUSPEND_CMDID: 15150 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 15151 case WMI_PDEV_RESUME_CMDID: 15152 case WMI_HB_SET_ENABLE_CMDID: 15153 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 15154 #ifdef FEATURE_WLAN_D0WOW 15155 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 15156 #endif 15157 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 15158 break; 15159 case WMI_FORCE_FW_HANG_CMDID: 15160 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 15161 break; 15162 default: 15163 break; 15164 } 15165 15166 return htc_tx_tag; 15167 } 15168 15169 #ifdef CONFIG_BAND_6GHZ 15170 15171 static struct cur_reg_rule 15172 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 15173 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 15174 { 15175 struct cur_reg_rule *reg_rule_ptr; 15176 uint32_t count; 15177 15178 if (!num_reg_rules) 15179 return NULL; 15180 15181 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15182 sizeof(*reg_rule_ptr)); 15183 15184 if (!reg_rule_ptr) 15185 return NULL; 15186 15187 for (count = 0; count < num_reg_rules; count++) { 15188 reg_rule_ptr[count].start_freq = 15189 WMI_REG_RULE_START_FREQ_GET( 15190 wmi_reg_rule[count].freq_info); 15191 reg_rule_ptr[count].end_freq = 15192 WMI_REG_RULE_END_FREQ_GET( 15193 wmi_reg_rule[count].freq_info); 15194 reg_rule_ptr[count].max_bw = 15195 WMI_REG_RULE_MAX_BW_GET( 15196 wmi_reg_rule[count].bw_pwr_info); 15197 reg_rule_ptr[count].reg_power = 15198 WMI_REG_RULE_REG_POWER_GET( 15199 wmi_reg_rule[count].bw_pwr_info); 15200 reg_rule_ptr[count].ant_gain = 15201 WMI_REG_RULE_ANTENNA_GAIN_GET( 15202 wmi_reg_rule[count].bw_pwr_info); 15203 reg_rule_ptr[count].flags = 15204 WMI_REG_RULE_FLAGS_GET( 15205 wmi_reg_rule[count].flag_info); 15206 reg_rule_ptr[count].psd_flag = 15207 WMI_REG_RULE_PSD_FLAG_GET( 15208 wmi_reg_rule[count].psd_power_info); 15209 reg_rule_ptr[count].psd_eirp = 15210 WMI_REG_RULE_PSD_EIRP_GET( 15211 wmi_reg_rule[count].psd_power_info); 15212 } 15213 15214 return reg_rule_ptr; 15215 } 15216 #endif 15217 15218 static struct cur_reg_rule 15219 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 15220 wmi_regulatory_rule_struct *wmi_reg_rule) 15221 { 15222 struct cur_reg_rule *reg_rule_ptr; 15223 uint32_t count; 15224 15225 if (!num_reg_rules) 15226 return NULL; 15227 15228 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 15229 sizeof(*reg_rule_ptr)); 15230 15231 if (!reg_rule_ptr) 15232 return NULL; 15233 15234 for (count = 0; count < num_reg_rules; count++) { 15235 reg_rule_ptr[count].start_freq = 15236 WMI_REG_RULE_START_FREQ_GET( 15237 wmi_reg_rule[count].freq_info); 15238 reg_rule_ptr[count].end_freq = 15239 WMI_REG_RULE_END_FREQ_GET( 15240 wmi_reg_rule[count].freq_info); 15241 reg_rule_ptr[count].max_bw = 15242 WMI_REG_RULE_MAX_BW_GET( 15243 wmi_reg_rule[count].bw_pwr_info); 15244 reg_rule_ptr[count].reg_power = 15245 WMI_REG_RULE_REG_POWER_GET( 15246 wmi_reg_rule[count].bw_pwr_info); 15247 reg_rule_ptr[count].ant_gain = 15248 WMI_REG_RULE_ANTENNA_GAIN_GET( 15249 wmi_reg_rule[count].bw_pwr_info); 15250 reg_rule_ptr[count].flags = 15251 WMI_REG_RULE_FLAGS_GET( 15252 wmi_reg_rule[count].flag_info); 15253 } 15254 15255 return reg_rule_ptr; 15256 } 15257 15258 static enum cc_setting_code wmi_reg_status_to_reg_status( 15259 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 15260 { 15261 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 15262 return REG_SET_CC_STATUS_PASS; 15263 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 15264 return REG_CURRENT_ALPHA2_NOT_FOUND; 15265 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 15266 return REG_INIT_ALPHA2_NOT_FOUND; 15267 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 15268 return REG_SET_CC_CHANGE_NOT_ALLOWED; 15269 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 15270 return REG_SET_CC_STATUS_NO_MEMORY; 15271 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 15272 return REG_SET_CC_STATUS_FAIL; 15273 15274 wmi_debug("Unknown reg status code from WMI"); 15275 return REG_SET_CC_STATUS_FAIL; 15276 } 15277 15278 #ifdef CONFIG_BAND_6GHZ 15279 15280 #ifdef CONFIG_REG_CLIENT 15281 #define MAX_NUM_FCC_RULES 2 15282 15283 /** 15284 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 15285 * @num_fcc_rules: Number of FCC rules 15286 * @wmi_fcc_rule: WMI FCC rules TLV 15287 * 15288 * Return fcc_rule_ptr 15289 */ 15290 static struct cur_fcc_rule 15291 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 15292 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 15293 { 15294 struct cur_fcc_rule *fcc_rule_ptr; 15295 uint32_t count; 15296 15297 if (!wmi_fcc_rule) 15298 return NULL; 15299 15300 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 15301 sizeof(*fcc_rule_ptr)); 15302 if (!fcc_rule_ptr) 15303 return NULL; 15304 15305 for (count = 0; count < num_fcc_rules; count++) { 15306 fcc_rule_ptr[count].center_freq = 15307 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 15308 wmi_fcc_rule[count].freq_info); 15309 fcc_rule_ptr[count].tx_power = 15310 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 15311 wmi_fcc_rule[count].freq_info); 15312 } 15313 15314 return fcc_rule_ptr; 15315 } 15316 15317 /** 15318 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 15319 * @param_buf - Pointer to WMI params TLV 15320 * @ext_chan_list_event_hdr - Pointer to REG CHAN LIST CC EXT EVENT Fixed 15321 * Params TLV 15322 * @ext_wmi_reg_rule - Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 15323 * @ext_wmi_chan_priority - Pointer to REG CHAN LIST CC EXT EVENT Chan 15324 * Priority TLV 15325 * @evt_buf - Pointer to REG CHAN LIST CC EXT EVENT event buffer 15326 * @reg_info - Pointer to Regulatory Info 15327 * @len - Length of REG CHAN LIST CC EXT EVENT buffer 15328 * 15329 * Return - QDF_STATUS 15330 */ 15331 static QDF_STATUS extract_reg_fcc_rules_tlv( 15332 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15333 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15334 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15335 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15336 uint8_t *evt_buf, 15337 struct cur_regulatory_info *reg_info, 15338 uint32_t len) 15339 { 15340 int i; 15341 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 15342 15343 if (!param_buf) { 15344 wmi_err("invalid channel list event buf"); 15345 return QDF_STATUS_E_INVAL; 15346 } 15347 15348 reg_info->num_fcc_rules = 0; 15349 if (param_buf->reg_fcc_rule) { 15350 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 15351 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 15352 return QDF_STATUS_E_INVAL; 15353 } 15354 15355 ext_wmi_fcc_rule = 15356 (wmi_regulatory_fcc_rule_struct *) 15357 ((uint8_t *)ext_chan_list_event_hdr + 15358 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15359 WMI_TLV_HDR_SIZE + 15360 sizeof(wmi_regulatory_rule_ext_struct) * 15361 param_buf->num_reg_rule_array + 15362 WMI_TLV_HDR_SIZE + 15363 sizeof(wmi_regulatory_chan_priority_struct) * 15364 param_buf->num_reg_chan_priority + 15365 WMI_TLV_HDR_SIZE); 15366 15367 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 15368 param_buf->num_reg_fcc_rule, 15369 ext_wmi_fcc_rule); 15370 15371 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 15372 } 15373 15374 if (reg_info->fcc_rules_ptr) { 15375 for (i = 0; i < reg_info->num_fcc_rules; i++) { 15376 wmi_debug("FCC rule %d center_freq %d tx_power %d", 15377 i, reg_info->fcc_rules_ptr[i].center_freq, 15378 reg_info->fcc_rules_ptr[i].tx_power); 15379 } 15380 } 15381 return QDF_STATUS_SUCCESS; 15382 } 15383 #else 15384 static QDF_STATUS extract_reg_fcc_rules_tlv( 15385 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 15386 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 15387 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 15388 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 15389 uint8_t *evt_buf, 15390 struct cur_regulatory_info *reg_info, 15391 uint32_t len) 15392 { 15393 return QDF_STATUS_SUCCESS; 15394 } 15395 #endif 15396 15397 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 15398 wmi_unified_t wmi_handle, uint8_t *evt_buf, 15399 struct cur_regulatory_info *reg_info, uint32_t len) 15400 { 15401 uint32_t i, j, k; 15402 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 15403 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 15404 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 15405 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 15406 uint32_t num_2g_reg_rules, num_5g_reg_rules; 15407 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 15408 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 15409 uint32_t total_reg_rules = 0; 15410 QDF_STATUS status; 15411 15412 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 15413 if (!param_buf) { 15414 wmi_err("invalid channel list event buf"); 15415 return QDF_STATUS_E_FAILURE; 15416 } 15417 15418 ext_chan_list_event_hdr = param_buf->fixed_param; 15419 ext_wmi_chan_priority = param_buf->reg_chan_priority; 15420 15421 if (ext_wmi_chan_priority) 15422 reg_info->reg_6g_thresh_priority_freq = 15423 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 15424 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 15425 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 15426 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 15427 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 15428 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 15429 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 15430 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 15431 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 15432 15433 wmi_debug("num reg rules from fw"); 15434 wmi_debug("AP SP %d, LPI %d, VLP %d", 15435 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15436 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15437 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15438 15439 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15440 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 15441 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 15442 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 15443 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 15444 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 15445 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 15446 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 15447 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 15448 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 15449 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 15450 } 15451 15452 num_2g_reg_rules = reg_info->num_2g_reg_rules; 15453 total_reg_rules += num_2g_reg_rules; 15454 num_5g_reg_rules = reg_info->num_5g_reg_rules; 15455 total_reg_rules += num_5g_reg_rules; 15456 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15457 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 15458 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 15459 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 15460 num_6g_reg_rules_ap[i]); 15461 return QDF_STATUS_E_FAILURE; 15462 } 15463 total_reg_rules += num_6g_reg_rules_ap[i]; 15464 num_6g_reg_rules_client[i] = 15465 reg_info->num_6g_reg_rules_client[i]; 15466 } 15467 15468 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15469 total_reg_rules += 15470 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 15471 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 15472 total_reg_rules += 15473 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 15474 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 15475 MAX_6G_REG_RULES) || 15476 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 15477 MAX_6G_REG_RULES) || 15478 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 15479 MAX_6G_REG_RULES)) { 15480 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", 15481 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 15482 num_6g_reg_rules_client[REG_INDOOR_AP][i], 15483 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 15484 i); 15485 return QDF_STATUS_E_FAILURE; 15486 } 15487 } 15488 15489 if (total_reg_rules != param_buf->num_reg_rule_array) { 15490 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 15491 total_reg_rules, param_buf->num_reg_rule_array); 15492 return QDF_STATUS_E_FAILURE; 15493 } 15494 15495 if ((num_2g_reg_rules > MAX_REG_RULES) || 15496 (num_5g_reg_rules > MAX_REG_RULES)) { 15497 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 15498 num_2g_reg_rules, num_5g_reg_rules); 15499 return QDF_STATUS_E_FAILURE; 15500 } 15501 15502 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 15503 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 15504 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 15505 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", 15506 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15507 num_6g_reg_rules_ap[REG_INDOOR_AP], 15508 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15509 return QDF_STATUS_E_FAILURE; 15510 } 15511 15512 if (param_buf->num_reg_rule_array > 15513 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 15514 sizeof(*ext_wmi_reg_rule)) { 15515 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 15516 param_buf->num_reg_rule_array); 15517 return QDF_STATUS_E_FAILURE; 15518 } 15519 15520 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 15521 REG_ALPHA2_LEN); 15522 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 15523 reg_info->phybitmap = convert_phybitmap_tlv( 15524 ext_chan_list_event_hdr->phybitmap); 15525 reg_info->offload_enabled = true; 15526 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 15527 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15528 wmi_handle, ext_chan_list_event_hdr->phy_id); 15529 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 15530 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 15531 15532 reg_info->status_code = 15533 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 15534 status_code); 15535 15536 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 15537 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 15538 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 15539 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 15540 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 15541 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 15542 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 15543 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 15544 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 15545 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 15546 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 15547 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 15548 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15549 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 15550 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 15551 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 15552 15553 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15554 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15555 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 15556 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 15557 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 15558 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 15559 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 15560 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 15561 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 15562 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15563 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 15564 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 15565 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 15566 } 15567 15568 wmi_debug("num_phys = %u and phy_id = %u", 15569 reg_info->num_phy, reg_info->phy_id); 15570 15571 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 15572 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 15573 reg_info->max_bw_2g, reg_info->min_bw_5g, 15574 reg_info->max_bw_5g); 15575 15576 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", 15577 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 15578 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 15579 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 15580 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 15581 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 15582 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 15583 15584 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", 15585 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15586 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15587 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15588 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15589 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 15590 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15591 15592 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", 15593 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15594 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15595 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15596 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15597 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 15598 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15599 15600 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 15601 num_2g_reg_rules, num_5g_reg_rules); 15602 15603 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 15604 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 15605 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 15606 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 15607 15608 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", 15609 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 15610 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 15611 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 15612 15613 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", 15614 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 15615 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 15616 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 15617 15618 ext_wmi_reg_rule = 15619 (wmi_regulatory_rule_ext_struct *) 15620 ((uint8_t *)ext_chan_list_event_hdr + 15621 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 15622 WMI_TLV_HDR_SIZE); 15623 reg_info->reg_rules_2g_ptr = 15624 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 15625 ext_wmi_reg_rule); 15626 ext_wmi_reg_rule += num_2g_reg_rules; 15627 for (i = 0; i < num_2g_reg_rules; i++) { 15628 if (!reg_info->reg_rules_2g_ptr) 15629 break; 15630 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 15631 i, reg_info->reg_rules_2g_ptr[i].start_freq, 15632 reg_info->reg_rules_2g_ptr[i].end_freq, 15633 reg_info->reg_rules_2g_ptr[i].flags); 15634 } 15635 reg_info->reg_rules_5g_ptr = 15636 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 15637 ext_wmi_reg_rule); 15638 ext_wmi_reg_rule += num_5g_reg_rules; 15639 for (i = 0; i < num_5g_reg_rules; i++) { 15640 if (!reg_info->reg_rules_5g_ptr) 15641 break; 15642 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 15643 i, reg_info->reg_rules_5g_ptr[i].start_freq, 15644 reg_info->reg_rules_5g_ptr[i].end_freq, 15645 reg_info->reg_rules_5g_ptr[i].flags); 15646 } 15647 15648 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 15649 reg_info->reg_rules_6g_ap_ptr[i] = 15650 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 15651 ext_wmi_reg_rule); 15652 15653 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 15654 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 15655 if (!reg_info->reg_rules_6g_ap_ptr[i]) 15656 break; 15657 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 15658 i, j, 15659 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 15660 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 15661 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 15662 } 15663 } 15664 15665 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 15666 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15667 reg_info->reg_rules_6g_client_ptr[j][i] = 15668 create_ext_reg_rules_from_wmi( 15669 num_6g_reg_rules_client[j][i], 15670 ext_wmi_reg_rule); 15671 15672 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 15673 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 15674 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 15675 break; 15676 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 15677 j, i, k, 15678 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 15679 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 15680 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 15681 } 15682 } 15683 } 15684 15685 reg_info->client_type = ext_chan_list_event_hdr->client_type; 15686 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 15687 reg_info->unspecified_ap_usable = 15688 ext_chan_list_event_hdr->unspecified_ap_usable; 15689 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 15690 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 15691 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 15692 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 15693 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 15694 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 15695 15696 wmi_debug("client type %d", reg_info->client_type); 15697 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 15698 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 15699 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 15700 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 15701 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 15702 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 15703 15704 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 15705 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 15706 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 15707 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 15708 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 15709 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 15710 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 15711 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 15712 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 15713 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 15714 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 15715 } 15716 15717 reg_info->domain_code_6g_super_id = 15718 ext_chan_list_event_hdr->domain_code_6g_super_id; 15719 15720 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 15721 ext_wmi_reg_rule, ext_wmi_chan_priority, 15722 evt_buf, reg_info, len); 15723 if (status != QDF_STATUS_SUCCESS) 15724 return status; 15725 15726 wmi_debug("processed regulatory extended channel list"); 15727 15728 return QDF_STATUS_SUCCESS; 15729 } 15730 15731 #ifdef CONFIG_AFC_SUPPORT 15732 /** 15733 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 15734 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 15735 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 15736 * an index pointer required to store the current index of 15737 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 15738 * @chan_eirp_info: pointer to chan_eirp_info 15739 * @num_chans: Number of channels 15740 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 15741 * @index: Pointer to index 15742 * 15743 * Return: void 15744 */ 15745 static void 15746 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 15747 uint8_t num_chans, 15748 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 15749 uint8_t *index) 15750 { 15751 uint8_t chan_idx; 15752 15753 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 15754 chan_eirp_info[chan_idx].cfi = 15755 chan_eirp_power_info_hdr[*index].channel_cfi; 15756 chan_eirp_info[chan_idx].eirp_power = 15757 chan_eirp_power_info_hdr[*index].eirp_pwr; 15758 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 15759 chan_idx, 15760 chan_eirp_info[chan_idx].cfi, 15761 chan_eirp_info[chan_idx].eirp_power); 15762 } 15763 } 15764 15765 /** 15766 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 15767 * to the internal buffer afc_chan_info. 15768 * @afc_chan_info: pointer to afc_chan_info 15769 * @num_chan_objs: Number of channel objects 15770 * @channel_info_hdr: Pointer to channel_info_hdr 15771 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 15772 * 15773 * Return: void 15774 */ 15775 static void 15776 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 15777 uint8_t num_chan_objs, 15778 wmi_6g_afc_channel_info *channel_info_hdr, 15779 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 15780 { 15781 uint8_t count; 15782 uint8_t src_pwr_index = 0; 15783 15784 for (count = 0; count < num_chan_objs; count++) { 15785 afc_chan_info[count].global_opclass = 15786 channel_info_hdr[count].global_operating_class; 15787 afc_chan_info[count].num_chans = 15788 channel_info_hdr[count].num_channels; 15789 wmi_debug("Chan object count = %d global opclasss = %d", 15790 count, 15791 afc_chan_info[count].global_opclass); 15792 wmi_debug("Number of Channel EIRP objects = %d", 15793 afc_chan_info[count].num_chans); 15794 15795 if (afc_chan_info[count].num_chans > 0) { 15796 struct chan_eirp_obj *chan_eirp_info; 15797 15798 chan_eirp_info = 15799 qdf_mem_malloc(afc_chan_info[count].num_chans * 15800 sizeof(*chan_eirp_info)); 15801 15802 if (!chan_eirp_info) 15803 return; 15804 15805 copy_afc_chan_eirp_info(chan_eirp_info, 15806 afc_chan_info[count].num_chans, 15807 chan_eirp_power_info_hdr, 15808 &src_pwr_index); 15809 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 15810 } else { 15811 wmi_err("Number of channels is zero in object idx %d", 15812 count); 15813 } 15814 } 15815 } 15816 15817 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 15818 uint8_t num_freq_objs, 15819 wmi_6g_afc_frequency_info *freq_info_hdr) 15820 { 15821 uint8_t count; 15822 15823 for (count = 0; count < num_freq_objs; count++) { 15824 afc_freq_info[count].low_freq = 15825 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 15826 afc_freq_info[count].high_freq = 15827 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 15828 afc_freq_info[count].max_psd = 15829 freq_info_hdr[count].psd_power_info; 15830 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 15831 count, 15832 afc_freq_info[count].low_freq, 15833 afc_freq_info[count].high_freq, 15834 afc_freq_info[count].max_psd); 15835 } 15836 } 15837 15838 /** 15839 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 15840 * the power event info from the WMI AFC event buffer to the internal buffer 15841 * power_info. 15842 * @power_info: pointer to power_info 15843 * @afc_power_event_hdr: pointer to afc_power_event_hdr 15844 * 15845 * Return: void 15846 */ 15847 static void 15848 copy_afc_event_fixed_hdr_power_info( 15849 struct reg_fw_afc_power_event *power_info, 15850 wmi_afc_power_event_param *afc_power_event_hdr) 15851 { 15852 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 15853 power_info->resp_id = afc_power_event_hdr->resp_id; 15854 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 15855 power_info->afc_wfa_version = 15856 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 15857 power_info->afc_wfa_version |= 15858 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 15859 15860 power_info->avail_exp_time_d = 15861 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 15862 power_info->avail_exp_time_d |= 15863 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 15864 power_info->avail_exp_time_d |= 15865 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 15866 15867 power_info->avail_exp_time_t = 15868 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 15869 power_info->avail_exp_time_t |= 15870 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 15871 power_info->avail_exp_time_t |= 15872 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 15873 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 15874 power_info->fw_status_code, 15875 power_info->resp_id, 15876 power_info->serv_resp_code); 15877 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 15878 power_info->afc_wfa_version, 15879 power_info->avail_exp_time_d, 15880 power_info->avail_exp_time_t); 15881 } 15882 15883 /** 15884 * copy_power_event() - Copy the power event parameters from the AFC event 15885 * buffer to the power_info within the afc_info. 15886 * @afc_info: pointer to afc_info 15887 * @param_buf: pointer to param_buf 15888 * 15889 * Return: void 15890 */ 15891 static void copy_power_event(struct afc_regulatory_info *afc_info, 15892 WMI_AFC_EVENTID_param_tlvs *param_buf) 15893 { 15894 struct reg_fw_afc_power_event *power_info; 15895 wmi_afc_power_event_param *afc_power_event_hdr; 15896 struct afc_freq_obj *afc_freq_info; 15897 15898 power_info = qdf_mem_malloc(sizeof(*power_info)); 15899 15900 if (!power_info) 15901 return; 15902 15903 afc_power_event_hdr = param_buf->afc_power_event_param; 15904 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 15905 afc_info->power_info = power_info; 15906 15907 power_info->num_freq_objs = param_buf->num_freq_info_array; 15908 wmi_debug("Number of frequency objects = %d", 15909 power_info->num_freq_objs); 15910 if (power_info->num_freq_objs > 0) { 15911 wmi_6g_afc_frequency_info *freq_info_hdr; 15912 15913 freq_info_hdr = param_buf->freq_info_array; 15914 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 15915 sizeof(*afc_freq_info)); 15916 15917 if (!afc_freq_info) 15918 return; 15919 15920 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 15921 freq_info_hdr); 15922 power_info->afc_freq_info = afc_freq_info; 15923 } else { 15924 wmi_err("Number of frequency objects is zero"); 15925 } 15926 15927 power_info->num_chan_objs = param_buf->num_channel_info_array; 15928 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 15929 if (power_info->num_chan_objs > 0) { 15930 struct afc_chan_obj *afc_chan_info; 15931 wmi_6g_afc_channel_info *channel_info_hdr; 15932 15933 channel_info_hdr = param_buf->channel_info_array; 15934 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 15935 sizeof(*afc_chan_info)); 15936 15937 if (!afc_chan_info) 15938 return; 15939 15940 copy_afc_chan_obj_info(afc_chan_info, 15941 power_info->num_chan_objs, 15942 channel_info_hdr, 15943 param_buf->chan_eirp_power_info_array); 15944 power_info->afc_chan_info = afc_chan_info; 15945 } else { 15946 wmi_err("Number of channel objects is zero"); 15947 } 15948 } 15949 15950 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 15951 WMI_AFC_EVENTID_param_tlvs *param_buf) 15952 { 15953 struct reg_afc_expiry_event *expiry_info; 15954 15955 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 15956 15957 if (!expiry_info) 15958 return; 15959 15960 expiry_info->request_id = 15961 param_buf->expiry_event_param->request_id; 15962 expiry_info->event_subtype = 15963 param_buf->expiry_event_param->event_subtype; 15964 wmi_debug("Event subtype %d request ID %d", 15965 expiry_info->event_subtype, 15966 expiry_info->request_id); 15967 afc_info->expiry_info = expiry_info; 15968 } 15969 15970 /** 15971 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 15972 * in the AFC event. 'Common' indicates that these parameters are common for 15973 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 15974 * @wmi_handle: wmi handle 15975 * @afc_info: pointer to afc_info 15976 * @event_fixed_hdr: pointer to event_fixed_hdr 15977 * 15978 * Return: void 15979 */ 15980 static void 15981 copy_afc_event_common_info(wmi_unified_t wmi_handle, 15982 struct afc_regulatory_info *afc_info, 15983 wmi_afc_event_fixed_param *event_fixed_hdr) 15984 { 15985 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 15986 wmi_handle, event_fixed_hdr->phy_id); 15987 wmi_debug("phy_id %d", afc_info->phy_id); 15988 afc_info->event_type = event_fixed_hdr->event_type; 15989 } 15990 15991 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 15992 uint8_t *evt_buf, 15993 struct afc_regulatory_info *afc_info, 15994 uint32_t len) 15995 { 15996 WMI_AFC_EVENTID_param_tlvs *param_buf; 15997 wmi_afc_event_fixed_param *event_fixed_hdr; 15998 15999 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 16000 if (!param_buf) { 16001 wmi_err("Invalid AFC event buf"); 16002 return QDF_STATUS_E_FAILURE; 16003 } 16004 16005 event_fixed_hdr = param_buf->fixed_param; 16006 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 16007 wmi_debug("AFC event type %d received", afc_info->event_type); 16008 16009 switch (afc_info->event_type) { 16010 case WMI_AFC_EVENT_POWER_INFO: 16011 copy_power_event(afc_info, param_buf); 16012 break; 16013 case WMI_AFC_EVENT_TIMER_EXPIRY: 16014 copy_expiry_event(afc_info, param_buf); 16015 return QDF_STATUS_SUCCESS; 16016 default: 16017 wmi_err("Invalid event type"); 16018 return QDF_STATUS_E_FAILURE; 16019 } 16020 16021 return QDF_STATUS_SUCCESS; 16022 } 16023 #endif 16024 #endif 16025 16026 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 16027 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16028 struct cur_regulatory_info *reg_info, uint32_t len) 16029 { 16030 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 16031 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 16032 wmi_regulatory_rule_struct *wmi_reg_rule; 16033 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16034 16035 wmi_debug("processing regulatory channel list"); 16036 16037 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 16038 if (!param_buf) { 16039 wmi_err("invalid channel list event buf"); 16040 return QDF_STATUS_E_FAILURE; 16041 } 16042 16043 chan_list_event_hdr = param_buf->fixed_param; 16044 16045 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 16046 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 16047 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16048 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16049 if ((num_2g_reg_rules > MAX_REG_RULES) || 16050 (num_5g_reg_rules > MAX_REG_RULES) || 16051 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 16052 (num_2g_reg_rules + num_5g_reg_rules != 16053 param_buf->num_reg_rule_array)) { 16054 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16055 num_2g_reg_rules, num_5g_reg_rules); 16056 return QDF_STATUS_E_FAILURE; 16057 } 16058 if (param_buf->num_reg_rule_array > 16059 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 16060 sizeof(*wmi_reg_rule)) { 16061 wmi_err_rl("Invalid num_reg_rule_array: %u", 16062 param_buf->num_reg_rule_array); 16063 return QDF_STATUS_E_FAILURE; 16064 } 16065 16066 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 16067 REG_ALPHA2_LEN); 16068 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 16069 reg_info->phybitmap = convert_phybitmap_tlv( 16070 chan_list_event_hdr->phybitmap); 16071 reg_info->offload_enabled = true; 16072 reg_info->num_phy = chan_list_event_hdr->num_phy; 16073 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16074 wmi_handle, chan_list_event_hdr->phy_id); 16075 reg_info->ctry_code = chan_list_event_hdr->country_id; 16076 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 16077 16078 reg_info->status_code = 16079 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 16080 16081 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 16082 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 16083 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 16084 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 16085 16086 wmi_debug("num_phys = %u and phy_id = %u", 16087 reg_info->num_phy, reg_info->phy_id); 16088 16089 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16090 reg_info->alpha2, reg_info->dfs_region, 16091 reg_info->min_bw_2g, reg_info->max_bw_2g, 16092 reg_info->min_bw_5g, reg_info->max_bw_5g); 16093 16094 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16095 num_2g_reg_rules, num_5g_reg_rules); 16096 wmi_reg_rule = 16097 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 16098 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 16099 + WMI_TLV_HDR_SIZE); 16100 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 16101 wmi_reg_rule); 16102 wmi_reg_rule += num_2g_reg_rules; 16103 16104 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 16105 wmi_reg_rule); 16106 16107 wmi_debug("processed regulatory channel list"); 16108 16109 return QDF_STATUS_SUCCESS; 16110 } 16111 16112 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 16113 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16114 struct reg_11d_new_country *reg_11d_country, uint32_t len) 16115 { 16116 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 16117 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 16118 16119 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 16120 if (!param_buf) { 16121 wmi_err("invalid 11d country event buf"); 16122 return QDF_STATUS_E_FAILURE; 16123 } 16124 16125 reg_11d_country_event = param_buf->fixed_param; 16126 16127 qdf_mem_copy(reg_11d_country->alpha2, 16128 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 16129 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 16130 16131 wmi_debug("processed 11d country event, new cc %s", 16132 reg_11d_country->alpha2); 16133 16134 return QDF_STATUS_SUCCESS; 16135 } 16136 16137 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 16138 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16139 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 16140 { 16141 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 16142 wmi_avoid_freq_range_desc *afr_desc; 16143 uint32_t num_freq_ranges, freq_range_idx; 16144 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 16145 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 16146 16147 if (!param_buf) { 16148 wmi_err("Invalid channel avoid event buffer"); 16149 return QDF_STATUS_E_INVAL; 16150 } 16151 16152 afr_fixed_param = param_buf->fixed_param; 16153 if (!afr_fixed_param) { 16154 wmi_err("Invalid channel avoid event fixed param buffer"); 16155 return QDF_STATUS_E_INVAL; 16156 } 16157 16158 if (!ch_avoid_ind) { 16159 wmi_err("Invalid channel avoid indication buffer"); 16160 return QDF_STATUS_E_INVAL; 16161 } 16162 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 16163 wmi_err("no.of freq ranges exceeded the limit"); 16164 return QDF_STATUS_E_INVAL; 16165 } 16166 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 16167 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 16168 afr_fixed_param->num_freq_ranges; 16169 16170 wmi_debug("Channel avoid event received with %d ranges", 16171 num_freq_ranges); 16172 16173 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 16174 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 16175 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 16176 freq_range_idx++) { 16177 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 16178 afr_desc->start_freq; 16179 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 16180 afr_desc->end_freq; 16181 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 16182 freq_range_idx, afr_desc->tlv_header, 16183 afr_desc->start_freq, afr_desc->end_freq); 16184 afr_desc++; 16185 } 16186 16187 return QDF_STATUS_SUCCESS; 16188 } 16189 16190 #ifdef DFS_COMPONENT_ENABLE 16191 /** 16192 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 16193 * @wmi_handle: wma handle 16194 * @evt_buf: event buffer 16195 * @vdev_id: vdev id 16196 * @len: length of buffer 16197 * 16198 * Return: 0 for success or error code 16199 */ 16200 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 16201 uint8_t *evt_buf, 16202 uint32_t *vdev_id, 16203 uint32_t len) 16204 { 16205 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16206 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 16207 16208 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 16209 if (!param_tlvs) { 16210 wmi_err("invalid cac complete event buf"); 16211 return QDF_STATUS_E_FAILURE; 16212 } 16213 16214 cac_event = param_tlvs->fixed_param; 16215 *vdev_id = cac_event->vdev_id; 16216 wmi_debug("processed cac complete event vdev %d", *vdev_id); 16217 16218 return QDF_STATUS_SUCCESS; 16219 } 16220 16221 /** 16222 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 16223 * @wmi_handle: wma handle 16224 * @evt_buf: event buffer 16225 * @vdev_id: vdev id 16226 * @len: length of buffer 16227 * 16228 * Return: 0 for success or error code 16229 */ 16230 static QDF_STATUS 16231 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 16232 uint8_t *evt_buf, 16233 struct vdev_adfs_complete_status *param) 16234 { 16235 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 16236 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 16237 16238 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16239 if (!param_tlvs) { 16240 wmi_err("invalid ocac complete event buf"); 16241 return QDF_STATUS_E_FAILURE; 16242 } 16243 16244 if (!param_tlvs->fixed_param) { 16245 wmi_err("invalid param_tlvs->fixed_param"); 16246 return QDF_STATUS_E_FAILURE; 16247 } 16248 16249 ocac_complete_status = param_tlvs->fixed_param; 16250 param->vdev_id = ocac_complete_status->vdev_id; 16251 param->chan_freq = ocac_complete_status->chan_freq; 16252 param->center_freq1 = ocac_complete_status->center_freq1; 16253 param->center_freq2 = ocac_complete_status->center_freq2; 16254 param->ocac_status = ocac_complete_status->status; 16255 param->chan_width = ocac_complete_status->chan_width; 16256 wmi_debug("processed ocac complete event vdev %d" 16257 " agile chan %d %d width %d status %d", 16258 param->vdev_id, 16259 param->center_freq1, 16260 param->center_freq2, 16261 param->chan_width, 16262 param->ocac_status); 16263 16264 return QDF_STATUS_SUCCESS; 16265 } 16266 16267 /** 16268 * extract_dfs_radar_detection_event_tlv() - extract radar found event 16269 * @wmi_handle: wma handle 16270 * @evt_buf: event buffer 16271 * @radar_found: radar found event info 16272 * @len: length of buffer 16273 * 16274 * Return: 0 for success or error code 16275 */ 16276 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 16277 wmi_unified_t wmi_handle, 16278 uint8_t *evt_buf, 16279 struct radar_found_info *radar_found, 16280 uint32_t len) 16281 { 16282 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 16283 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 16284 16285 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 16286 if (!param_tlv) { 16287 wmi_err("invalid radar detection event buf"); 16288 return QDF_STATUS_E_FAILURE; 16289 } 16290 16291 radar_event = param_tlv->fixed_param; 16292 16293 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 16294 wmi_handle, 16295 radar_event->pdev_id); 16296 16297 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 16298 return QDF_STATUS_E_FAILURE; 16299 16300 radar_found->detection_mode = radar_event->detection_mode; 16301 radar_found->chan_freq = radar_event->chan_freq; 16302 radar_found->chan_width = radar_event->chan_width; 16303 radar_found->detector_id = radar_event->detector_id; 16304 radar_found->segment_id = radar_event->segment_id; 16305 radar_found->timestamp = radar_event->timestamp; 16306 radar_found->is_chirp = radar_event->is_chirp; 16307 radar_found->freq_offset = radar_event->freq_offset; 16308 radar_found->sidx = radar_event->sidx; 16309 16310 wmi_debug("processed radar found event pdev %d," 16311 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 16312 "chan_width (RSSI) %d,detector_id (false_radar) %d," 16313 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 16314 "is_chirp %d,detection mode %d", 16315 radar_event->pdev_id, radar_found->pdev_id, 16316 radar_event->timestamp, radar_event->chan_freq, 16317 radar_event->chan_width, radar_event->detector_id, 16318 radar_event->freq_offset, radar_event->segment_id, 16319 radar_event->sidx, radar_event->is_chirp, 16320 radar_event->detection_mode); 16321 16322 return QDF_STATUS_SUCCESS; 16323 } 16324 16325 #ifdef MOBILE_DFS_SUPPORT 16326 /** 16327 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 16328 * @wmi_handle: wma handle 16329 * @evt_buf: event buffer 16330 * @wlan_radar_event: Pointer to struct radar_event_info 16331 * @len: length of buffer 16332 * 16333 * Return: QDF_STATUS 16334 */ 16335 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16336 wmi_unified_t wmi_handle, 16337 uint8_t *evt_buf, 16338 struct radar_event_info *wlan_radar_event, 16339 uint32_t len) 16340 { 16341 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 16342 wmi_dfs_radar_event_fixed_param *radar_event; 16343 16344 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 16345 if (!param_tlv) { 16346 wmi_err("invalid wlan radar event buf"); 16347 return QDF_STATUS_E_FAILURE; 16348 } 16349 16350 radar_event = param_tlv->fixed_param; 16351 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 16352 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 16353 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 16354 wlan_radar_event->rssi = radar_event->rssi; 16355 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 16356 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 16357 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 16358 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 16359 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 16360 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 16361 if (radar_event->pulse_flags & 16362 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 16363 wlan_radar_event->is_psidx_diff_valid = true; 16364 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 16365 } else { 16366 wlan_radar_event->is_psidx_diff_valid = false; 16367 } 16368 16369 wlan_radar_event->pdev_id = radar_event->pdev_id; 16370 16371 return QDF_STATUS_SUCCESS; 16372 } 16373 #else 16374 static QDF_STATUS extract_wlan_radar_event_info_tlv( 16375 wmi_unified_t wmi_handle, 16376 uint8_t *evt_buf, 16377 struct radar_event_info *wlan_radar_event, 16378 uint32_t len) 16379 { 16380 return QDF_STATUS_SUCCESS; 16381 } 16382 #endif 16383 #endif 16384 16385 /** 16386 * send_get_rcpi_cmd_tlv() - send request for rcpi value 16387 * @wmi_handle: wmi handle 16388 * @get_rcpi_param: rcpi params 16389 * 16390 * Return: QDF status 16391 */ 16392 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 16393 struct rcpi_req *get_rcpi_param) 16394 { 16395 wmi_buf_t buf; 16396 wmi_request_rcpi_cmd_fixed_param *cmd; 16397 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 16398 16399 buf = wmi_buf_alloc(wmi_handle, len); 16400 if (!buf) 16401 return QDF_STATUS_E_NOMEM; 16402 16403 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 16404 WMITLV_SET_HDR(&cmd->tlv_header, 16405 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 16406 WMITLV_GET_STRUCT_TLVLEN 16407 (wmi_request_rcpi_cmd_fixed_param)); 16408 16409 cmd->vdev_id = get_rcpi_param->vdev_id; 16410 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 16411 &cmd->peer_macaddr); 16412 16413 switch (get_rcpi_param->measurement_type) { 16414 16415 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16416 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16417 break; 16418 16419 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 16420 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 16421 break; 16422 16423 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16424 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16425 break; 16426 16427 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 16428 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 16429 break; 16430 16431 default: 16432 /* 16433 * invalid rcpi measurement type, fall back to 16434 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 16435 */ 16436 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16437 break; 16438 } 16439 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 16440 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 16441 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16442 WMI_REQUEST_RCPI_CMDID)) { 16443 16444 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 16445 wmi_buf_free(buf); 16446 return QDF_STATUS_E_FAILURE; 16447 } 16448 16449 return QDF_STATUS_SUCCESS; 16450 } 16451 16452 /** 16453 * extract_rcpi_response_event_tlv() - Extract RCPI event params 16454 * @wmi_handle: wmi handle 16455 * @evt_buf: pointer to event buffer 16456 * @res: pointer to hold rcpi response from firmware 16457 * 16458 * Return: QDF_STATUS_SUCCESS for successful event parse 16459 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 16460 */ 16461 static QDF_STATUS 16462 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 16463 void *evt_buf, struct rcpi_res *res) 16464 { 16465 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 16466 wmi_update_rcpi_event_fixed_param *event; 16467 16468 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 16469 if (!param_buf) { 16470 wmi_err("Invalid rcpi event"); 16471 return QDF_STATUS_E_INVAL; 16472 } 16473 16474 event = param_buf->fixed_param; 16475 res->vdev_id = event->vdev_id; 16476 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 16477 16478 switch (event->measurement_type) { 16479 16480 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 16481 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 16482 break; 16483 16484 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 16485 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 16486 break; 16487 16488 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 16489 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 16490 break; 16491 16492 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 16493 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 16494 break; 16495 16496 default: 16497 wmi_err("Invalid rcpi measurement type from firmware"); 16498 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 16499 return QDF_STATUS_E_FAILURE; 16500 } 16501 16502 if (event->status) 16503 return QDF_STATUS_E_FAILURE; 16504 else 16505 return QDF_STATUS_SUCCESS; 16506 } 16507 16508 /** 16509 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 16510 * host to target defines. For legacy there is not conversion 16511 * required. Just return pdev_id as it is. 16512 * @param pdev_id: host pdev_id to be converted. 16513 * Return: target pdev_id after conversion. 16514 */ 16515 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 16516 wmi_unified_t wmi_handle, 16517 uint32_t pdev_id) 16518 { 16519 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 16520 return WMI_PDEV_ID_SOC; 16521 16522 /*No conversion required*/ 16523 return pdev_id; 16524 } 16525 16526 /** 16527 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 16528 * target to host defines. For legacy there is not conversion 16529 * required. Just return pdev_id as it is. 16530 * @param pdev_id: target pdev_id to be converted. 16531 * Return: host pdev_id after conversion. 16532 */ 16533 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 16534 wmi_unified_t wmi_handle, 16535 uint32_t pdev_id) 16536 { 16537 /*No conversion required*/ 16538 return pdev_id; 16539 } 16540 16541 /** 16542 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 16543 * host to target defines. For legacy there is not conversion 16544 * required. Just return phy_id as it is. 16545 * @param pdev_id: host phy_id to be converted. 16546 * Return: target phy_id after conversion. 16547 */ 16548 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 16549 wmi_unified_t wmi_handle, 16550 uint32_t phy_id) 16551 { 16552 /*No conversion required*/ 16553 return phy_id; 16554 } 16555 16556 /** 16557 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 16558 * target to host defines. For legacy there is not conversion 16559 * required. Just return phy_id as it is. 16560 * @param pdev_id: target phy_id to be converted. 16561 * Return: host phy_id after conversion. 16562 */ 16563 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 16564 wmi_unified_t wmi_handle, 16565 uint32_t phy_id) 16566 { 16567 /*No conversion required*/ 16568 return phy_id; 16569 } 16570 16571 /** 16572 * send_set_country_cmd_tlv() - WMI scan channel list function 16573 * @param wmi_handle : handle to WMI. 16574 * @param param : pointer to hold scan channel list parameter 16575 * 16576 * Return: 0 on success and -ve on failure. 16577 */ 16578 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 16579 struct set_country *params) 16580 { 16581 wmi_buf_t buf; 16582 QDF_STATUS qdf_status; 16583 wmi_set_current_country_cmd_fixed_param *cmd; 16584 uint16_t len = sizeof(*cmd); 16585 uint8_t pdev_id = params->pdev_id; 16586 16587 buf = wmi_buf_alloc(wmi_handle, len); 16588 if (!buf) { 16589 qdf_status = QDF_STATUS_E_NOMEM; 16590 goto end; 16591 } 16592 16593 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 16594 WMITLV_SET_HDR(&cmd->tlv_header, 16595 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 16596 WMITLV_GET_STRUCT_TLVLEN 16597 (wmi_set_current_country_cmd_fixed_param)); 16598 16599 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 16600 wmi_handle, 16601 pdev_id); 16602 wmi_debug("setting current country to %s and target pdev_id = %u", 16603 params->country, cmd->pdev_id); 16604 16605 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 16606 16607 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 16608 qdf_status = wmi_unified_cmd_send(wmi_handle, 16609 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 16610 16611 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16612 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 16613 wmi_buf_free(buf); 16614 } 16615 16616 end: 16617 return qdf_status; 16618 } 16619 16620 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 16621 WMI_SET_BITS(alpha, 0, 8, val0); \ 16622 WMI_SET_BITS(alpha, 8, 8, val1); \ 16623 WMI_SET_BITS(alpha, 16, 8, val2); \ 16624 } while (0) 16625 16626 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 16627 uint8_t pdev_id, struct cc_regdmn_s *rd) 16628 { 16629 wmi_set_init_country_cmd_fixed_param *cmd; 16630 uint16_t len; 16631 wmi_buf_t buf; 16632 int ret; 16633 16634 len = sizeof(wmi_set_init_country_cmd_fixed_param); 16635 buf = wmi_buf_alloc(wmi_handle, len); 16636 if (!buf) 16637 return QDF_STATUS_E_NOMEM; 16638 16639 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 16640 WMITLV_SET_HDR(&cmd->tlv_header, 16641 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 16642 WMITLV_GET_STRUCT_TLVLEN 16643 (wmi_set_init_country_cmd_fixed_param)); 16644 16645 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 16646 wmi_handle, 16647 pdev_id); 16648 16649 if (rd->flags == CC_IS_SET) { 16650 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 16651 cmd->country_code.country_id = rd->cc.country_code; 16652 } else if (rd->flags == ALPHA_IS_SET) { 16653 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 16654 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 16655 rd->cc.alpha[0], 16656 rd->cc.alpha[1], 16657 rd->cc.alpha[2]); 16658 } else if (rd->flags == REGDMN_IS_SET) { 16659 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 16660 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 16661 rd->cc.regdmn.reg_2g_5g_pair_id); 16662 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 16663 rd->cc.regdmn.sixg_superdmn_id); 16664 } 16665 16666 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 16667 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16668 WMI_SET_INIT_COUNTRY_CMDID); 16669 if (ret) { 16670 wmi_err("Failed to config wow wakeup event"); 16671 wmi_buf_free(buf); 16672 return QDF_STATUS_E_FAILURE; 16673 } 16674 16675 return QDF_STATUS_SUCCESS; 16676 } 16677 16678 /** 16679 * send_obss_detection_cfg_cmd_tlv() - send obss detection 16680 * configurations to firmware. 16681 * @wmi_handle: wmi handle 16682 * @obss_cfg_param: obss detection configurations 16683 * 16684 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 16685 * 16686 * Return: QDF_STATUS 16687 */ 16688 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 16689 struct wmi_obss_detection_cfg_param *obss_cfg_param) 16690 { 16691 wmi_buf_t buf; 16692 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 16693 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 16694 16695 buf = wmi_buf_alloc(wmi_handle, len); 16696 if (!buf) 16697 return QDF_STATUS_E_NOMEM; 16698 16699 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 16700 WMITLV_SET_HDR(&cmd->tlv_header, 16701 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 16702 WMITLV_GET_STRUCT_TLVLEN 16703 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 16704 16705 cmd->vdev_id = obss_cfg_param->vdev_id; 16706 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 16707 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 16708 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 16709 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 16710 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 16711 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 16712 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 16713 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 16714 16715 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 16716 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16717 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 16718 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 16719 wmi_buf_free(buf); 16720 return QDF_STATUS_E_FAILURE; 16721 } 16722 16723 return QDF_STATUS_SUCCESS; 16724 } 16725 16726 /** 16727 * extract_obss_detection_info_tlv() - Extract obss detection info 16728 * received from firmware. 16729 * @evt_buf: pointer to event buffer 16730 * @obss_detection: Pointer to hold obss detection info 16731 * 16732 * Return: QDF_STATUS 16733 */ 16734 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 16735 struct wmi_obss_detect_info 16736 *obss_detection) 16737 { 16738 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 16739 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 16740 16741 if (!obss_detection) { 16742 wmi_err("Invalid obss_detection event buffer"); 16743 return QDF_STATUS_E_INVAL; 16744 } 16745 16746 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 16747 if (!param_buf) { 16748 wmi_err("Invalid evt_buf"); 16749 return QDF_STATUS_E_INVAL; 16750 } 16751 16752 fix_param = param_buf->fixed_param; 16753 obss_detection->vdev_id = fix_param->vdev_id; 16754 obss_detection->matched_detection_masks = 16755 fix_param->matched_detection_masks; 16756 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 16757 &obss_detection->matched_bssid_addr[0]); 16758 switch (fix_param->reason) { 16759 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 16760 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 16761 break; 16762 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 16763 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 16764 break; 16765 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 16766 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 16767 break; 16768 default: 16769 wmi_err("Invalid reason: %d", fix_param->reason); 16770 return QDF_STATUS_E_INVAL; 16771 } 16772 16773 return QDF_STATUS_SUCCESS; 16774 } 16775 16776 /** 16777 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 16778 * @wmi_handle: wmi handle 16779 * @params: pointer to request structure 16780 * 16781 * Return: QDF_STATUS 16782 */ 16783 static QDF_STATUS 16784 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 16785 struct wmi_roam_scan_stats_req *params) 16786 { 16787 wmi_buf_t buf; 16788 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 16789 WMITLV_TAG_ID tag; 16790 uint32_t size; 16791 uint32_t len = sizeof(*cmd); 16792 16793 buf = wmi_buf_alloc(wmi_handle, len); 16794 if (!buf) 16795 return QDF_STATUS_E_FAILURE; 16796 16797 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 16798 16799 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 16800 size = WMITLV_GET_STRUCT_TLVLEN( 16801 wmi_request_roam_scan_stats_cmd_fixed_param); 16802 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 16803 16804 cmd->vdev_id = params->vdev_id; 16805 16806 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 16807 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16808 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 16809 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 16810 wmi_buf_free(buf); 16811 return QDF_STATUS_E_FAILURE; 16812 } 16813 16814 return QDF_STATUS_SUCCESS; 16815 } 16816 16817 /** 16818 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 16819 * channel list from firmware 16820 * @wmi_handle: wmi handler 16821 * @vdev_id: vdev id 16822 * 16823 * Return: QDF_STATUS 16824 */ 16825 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 16826 uint32_t vdev_id) 16827 { 16828 wmi_buf_t buf; 16829 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 16830 uint16_t len = sizeof(*cmd); 16831 int ret; 16832 16833 buf = wmi_buf_alloc(wmi_handle, len); 16834 if (!buf) { 16835 wmi_err("Failed to allocate wmi buffer"); 16836 return QDF_STATUS_E_NOMEM; 16837 } 16838 16839 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 16840 wmi_buf_data(buf); 16841 WMITLV_SET_HDR(&cmd->tlv_header, 16842 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 16843 WMITLV_GET_STRUCT_TLVLEN( 16844 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 16845 cmd->vdev_id = vdev_id; 16846 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 16847 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16848 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 16849 if (QDF_IS_STATUS_ERROR(ret)) { 16850 wmi_err("Failed to send get roam scan channels request = %d", 16851 ret); 16852 wmi_buf_free(buf); 16853 } 16854 return ret; 16855 } 16856 16857 /** 16858 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 16859 * @wmi_handle: wmi handle 16860 * @evt_buf: pointer to event buffer 16861 * @vdev_id: output pointer to hold vdev id 16862 * @res_param: output pointer to hold the allocated response 16863 * 16864 * Return: QDF_STATUS 16865 */ 16866 static QDF_STATUS 16867 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16868 uint32_t *vdev_id, 16869 struct wmi_roam_scan_stats_res **res_param) 16870 { 16871 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 16872 wmi_roam_scan_stats_event_fixed_param *fixed_param; 16873 uint32_t *client_id = NULL; 16874 wmi_roaming_timestamp *timestamp = NULL; 16875 uint32_t *num_channels = NULL; 16876 uint32_t *chan_info = NULL; 16877 wmi_mac_addr *old_bssid = NULL; 16878 uint32_t *is_roaming_success = NULL; 16879 wmi_mac_addr *new_bssid = NULL; 16880 uint32_t *num_roam_candidates = NULL; 16881 wmi_roam_scan_trigger_reason *roam_reason = NULL; 16882 wmi_mac_addr *bssid = NULL; 16883 uint32_t *score = NULL; 16884 uint32_t *channel = NULL; 16885 uint32_t *rssi = NULL; 16886 int chan_idx = 0, cand_idx = 0; 16887 uint32_t total_len; 16888 struct wmi_roam_scan_stats_res *res; 16889 uint32_t i, j; 16890 uint32_t num_scans, scan_param_size; 16891 16892 *res_param = NULL; 16893 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 16894 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 16895 if (!param_buf) { 16896 wmi_err("Invalid roam scan stats event"); 16897 return QDF_STATUS_E_INVAL; 16898 } 16899 16900 fixed_param = param_buf->fixed_param; 16901 16902 num_scans = fixed_param->num_roam_scans; 16903 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 16904 *vdev_id = fixed_param->vdev_id; 16905 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 16906 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 16907 num_scans, WMI_ROAM_SCAN_STATS_MAX); 16908 return QDF_STATUS_E_INVAL; 16909 } 16910 16911 total_len = sizeof(*res) + num_scans * scan_param_size; 16912 16913 res = qdf_mem_malloc(total_len); 16914 if (!res) 16915 return QDF_STATUS_E_NOMEM; 16916 16917 if (!num_scans) { 16918 *res_param = res; 16919 return QDF_STATUS_SUCCESS; 16920 } 16921 16922 if (param_buf->client_id && 16923 param_buf->num_client_id == num_scans) 16924 client_id = param_buf->client_id; 16925 16926 if (param_buf->timestamp && 16927 param_buf->num_timestamp == num_scans) 16928 timestamp = param_buf->timestamp; 16929 16930 if (param_buf->old_bssid && 16931 param_buf->num_old_bssid == num_scans) 16932 old_bssid = param_buf->old_bssid; 16933 16934 if (param_buf->new_bssid && 16935 param_buf->num_new_bssid == num_scans) 16936 new_bssid = param_buf->new_bssid; 16937 16938 if (param_buf->is_roaming_success && 16939 param_buf->num_is_roaming_success == num_scans) 16940 is_roaming_success = param_buf->is_roaming_success; 16941 16942 if (param_buf->roam_reason && 16943 param_buf->num_roam_reason == num_scans) 16944 roam_reason = param_buf->roam_reason; 16945 16946 if (param_buf->num_channels && 16947 param_buf->num_num_channels == num_scans) { 16948 uint32_t count, chan_info_sum = 0; 16949 16950 num_channels = param_buf->num_channels; 16951 for (count = 0; count < param_buf->num_num_channels; count++) { 16952 if (param_buf->num_channels[count] > 16953 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 16954 wmi_err_rl("%u exceeded max scan channels %u", 16955 param_buf->num_channels[count], 16956 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 16957 goto error; 16958 } 16959 chan_info_sum += param_buf->num_channels[count]; 16960 } 16961 16962 if (param_buf->chan_info && 16963 param_buf->num_chan_info == chan_info_sum) 16964 chan_info = param_buf->chan_info; 16965 } 16966 16967 if (param_buf->num_roam_candidates && 16968 param_buf->num_num_roam_candidates == num_scans) { 16969 uint32_t cnt, roam_cand_sum = 0; 16970 16971 num_roam_candidates = param_buf->num_roam_candidates; 16972 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 16973 if (param_buf->num_roam_candidates[cnt] > 16974 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 16975 wmi_err_rl("%u exceeded max scan cand %u", 16976 param_buf->num_roam_candidates[cnt], 16977 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 16978 goto error; 16979 } 16980 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 16981 } 16982 16983 if (param_buf->bssid && 16984 param_buf->num_bssid == roam_cand_sum) 16985 bssid = param_buf->bssid; 16986 16987 if (param_buf->score && 16988 param_buf->num_score == roam_cand_sum) 16989 score = param_buf->score; 16990 16991 if (param_buf->channel && 16992 param_buf->num_channel == roam_cand_sum) 16993 channel = param_buf->channel; 16994 16995 if (param_buf->rssi && 16996 param_buf->num_rssi == roam_cand_sum) 16997 rssi = param_buf->rssi; 16998 } 16999 17000 res->num_roam_scans = num_scans; 17001 for (i = 0; i < num_scans; i++) { 17002 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 17003 17004 if (timestamp) 17005 roam->time_stamp = timestamp[i].lower32bit | 17006 (timestamp[i].upper32bit << 31); 17007 17008 if (client_id) 17009 roam->client_id = client_id[i]; 17010 17011 if (num_channels) { 17012 roam->num_scan_chans = num_channels[i]; 17013 if (chan_info) { 17014 for (j = 0; j < num_channels[i]; j++) 17015 roam->scan_freqs[j] = 17016 chan_info[chan_idx++]; 17017 } 17018 } 17019 17020 if (is_roaming_success) 17021 roam->is_roam_successful = is_roaming_success[i]; 17022 17023 if (roam_reason) { 17024 roam->trigger_id = roam_reason[i].trigger_id; 17025 roam->trigger_value = roam_reason[i].trigger_value; 17026 } 17027 17028 if (num_roam_candidates) { 17029 roam->num_roam_candidates = num_roam_candidates[i]; 17030 17031 for (j = 0; j < num_roam_candidates[i]; j++) { 17032 if (score) 17033 roam->cand[j].score = score[cand_idx]; 17034 if (rssi) 17035 roam->cand[j].rssi = rssi[cand_idx]; 17036 if (channel) 17037 roam->cand[j].freq = 17038 channel[cand_idx]; 17039 17040 if (bssid) 17041 WMI_MAC_ADDR_TO_CHAR_ARRAY( 17042 &bssid[cand_idx], 17043 roam->cand[j].bssid); 17044 17045 cand_idx++; 17046 } 17047 } 17048 17049 if (old_bssid) 17050 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 17051 roam->old_bssid); 17052 17053 if (new_bssid) 17054 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 17055 roam->new_bssid); 17056 } 17057 17058 *res_param = res; 17059 17060 return QDF_STATUS_SUCCESS; 17061 error: 17062 qdf_mem_free(res); 17063 return QDF_STATUS_E_FAILURE; 17064 } 17065 17066 /** 17067 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 17068 * @wmi_handle: wmi handle 17069 * @evt_buf: pointer to event buffer 17070 * @vdev_id: output pointer to hold vdev id 17071 * @tx_status: output pointer to hold the tx_status 17072 * 17073 * Return: QDF_STATUS 17074 */ 17075 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 17076 void *evt_buf, 17077 uint32_t *vdev_id, 17078 uint32_t *tx_status) { 17079 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 17080 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 17081 17082 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 17083 if (!param_buf) { 17084 wmi_err("Invalid offload bcn tx status event buffer"); 17085 return QDF_STATUS_E_INVAL; 17086 } 17087 17088 bcn_tx_status_event = param_buf->fixed_param; 17089 *vdev_id = bcn_tx_status_event->vdev_id; 17090 *tx_status = bcn_tx_status_event->tx_status; 17091 17092 return QDF_STATUS_SUCCESS; 17093 } 17094 17095 #ifdef WLAN_SUPPORT_GREEN_AP 17096 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 17097 uint8_t *evt_buf, 17098 struct wlan_green_ap_egap_status_info *egap_status_info_params) 17099 { 17100 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 17101 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 17102 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 17103 17104 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 17105 if (!param_buf) { 17106 wmi_err("Invalid EGAP Info status event buffer"); 17107 return QDF_STATUS_E_INVAL; 17108 } 17109 17110 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 17111 param_buf->fixed_param; 17112 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 17113 param_buf->chainmask_list; 17114 17115 if (!egap_info_event || !chainmask_event) { 17116 wmi_err("Invalid EGAP Info event or chainmask event"); 17117 return QDF_STATUS_E_INVAL; 17118 } 17119 17120 egap_status_info_params->status = egap_info_event->status; 17121 egap_status_info_params->mac_id = chainmask_event->mac_id; 17122 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 17123 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 17124 17125 return QDF_STATUS_SUCCESS; 17126 } 17127 #endif 17128 17129 /* 17130 * extract_comb_phyerr_tlv() - extract comb phy error from event 17131 * @wmi_handle: wmi handle 17132 * @evt_buf: pointer to event buffer 17133 * @datalen: data length of event buffer 17134 * @buf_offset: Pointer to hold value of current event buffer offset 17135 * post extraction 17136 * @phyerr: Pointer to hold phyerr 17137 * 17138 * Return: QDF_STATUS 17139 */ 17140 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 17141 void *evt_buf, 17142 uint16_t datalen, 17143 uint16_t *buf_offset, 17144 wmi_host_phyerr_t *phyerr) 17145 { 17146 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 17147 wmi_comb_phyerr_rx_hdr *pe_hdr; 17148 17149 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 17150 if (!param_tlvs) { 17151 wmi_debug("Received null data from FW"); 17152 return QDF_STATUS_E_FAILURE; 17153 } 17154 17155 pe_hdr = param_tlvs->hdr; 17156 if (!pe_hdr) { 17157 wmi_debug("Received Data PE Header is NULL"); 17158 return QDF_STATUS_E_FAILURE; 17159 } 17160 17161 /* Ensure it's at least the size of the header */ 17162 if (datalen < sizeof(*pe_hdr)) { 17163 wmi_debug("Expected minimum size %zu, received %d", 17164 sizeof(*pe_hdr), datalen); 17165 return QDF_STATUS_E_FAILURE; 17166 } 17167 17168 phyerr->pdev_id = wmi_handle->ops-> 17169 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 17170 phyerr->tsf64 = pe_hdr->tsf_l32; 17171 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 17172 phyerr->bufp = param_tlvs->bufp; 17173 17174 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 17175 wmi_debug("Invalid buf_len %d, num_bufp %d", 17176 pe_hdr->buf_len, param_tlvs->num_bufp); 17177 return QDF_STATUS_E_FAILURE; 17178 } 17179 17180 phyerr->buf_len = pe_hdr->buf_len; 17181 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 17182 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 17183 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 17184 17185 return QDF_STATUS_SUCCESS; 17186 } 17187 17188 /** 17189 * extract_single_phyerr_tlv() - extract single phy error from event 17190 * @wmi_handle: wmi handle 17191 * @evt_buf: pointer to event buffer 17192 * @datalen: data length of event buffer 17193 * @buf_offset: Pointer to hold value of current event buffer offset 17194 * post extraction 17195 * @phyerr: Pointer to hold phyerr 17196 * 17197 * Return: QDF_STATUS 17198 */ 17199 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 17200 void *evt_buf, 17201 uint16_t datalen, 17202 uint16_t *buf_offset, 17203 wmi_host_phyerr_t *phyerr) 17204 { 17205 wmi_single_phyerr_rx_event *ev; 17206 uint16_t n = *buf_offset; 17207 uint8_t *data = (uint8_t *)evt_buf; 17208 17209 if (n < datalen) { 17210 if ((datalen - n) < sizeof(ev->hdr)) { 17211 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 17212 datalen, n, sizeof(ev->hdr)); 17213 return QDF_STATUS_E_FAILURE; 17214 } 17215 17216 /* 17217 * Obtain a pointer to the beginning of the current event. 17218 * data[0] is the beginning of the WMI payload. 17219 */ 17220 ev = (wmi_single_phyerr_rx_event *)&data[n]; 17221 17222 /* 17223 * Sanity check the buffer length of the event against 17224 * what we currently have. 17225 * 17226 * Since buf_len is 32 bits, we check if it overflows 17227 * a large 32 bit value. It's not 0x7fffffff because 17228 * we increase n by (buf_len + sizeof(hdr)), which would 17229 * in itself cause n to overflow. 17230 * 17231 * If "int" is 64 bits then this becomes a moot point. 17232 */ 17233 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 17234 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 17235 return QDF_STATUS_E_FAILURE; 17236 } 17237 17238 if ((n + ev->hdr.buf_len) > datalen) { 17239 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 17240 n, ev->hdr.buf_len, datalen); 17241 return QDF_STATUS_E_FAILURE; 17242 } 17243 17244 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 17245 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 17246 phyerr->bufp = &ev->bufp[0]; 17247 phyerr->buf_len = ev->hdr.buf_len; 17248 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 17249 17250 /* 17251 * Advance the buffer pointer to the next PHY error. 17252 * buflen is the length of this payload, so we need to 17253 * advance past the current header _AND_ the payload. 17254 */ 17255 n += sizeof(*ev) + ev->hdr.buf_len; 17256 } 17257 *buf_offset = n; 17258 17259 return QDF_STATUS_SUCCESS; 17260 } 17261 17262 /** 17263 * extract_esp_estimation_ev_param_tlv() - extract air time from event 17264 * @wmi_handle: wmi handle 17265 * @evt_buf: pointer to event buffer 17266 * @param: Pointer to hold esp event 17267 * 17268 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 17269 */ 17270 static QDF_STATUS 17271 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 17272 void *evt_buf, 17273 struct esp_estimation_event *param) 17274 { 17275 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 17276 wmi_esp_estimate_event_fixed_param *esp_event; 17277 17278 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 17279 if (!param_buf) { 17280 wmi_err("Invalid ESP Estimate Event buffer"); 17281 return QDF_STATUS_E_INVAL; 17282 } 17283 esp_event = param_buf->fixed_param; 17284 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 17285 17286 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17287 wmi_handle, 17288 esp_event->pdev_id); 17289 17290 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17291 return QDF_STATUS_E_FAILURE; 17292 17293 return QDF_STATUS_SUCCESS; 17294 } 17295 17296 /* 17297 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 17298 * updating bss color change within firmware when AP announces bss color change. 17299 * @wmi_handle: wmi handle 17300 * @vdev_id: vdev ID 17301 * @enable: enable bss color change within firmware 17302 * 17303 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 17304 * 17305 * Return: QDF_STATUS 17306 */ 17307 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 17308 uint32_t vdev_id, 17309 bool enable) 17310 { 17311 wmi_buf_t buf; 17312 wmi_bss_color_change_enable_fixed_param *cmd; 17313 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 17314 17315 buf = wmi_buf_alloc(wmi_handle, len); 17316 if (!buf) 17317 return QDF_STATUS_E_NOMEM; 17318 17319 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 17320 WMITLV_SET_HDR(&cmd->tlv_header, 17321 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 17322 WMITLV_GET_STRUCT_TLVLEN 17323 (wmi_bss_color_change_enable_fixed_param)); 17324 cmd->vdev_id = vdev_id; 17325 cmd->enable = enable; 17326 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 17327 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17328 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 17329 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 17330 wmi_buf_free(buf); 17331 return QDF_STATUS_E_FAILURE; 17332 } 17333 17334 return QDF_STATUS_SUCCESS; 17335 } 17336 17337 /** 17338 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 17339 * configurations to firmware. 17340 * @wmi_handle: wmi handle 17341 * @cfg_param: obss detection configurations 17342 * 17343 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 17344 * 17345 * Return: QDF_STATUS 17346 */ 17347 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 17348 wmi_unified_t wmi_handle, 17349 struct wmi_obss_color_collision_cfg_param *cfg_param) 17350 { 17351 wmi_buf_t buf; 17352 wmi_obss_color_collision_det_config_fixed_param *cmd; 17353 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 17354 17355 buf = wmi_buf_alloc(wmi_handle, len); 17356 if (!buf) 17357 return QDF_STATUS_E_NOMEM; 17358 17359 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 17360 buf); 17361 WMITLV_SET_HDR(&cmd->tlv_header, 17362 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 17363 WMITLV_GET_STRUCT_TLVLEN 17364 (wmi_obss_color_collision_det_config_fixed_param)); 17365 cmd->vdev_id = cfg_param->vdev_id; 17366 cmd->flags = cfg_param->flags; 17367 cmd->current_bss_color = cfg_param->current_bss_color; 17368 cmd->detection_period_ms = cfg_param->detection_period_ms; 17369 cmd->scan_period_ms = cfg_param->scan_period_ms; 17370 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 17371 17372 switch (cfg_param->evt_type) { 17373 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 17374 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 17375 break; 17376 case OBSS_COLOR_COLLISION_DETECTION: 17377 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 17378 break; 17379 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17380 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17381 break; 17382 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 17383 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 17384 break; 17385 default: 17386 wmi_err("Invalid event type: %d", cfg_param->evt_type); 17387 wmi_buf_free(buf); 17388 return QDF_STATUS_E_FAILURE; 17389 } 17390 17391 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 17392 "detection_period_ms: %d scan_period_ms: %d " 17393 "free_slot_expiry_timer_ms: %d", 17394 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 17395 cmd->detection_period_ms, cmd->scan_period_ms, 17396 cmd->free_slot_expiry_time_ms); 17397 17398 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 17399 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17400 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 17401 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 17402 cfg_param->vdev_id); 17403 wmi_buf_free(buf); 17404 return QDF_STATUS_E_FAILURE; 17405 } 17406 17407 return QDF_STATUS_SUCCESS; 17408 } 17409 17410 /** 17411 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 17412 * received from firmware. 17413 * @evt_buf: pointer to event buffer 17414 * @info: Pointer to hold bss collision info 17415 * 17416 * Return: QDF_STATUS 17417 */ 17418 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 17419 struct wmi_obss_color_collision_info *info) 17420 { 17421 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 17422 wmi_obss_color_collision_evt_fixed_param *fix_param; 17423 17424 if (!info) { 17425 wmi_err("Invalid obss color buffer"); 17426 return QDF_STATUS_E_INVAL; 17427 } 17428 17429 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 17430 evt_buf; 17431 if (!param_buf) { 17432 wmi_err("Invalid evt_buf"); 17433 return QDF_STATUS_E_INVAL; 17434 } 17435 17436 fix_param = param_buf->fixed_param; 17437 info->vdev_id = fix_param->vdev_id; 17438 info->obss_color_bitmap_bit0to31 = 17439 fix_param->bss_color_bitmap_bit0to31; 17440 info->obss_color_bitmap_bit32to63 = 17441 fix_param->bss_color_bitmap_bit32to63; 17442 17443 switch (fix_param->evt_type) { 17444 case WMI_BSS_COLOR_COLLISION_DISABLE: 17445 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 17446 break; 17447 case WMI_BSS_COLOR_COLLISION_DETECTION: 17448 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 17449 break; 17450 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 17451 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 17452 break; 17453 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 17454 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 17455 break; 17456 default: 17457 wmi_err("Invalid event type: %d, vdev_id: %d", 17458 fix_param->evt_type, fix_param->vdev_id); 17459 return QDF_STATUS_E_FAILURE; 17460 } 17461 17462 return QDF_STATUS_SUCCESS; 17463 } 17464 17465 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 17466 { 17467 struct wmi_ops *ops = wmi_handle->ops; 17468 17469 ops->send_obss_color_collision_cfg_cmd = 17470 send_obss_color_collision_cfg_cmd_tlv; 17471 ops->extract_obss_color_collision_info = 17472 extract_obss_color_collision_info_tlv; 17473 } 17474 17475 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 17476 static QDF_STATUS 17477 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 17478 struct config_fils_params *param) 17479 { 17480 wmi_buf_t buf; 17481 wmi_enable_fils_cmd_fixed_param *cmd; 17482 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 17483 17484 buf = wmi_buf_alloc(wmi_handle, len); 17485 if (!buf) 17486 return QDF_STATUS_E_NOMEM; 17487 17488 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 17489 buf); 17490 WMITLV_SET_HDR(&cmd->tlv_header, 17491 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 17492 WMITLV_GET_STRUCT_TLVLEN 17493 (wmi_enable_fils_cmd_fixed_param)); 17494 cmd->vdev_id = param->vdev_id; 17495 cmd->fd_period = param->fd_period; 17496 if (param->send_prb_rsp_frame) 17497 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 17498 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 17499 cmd->vdev_id, cmd->fd_period, cmd->flags); 17500 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 17501 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17502 WMI_ENABLE_FILS_CMDID)) { 17503 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 17504 wmi_buf_free(buf); 17505 return QDF_STATUS_E_FAILURE; 17506 } 17507 17508 return QDF_STATUS_SUCCESS; 17509 } 17510 #endif 17511 17512 #ifdef WLAN_MWS_INFO_DEBUGFS 17513 /** 17514 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 17515 * 17516 * @wmi_handle: wmi handle 17517 * @vdev_id: vdev id 17518 * @cmd_id: Coex command id 17519 * 17520 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 17521 * 17522 * Return: QDF_STATUS 17523 */ 17524 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 17525 uint32_t vdev_id, 17526 uint32_t cmd_id) 17527 { 17528 wmi_buf_t buf; 17529 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 17530 uint16_t len = sizeof(*cmd); 17531 int ret; 17532 17533 buf = wmi_buf_alloc(wmi_handle, len); 17534 if (!buf) { 17535 wmi_err("Failed to allocate wmi buffer"); 17536 return QDF_STATUS_E_NOMEM; 17537 } 17538 17539 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 17540 WMITLV_SET_HDR(&cmd->tlv_header, 17541 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 17542 WMITLV_GET_STRUCT_TLVLEN 17543 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 17544 cmd->vdev_id = vdev_id; 17545 cmd->cmd_id = cmd_id; 17546 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 17547 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17548 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 17549 if (QDF_IS_STATUS_ERROR(ret)) { 17550 wmi_err("Failed to send set param command ret = %d", ret); 17551 wmi_buf_free(buf); 17552 } 17553 return ret; 17554 } 17555 #endif 17556 17557 #ifdef FEATURE_MEC_OFFLOAD 17558 static QDF_STATUS 17559 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 17560 struct set_mec_timer_params *param) 17561 { 17562 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 17563 wmi_buf_t buf; 17564 int32_t len = sizeof(*cmd); 17565 17566 buf = wmi_buf_alloc(wmi_handle, len); 17567 if (!buf) { 17568 wmi_err("wmi_buf_alloc failed"); 17569 return QDF_STATUS_E_FAILURE; 17570 } 17571 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 17572 wmi_buf_data(buf); 17573 WMITLV_SET_HDR(&cmd->tlv_header, 17574 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 17575 WMITLV_GET_STRUCT_TLVLEN( 17576 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 17577 cmd->pdev_id = param->pdev_id; 17578 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 17579 17580 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 17581 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17582 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 17583 wmi_err("Failed to set mec aging timer param"); 17584 wmi_buf_free(buf); 17585 return QDF_STATUS_E_FAILURE; 17586 } 17587 17588 return QDF_STATUS_SUCCESS; 17589 } 17590 #endif 17591 17592 #ifdef WIFI_POS_CONVERGED 17593 /** 17594 * extract_oem_response_param_tlv() - Extract oem response params 17595 * @wmi_handle: wmi handle 17596 * @resp_buf: response buffer 17597 * @oem_resp_param: pointer to hold oem response params 17598 * 17599 * Return: QDF_STATUS_SUCCESS on success or proper error code. 17600 */ 17601 static QDF_STATUS 17602 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 17603 struct wmi_oem_response_param *oem_resp_param) 17604 { 17605 uint64_t temp_addr; 17606 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 17607 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 17608 17609 if (!param_buf) { 17610 wmi_err("Invalid OEM response"); 17611 return QDF_STATUS_E_INVAL; 17612 } 17613 17614 if (param_buf->num_data) { 17615 oem_resp_param->num_data1 = param_buf->num_data; 17616 oem_resp_param->data_1 = param_buf->data; 17617 } 17618 17619 if (param_buf->num_data2) { 17620 oem_resp_param->num_data2 = param_buf->num_data2; 17621 oem_resp_param->data_2 = param_buf->data2; 17622 } 17623 17624 if (param_buf->indirect_data) { 17625 oem_resp_param->indirect_data.pdev_id = 17626 param_buf->indirect_data->pdev_id; 17627 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 17628 oem_resp_param->indirect_data.addr = 17629 param_buf->indirect_data->addr_lo + 17630 ((uint64_t)temp_addr << 32); 17631 oem_resp_param->indirect_data.len = 17632 param_buf->indirect_data->len; 17633 } 17634 17635 return QDF_STATUS_SUCCESS; 17636 } 17637 #endif /* WIFI_POS_CONVERGED */ 17638 17639 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 17640 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 17641 17642 static QDF_STATUS 17643 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17644 struct wifi_pos_pasn_peer_data *dst) 17645 { 17646 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 17647 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 17648 wmi_rtt_pasn_peer_create_req_param *buf; 17649 uint8_t security_mode, i; 17650 17651 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 17652 if (!param_buf) { 17653 wmi_err("Invalid peer_create req buffer"); 17654 return QDF_STATUS_E_INVAL; 17655 } 17656 17657 fixed_param = param_buf->fixed_param; 17658 17659 if (param_buf->num_rtt_pasn_peer_param > 17660 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 17661 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 17662 wmi_err("Invalid TLV size"); 17663 return QDF_STATUS_E_INVAL; 17664 } 17665 17666 if (!param_buf->num_rtt_pasn_peer_param || 17667 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 17668 wmi_err("Invalid num TLV:%d", 17669 param_buf->num_rtt_pasn_peer_param); 17670 return QDF_STATUS_E_INVAL; 17671 } 17672 17673 dst->vdev_id = fixed_param->vdev_id; 17674 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 17675 wmi_err("Invalid vdev id:%d", dst->vdev_id); 17676 return QDF_STATUS_E_INVAL; 17677 } 17678 17679 buf = param_buf->rtt_pasn_peer_param; 17680 if (!buf) { 17681 wmi_err("NULL peer param TLV"); 17682 return QDF_STATUS_E_INVAL; 17683 } 17684 17685 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 17686 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 17687 dst->peer_info[i].self_mac.bytes); 17688 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 17689 dst->peer_info[i].peer_mac.bytes); 17690 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 17691 buf->control_flag); 17692 if (security_mode) 17693 dst->peer_info[i].peer_type = 17694 WLAN_WIFI_POS_PASN_SECURE_PEER; 17695 else 17696 dst->peer_info[i].peer_type = 17697 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 17698 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 17699 dst->peer_info[i].is_ltf_keyseed_required = true; 17700 17701 dst->peer_info[i].force_self_mac_usage = 17702 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 17703 buf->control_flag); 17704 dst->num_peers++; 17705 buf++; 17706 } 17707 17708 return QDF_STATUS_SUCCESS; 17709 } 17710 17711 static QDF_STATUS 17712 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17713 struct wifi_pos_pasn_peer_data *dst) 17714 { 17715 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 17716 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 17717 wmi_rtt_pasn_peer_delete_param *buf; 17718 uint8_t i; 17719 17720 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 17721 if (!param_buf) { 17722 wmi_err("Invalid peer_delete evt buffer"); 17723 return QDF_STATUS_E_INVAL; 17724 } 17725 17726 fixed_param = param_buf->fixed_param; 17727 17728 if (param_buf->num_rtt_pasn_peer_param > 17729 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 17730 sizeof(wmi_rtt_pasn_peer_delete_param))) { 17731 wmi_err("Invalid TLV size"); 17732 return QDF_STATUS_E_INVAL; 17733 } 17734 17735 if (!param_buf->num_rtt_pasn_peer_param || 17736 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 17737 wmi_err("Invalid num TLV:%d", 17738 param_buf->num_rtt_pasn_peer_param); 17739 return QDF_STATUS_E_INVAL; 17740 } 17741 17742 dst->vdev_id = fixed_param->vdev_id; 17743 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 17744 wmi_err("Invalid vdev id:%d", dst->vdev_id); 17745 return QDF_STATUS_E_INVAL; 17746 } 17747 17748 buf = param_buf->rtt_pasn_peer_param; 17749 if (!buf) { 17750 wmi_err("NULL peer param TLV"); 17751 return QDF_STATUS_E_INVAL; 17752 } 17753 17754 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 17755 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 17756 dst->peer_info[i].peer_mac.bytes); 17757 dst->peer_info[i].control_flags = buf->control_flag; 17758 17759 dst->num_peers++; 17760 buf++; 17761 } 17762 17763 return QDF_STATUS_SUCCESS; 17764 } 17765 17766 static QDF_STATUS 17767 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 17768 struct wlan_pasn_auth_status *data) 17769 { 17770 QDF_STATUS status; 17771 wmi_buf_t buf; 17772 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 17773 uint8_t *buf_ptr; 17774 uint8_t i; 17775 size_t len = sizeof(*fixed_param) + 17776 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 17777 WMI_TLV_HDR_SIZE; 17778 17779 buf = wmi_buf_alloc(wmi_handle, len); 17780 if (!buf) { 17781 wmi_err("wmi_buf_alloc failed"); 17782 return QDF_STATUS_E_FAILURE; 17783 } 17784 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17785 fixed_param = 17786 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 17787 WMITLV_SET_HDR(&fixed_param->tlv_header, 17788 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 17789 WMITLV_GET_STRUCT_TLVLEN( 17790 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 17791 buf_ptr += sizeof(*fixed_param); 17792 17793 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 17794 (data->num_peers * 17795 sizeof(wmi_rtt_pasn_auth_status_param))); 17796 buf_ptr += WMI_TLV_HDR_SIZE; 17797 17798 for (i = 0; i < data->num_peers; i++) { 17799 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 17800 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 17801 17802 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 17803 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 17804 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 17805 17806 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 17807 &auth_status_tlv->peer_mac_addr); 17808 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 17809 &auth_status_tlv->source_mac_addr); 17810 auth_status_tlv->status = data->auth_status[i].status; 17811 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 17812 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 17813 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 17814 auth_status_tlv->status); 17815 17816 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 17817 } 17818 17819 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 17820 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17821 WMI_RTT_PASN_AUTH_STATUS_CMD); 17822 if (QDF_IS_STATUS_ERROR(status)) { 17823 wmi_err("Failed to send Auth status command ret = %d", status); 17824 wmi_buf_free(buf); 17825 } 17826 17827 return status; 17828 } 17829 17830 static QDF_STATUS 17831 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 17832 struct qdf_mac_addr *peer_mac) 17833 { 17834 QDF_STATUS status; 17835 wmi_buf_t buf; 17836 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 17837 size_t len = sizeof(*fixed_param); 17838 17839 buf = wmi_buf_alloc(wmi_handle, len); 17840 if (!buf) { 17841 wmi_err("wmi_buf_alloc failed"); 17842 return QDF_STATUS_E_FAILURE; 17843 } 17844 fixed_param = 17845 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 17846 WMITLV_SET_HDR(&fixed_param->tlv_header, 17847 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 17848 WMITLV_GET_STRUCT_TLVLEN( 17849 wmi_rtt_pasn_deauth_cmd_fixed_param)); 17850 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 17851 &fixed_param->peer_mac_addr); 17852 17853 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 17854 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17855 WMI_RTT_PASN_DEAUTH_CMD); 17856 if (QDF_IS_STATUS_ERROR(status)) { 17857 wmi_err("Failed to send pasn deauth command ret = %d", status); 17858 wmi_buf_free(buf); 17859 } 17860 17861 return status; 17862 } 17863 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 17864 17865 static QDF_STATUS 17866 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 17867 struct wlan_crypto_ltf_keyseed_data *data) 17868 { 17869 QDF_STATUS status; 17870 wmi_buf_t buf; 17871 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 17872 uint8_t *buf_ptr; 17873 size_t len = sizeof(*fixed_param) + data->key_seed_len + 17874 WMI_TLV_HDR_SIZE; 17875 17876 buf = wmi_buf_alloc(wmi_handle, len); 17877 if (!buf) { 17878 wmi_err("wmi_buf_alloc failed"); 17879 return QDF_STATUS_E_FAILURE; 17880 } 17881 17882 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17883 fixed_param = 17884 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 17885 WMITLV_SET_HDR(&fixed_param->tlv_header, 17886 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 17887 WMITLV_GET_STRUCT_TLVLEN( 17888 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 17889 17890 fixed_param->vdev_id = data->vdev_id; 17891 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 17892 &fixed_param->peer_macaddr); 17893 fixed_param->key_seed_len = data->key_seed_len; 17894 fixed_param->rsn_authmode = data->rsn_authmode; 17895 17896 buf_ptr += sizeof(*fixed_param); 17897 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 17898 (fixed_param->key_seed_len * sizeof(A_UINT8))); 17899 buf_ptr += WMI_TLV_HDR_SIZE; 17900 17901 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 17902 17903 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 17904 status = wmi_unified_cmd_send(wmi_handle, buf, len, 17905 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 17906 if (QDF_IS_STATUS_ERROR(status)) { 17907 wmi_err("Failed to send ltf keyseed command ret = %d", status); 17908 wmi_buf_free(buf); 17909 } 17910 17911 return status; 17912 } 17913 17914 /** 17915 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 17916 * @wmi_handle: wmi handle 17917 * @event_buf: pointer to event buffer 17918 * @cmd_status: status of HW mode change command 17919 * 17920 * Return QDF_STATUS_SUCCESS on success or proper error code. 17921 */ 17922 static QDF_STATUS 17923 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 17924 uint32_t *cmd_status) 17925 { 17926 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 17927 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 17928 17929 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 17930 if (!param_buf) { 17931 wmi_err("Invalid mode change event buffer"); 17932 return QDF_STATUS_E_INVAL; 17933 } 17934 17935 fixed_param = param_buf->fixed_param; 17936 if (!fixed_param) { 17937 wmi_err("Invalid fixed param"); 17938 return QDF_STATUS_E_INVAL; 17939 } 17940 17941 *cmd_status = fixed_param->status; 17942 return QDF_STATUS_SUCCESS; 17943 } 17944 17945 #ifdef FEATURE_ANI_LEVEL_REQUEST 17946 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 17947 uint32_t *freqs, 17948 uint8_t num_freqs) 17949 { 17950 wmi_buf_t buf; 17951 wmi_get_channel_ani_cmd_fixed_param *cmd; 17952 QDF_STATUS ret; 17953 uint32_t len; 17954 A_UINT32 *chan_list; 17955 uint8_t i, *buf_ptr; 17956 17957 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 17958 WMI_TLV_HDR_SIZE + 17959 num_freqs * sizeof(A_UINT32); 17960 17961 buf = wmi_buf_alloc(wmi_handle, len); 17962 if (!buf) 17963 return QDF_STATUS_E_FAILURE; 17964 17965 buf_ptr = (uint8_t *)wmi_buf_data(buf); 17966 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 17967 WMITLV_SET_HDR(&cmd->tlv_header, 17968 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 17969 WMITLV_GET_STRUCT_TLVLEN( 17970 wmi_get_channel_ani_cmd_fixed_param)); 17971 17972 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 17973 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 17974 (num_freqs * sizeof(A_UINT32))); 17975 17976 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 17977 for (i = 0; i < num_freqs; i++) { 17978 chan_list[i] = freqs[i]; 17979 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 17980 } 17981 17982 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17983 WMI_GET_CHANNEL_ANI_CMDID); 17984 17985 if (QDF_IS_STATUS_ERROR(ret)) { 17986 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 17987 wmi_buf_free(buf); 17988 } 17989 17990 return ret; 17991 } 17992 17993 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 17994 struct wmi_host_ani_level_event **info, 17995 uint32_t *num_freqs) 17996 { 17997 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 17998 wmi_get_channel_ani_event_fixed_param *fixed_param; 17999 wmi_channel_ani_info_tlv_param *tlv_params; 18000 uint8_t *buf_ptr, i; 18001 18002 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 18003 if (!param_buf) { 18004 wmi_err("Invalid ani level event buffer"); 18005 return QDF_STATUS_E_INVAL; 18006 } 18007 18008 fixed_param = 18009 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 18010 if (!fixed_param) { 18011 wmi_err("Invalid fixed param"); 18012 return QDF_STATUS_E_INVAL; 18013 } 18014 18015 buf_ptr = (uint8_t *)fixed_param; 18016 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 18017 buf_ptr += WMI_TLV_HDR_SIZE; 18018 18019 *num_freqs = param_buf->num_ani_info; 18020 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 18021 wmi_err("Invalid number of freqs received"); 18022 return QDF_STATUS_E_INVAL; 18023 } 18024 18025 *info = qdf_mem_malloc(*num_freqs * 18026 sizeof(struct wmi_host_ani_level_event)); 18027 if (!(*info)) 18028 return QDF_STATUS_E_NOMEM; 18029 18030 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 18031 for (i = 0; i < param_buf->num_ani_info; i++) { 18032 (*info)[i].ani_level = tlv_params->ani_level; 18033 (*info)[i].chan_freq = tlv_params->chan_freq; 18034 tlv_params++; 18035 } 18036 18037 return QDF_STATUS_SUCCESS; 18038 } 18039 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 18040 18041 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 18042 /** 18043 * convert_wtc_scan_mode() - Function to convert TLV specific 18044 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 18045 * @scan_mode: scan freq scheme coming from firmware 18046 * 18047 * Return: ROAM_TRIGGER_SCAN_MODE 18048 */ 18049 static enum roam_scan_freq_scheme 18050 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 18051 { 18052 switch (scan_mode) { 18053 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 18054 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 18055 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 18056 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 18057 case ROAM_TRIGGER_SCAN_MODE_FULL: 18058 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 18059 default: 18060 return ROAM_SCAN_FREQ_SCHEME_NONE; 18061 } 18062 } 18063 18064 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 18065 { 18066 switch (fw_trig_reason) { 18067 case WMI_ROAM_TRIGGER_REASON_NONE: 18068 return ROAM_TRIGGER_REASON_NONE; 18069 case WMI_ROAM_TRIGGER_REASON_PER: 18070 return ROAM_TRIGGER_REASON_PER; 18071 case WMI_ROAM_TRIGGER_REASON_BMISS: 18072 return ROAM_TRIGGER_REASON_BMISS; 18073 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18074 return ROAM_TRIGGER_REASON_LOW_RSSI; 18075 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18076 return ROAM_TRIGGER_REASON_HIGH_RSSI; 18077 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18078 return ROAM_TRIGGER_REASON_PERIODIC; 18079 case WMI_ROAM_TRIGGER_REASON_MAWC: 18080 return ROAM_TRIGGER_REASON_MAWC; 18081 case WMI_ROAM_TRIGGER_REASON_DENSE: 18082 return ROAM_TRIGGER_REASON_DENSE; 18083 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18084 return ROAM_TRIGGER_REASON_BACKGROUND; 18085 case WMI_ROAM_TRIGGER_REASON_FORCED: 18086 return ROAM_TRIGGER_REASON_FORCED; 18087 case WMI_ROAM_TRIGGER_REASON_BTM: 18088 return ROAM_TRIGGER_REASON_BTM; 18089 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18090 return ROAM_TRIGGER_REASON_UNIT_TEST; 18091 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18092 return ROAM_TRIGGER_REASON_BSS_LOAD; 18093 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18094 return ROAM_TRIGGER_REASON_DEAUTH; 18095 case WMI_ROAM_TRIGGER_REASON_IDLE: 18096 return ROAM_TRIGGER_REASON_IDLE; 18097 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 18098 return ROAM_TRIGGER_REASON_STA_KICKOUT; 18099 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 18100 return ROAM_TRIGGER_REASON_ESS_RSSI; 18101 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18102 return ROAM_TRIGGER_REASON_WTC_BTM; 18103 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 18104 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 18105 case WMI_ROAM_TRIGGER_REASON_BTC: 18106 return ROAM_TRIGGER_REASON_BTC; 18107 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 18108 return ROAM_TRIGGER_REASON_MAX; 18109 default: 18110 return ROAM_TRIGGER_REASON_NONE; 18111 } 18112 } 18113 18114 /** 18115 * extract_roam_11kv_candidate_info - Extract btm candidate info 18116 * @wmi_handle: wmi_handle 18117 * @evt_buf: Event buffer 18118 * @dst_info: Destination buffer 18119 * 18120 * Return: QDF_STATUS 18121 */ 18122 static QDF_STATUS 18123 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 18124 struct wmi_btm_req_candidate_info *dst_info, 18125 uint8_t btm_idx, uint16_t num_cand) 18126 { 18127 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18128 wmi_roam_btm_request_candidate_info *src_data; 18129 uint8_t i; 18130 18131 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18132 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 18133 !param_buf->num_roam_btm_request_candidate_info || 18134 (btm_idx + 18135 num_cand) > param_buf->num_roam_btm_request_candidate_info) 18136 return QDF_STATUS_SUCCESS; 18137 18138 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 18139 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 18140 num_cand = WLAN_MAX_BTM_CANDIDATE; 18141 for (i = 0; i < num_cand; i++) { 18142 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 18143 dst_info->candidate_bssid.bytes); 18144 dst_info->preference = src_data->preference; 18145 src_data++; 18146 dst_info++; 18147 } 18148 18149 return QDF_STATUS_SUCCESS; 18150 } 18151 18152 static enum roam_trigger_sub_reason 18153 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 18154 { 18155 switch (subreason) { 18156 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 18157 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 18158 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 18159 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 18160 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 18161 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 18162 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 18163 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 18164 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 18165 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 18166 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 18167 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 18168 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 18169 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 18170 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 18171 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 18172 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 18173 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 18174 default: 18175 break; 18176 } 18177 18178 return 0; 18179 } 18180 18181 /** 18182 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 18183 * from the WMI_ROAM_STATS_EVENTID 18184 * @wmi_handle: wmi handle 18185 * @evt_buf: Pointer to the event buffer 18186 * @trig: Pointer to destination structure to fill data 18187 * @idx: TLV id 18188 */ 18189 static QDF_STATUS 18190 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18191 struct wmi_roam_trigger_info *trig, uint8_t idx, 18192 uint8_t btm_idx) 18193 { 18194 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18195 wmi_roam_trigger_reason *src_data = NULL; 18196 uint32_t trig_reason; 18197 18198 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18199 if (!param_buf || !param_buf->roam_trigger_reason) 18200 return QDF_STATUS_E_FAILURE; 18201 18202 src_data = ¶m_buf->roam_trigger_reason[idx]; 18203 18204 trig->present = true; 18205 trig_reason = src_data->trigger_reason; 18206 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 18207 trig->trigger_sub_reason = 18208 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 18209 trig->current_rssi = src_data->current_rssi; 18210 trig->timestamp = src_data->timestamp; 18211 18212 switch (trig_reason) { 18213 case WMI_ROAM_TRIGGER_REASON_PER: 18214 case WMI_ROAM_TRIGGER_REASON_BMISS: 18215 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 18216 case WMI_ROAM_TRIGGER_REASON_MAWC: 18217 case WMI_ROAM_TRIGGER_REASON_DENSE: 18218 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 18219 case WMI_ROAM_TRIGGER_REASON_IDLE: 18220 case WMI_ROAM_TRIGGER_REASON_FORCED: 18221 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 18222 case WMI_ROAM_TRIGGER_REASON_BTC: 18223 return QDF_STATUS_SUCCESS; 18224 18225 case WMI_ROAM_TRIGGER_REASON_BTM: 18226 trig->btm_trig_data.btm_request_mode = 18227 src_data->btm_request_mode; 18228 trig->btm_trig_data.disassoc_timer = 18229 src_data->disassoc_imminent_timer; 18230 trig->btm_trig_data.validity_interval = 18231 src_data->validity_internal; 18232 trig->btm_trig_data.candidate_list_count = 18233 src_data->candidate_list_count; 18234 trig->btm_trig_data.btm_resp_status = 18235 src_data->btm_response_status_code; 18236 trig->btm_trig_data.btm_bss_termination_timeout = 18237 src_data->btm_bss_termination_timeout; 18238 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 18239 src_data->btm_mbo_assoc_retry_timeout; 18240 trig->btm_trig_data.token = src_data->btm_req_dialog_token; 18241 if ((btm_idx + trig->btm_trig_data.candidate_list_count) <= 18242 param_buf->num_roam_btm_request_candidate_info) 18243 extract_roam_11kv_candidate_info( 18244 wmi_handle, evt_buf, 18245 trig->btm_trig_data.btm_cand, 18246 btm_idx, 18247 src_data->candidate_list_count); 18248 18249 return QDF_STATUS_SUCCESS; 18250 18251 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 18252 trig->cu_trig_data.cu_load = src_data->cu_load; 18253 return QDF_STATUS_SUCCESS; 18254 18255 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 18256 trig->deauth_trig_data.type = src_data->deauth_type; 18257 trig->deauth_trig_data.reason = src_data->deauth_reason; 18258 return QDF_STATUS_SUCCESS; 18259 18260 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 18261 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 18262 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 18263 return QDF_STATUS_SUCCESS; 18264 18265 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 18266 trig->wtc_btm_trig_data.roaming_mode = 18267 src_data->vendor_specific1[0]; 18268 trig->wtc_btm_trig_data.vsie_trigger_reason = 18269 src_data->vendor_specific1[1]; 18270 trig->wtc_btm_trig_data.sub_code = 18271 src_data->vendor_specific1[2]; 18272 trig->wtc_btm_trig_data.wtc_mode = 18273 src_data->vendor_specific1[3]; 18274 trig->wtc_btm_trig_data.wtc_scan_mode = 18275 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 18276 trig->wtc_btm_trig_data.wtc_rssi_th = 18277 src_data->vendor_specific1[5]; 18278 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 18279 src_data->vendor_specific1[6]; 18280 18281 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 18282 src_data->vendor_specific2[0]; 18283 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 18284 src_data->vendor_specific2[1]; 18285 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 18286 src_data->vendor_specific2[2]; 18287 trig->wtc_btm_trig_data.duration = 18288 src_data->vendor_specific2[3]; 18289 18290 return QDF_STATUS_SUCCESS; 18291 default: 18292 return QDF_STATUS_SUCCESS; 18293 } 18294 18295 return QDF_STATUS_SUCCESS; 18296 } 18297 18298 /** 18299 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 18300 * from the WMI_ROAM_STATS_EVENTID 18301 * @wmi_handle: wmi handle 18302 * @evt_buf: Pointer to the event buffer 18303 * @dst: Pointer to destination structure to fill data 18304 * @ap_idx: TLV index for this roam scan 18305 * @num_cand: number of candidates list in the roam scan 18306 */ 18307 static QDF_STATUS 18308 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18309 struct wmi_roam_candidate_info *dst, 18310 uint8_t ap_idx, uint16_t num_cand) 18311 { 18312 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18313 wmi_roam_ap_info *src = NULL; 18314 uint8_t i; 18315 18316 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18317 if (!param_buf) { 18318 wmi_err("Param buf is NULL"); 18319 return QDF_STATUS_E_FAILURE; 18320 } 18321 18322 if (ap_idx >= param_buf->num_roam_ap_info) { 18323 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 18324 ap_idx, param_buf->num_roam_ap_info); 18325 return QDF_STATUS_E_FAILURE; 18326 } 18327 18328 src = ¶m_buf->roam_ap_info[ap_idx]; 18329 18330 for (i = 0; i < num_cand; i++) { 18331 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 18332 dst->type = src->candidate_type; 18333 dst->freq = src->channel; 18334 dst->etp = src->etp; 18335 dst->rssi = src->rssi; 18336 dst->rssi_score = src->rssi_score; 18337 dst->cu_load = src->cu_load; 18338 dst->cu_score = src->cu_score; 18339 dst->total_score = src->total_score; 18340 dst->timestamp = src->timestamp; 18341 dst->dl_reason = src->bl_reason; 18342 dst->dl_source = src->bl_source; 18343 dst->dl_timestamp = src->bl_timestamp; 18344 dst->dl_original_timeout = src->bl_original_timeout; 18345 18346 src++; 18347 dst++; 18348 } 18349 18350 return QDF_STATUS_SUCCESS; 18351 } 18352 18353 /** 18354 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18355 * from the WMI_ROAM_STATS_EVENTID 18356 * @wmi_handle: wmi handle 18357 * @evt_buf: Pointer to the event buffer 18358 * @dst: Pointer to destination structure to fill data 18359 * @idx: TLV id 18360 * @chan_idx: Index of the channel tlv for the current roam trigger 18361 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 18362 */ 18363 static QDF_STATUS 18364 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18365 struct wmi_roam_scan_data *dst, uint8_t idx, 18366 uint8_t chan_idx, uint8_t ap_idx) 18367 { 18368 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18369 wmi_roam_scan_info *src_data = NULL; 18370 wmi_roam_scan_channel_info *src_chan = NULL; 18371 QDF_STATUS status; 18372 uint8_t i; 18373 18374 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18375 if (!param_buf || !param_buf->roam_scan_info || 18376 idx >= param_buf->num_roam_scan_info) 18377 return QDF_STATUS_E_FAILURE; 18378 18379 src_data = ¶m_buf->roam_scan_info[idx]; 18380 18381 dst->present = true; 18382 dst->type = src_data->roam_scan_type; 18383 dst->num_chan = src_data->roam_scan_channel_count; 18384 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 18385 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 18386 dst->frame_info_count = src_data->frame_info_count; 18387 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 18388 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 18389 18390 /* Read the channel data only for dst->type is 0 (partial scan) */ 18391 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 18392 chan_idx < param_buf->num_roam_scan_chan_info) { 18393 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 18394 dst->num_chan = MAX_ROAM_SCAN_CHAN; 18395 18396 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 18397 for (i = 0; i < dst->num_chan; i++) { 18398 dst->chan_freq[i] = src_chan->channel; 18399 src_chan++; 18400 } 18401 } 18402 18403 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 18404 return QDF_STATUS_SUCCESS; 18405 18406 dst->num_ap = src_data->roam_ap_count; 18407 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 18408 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 18409 18410 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 18411 ap_idx, dst->num_ap); 18412 if (QDF_IS_STATUS_ERROR(status)) { 18413 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 18414 return status; 18415 } 18416 18417 return QDF_STATUS_SUCCESS; 18418 } 18419 18420 /** 18421 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 18422 * @wmi_roam_fail_reason: roam fail enum 18423 * 18424 * Return: Roaming failure reason codes 18425 */ 18426 static enum wlan_roam_failure_reason_code 18427 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 18428 { 18429 switch (wmi_roam_fail_reason) { 18430 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 18431 return ROAM_FAIL_REASON_NO_SCAN_START; 18432 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 18433 return ROAM_FAIL_REASON_NO_AP_FOUND; 18434 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 18435 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 18436 case WMI_ROAM_FAIL_REASON_HOST: 18437 return ROAM_FAIL_REASON_HOST; 18438 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 18439 return ROAM_FAIL_REASON_AUTH_SEND; 18440 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 18441 return ROAM_FAIL_REASON_AUTH_RECV; 18442 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 18443 return ROAM_FAIL_REASON_NO_AUTH_RESP; 18444 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 18445 return ROAM_FAIL_REASON_REASSOC_SEND; 18446 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 18447 return ROAM_FAIL_REASON_REASSOC_RECV; 18448 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 18449 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 18450 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 18451 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 18452 case WMI_ROAM_FAIL_REASON_MLME: 18453 return ROAM_FAIL_REASON_MLME; 18454 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 18455 return ROAM_FAIL_REASON_INTERNAL_ABORT; 18456 case WMI_ROAM_FAIL_REASON_SCAN_START: 18457 return ROAM_FAIL_REASON_SCAN_START; 18458 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 18459 return ROAM_FAIL_REASON_AUTH_NO_ACK; 18460 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 18461 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 18462 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 18463 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 18464 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 18465 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 18466 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 18467 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 18468 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 18469 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 18470 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 18471 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 18472 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 18473 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 18474 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 18475 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 18476 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 18477 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 18478 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 18479 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 18480 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 18481 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 18482 case WMI_ROAM_FAIL_REASON_DISCONNECT: 18483 return ROAM_FAIL_REASON_DISCONNECT; 18484 case WMI_ROAM_FAIL_REASON_SYNC: 18485 return ROAM_FAIL_REASON_SYNC; 18486 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 18487 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 18488 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 18489 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 18490 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 18491 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 18492 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 18493 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 18494 default: 18495 return ROAM_FAIL_REASON_UNKNOWN; 18496 } 18497 } 18498 18499 /** 18500 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 18501 * from the WMI_ROAM_STATS_EVENTID 18502 * @wmi_handle: wmi handle 18503 * @evt_buf: Pointer to the event buffer 18504 * @dst: Pointer to destination structure to fill data 18505 * @idx: TLV id 18506 */ 18507 static QDF_STATUS 18508 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18509 struct wmi_roam_result *dst, uint8_t idx) 18510 { 18511 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18512 wmi_roam_result *src_data = NULL; 18513 18514 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18515 if (!param_buf || !param_buf->roam_result || 18516 idx >= param_buf->num_roam_result) 18517 return QDF_STATUS_E_FAILURE; 18518 18519 src_data = ¶m_buf->roam_result[idx]; 18520 18521 dst->present = true; 18522 dst->status = src_data->roam_status; 18523 dst->timestamp = src_data->timestamp; 18524 dst->fail_reason = 18525 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 18526 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 18527 18528 return QDF_STATUS_SUCCESS; 18529 } 18530 18531 /** 18532 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 18533 * from the WMI_ROAM_STATS_EVENTID 18534 * @wmi_handle: wmi handle 18535 * @evt_buf: Pointer to the event buffer 18536 * @dst: Pointer to destination structure to fill data 18537 * @idx: TLV id 18538 * @rpt_idx: Neighbor report Channel index 18539 */ 18540 static QDF_STATUS 18541 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18542 struct wmi_neighbor_report_data *dst, 18543 uint8_t idx, uint8_t rpt_idx) 18544 { 18545 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 18546 wmi_roam_neighbor_report_info *src_data = NULL; 18547 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 18548 uint8_t i; 18549 18550 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 18551 if (!param_buf || !param_buf->roam_neighbor_report_info || 18552 !param_buf->num_roam_neighbor_report_info || 18553 idx >= param_buf->num_roam_neighbor_report_info) { 18554 wmi_debug("Invalid 1kv param buf"); 18555 return QDF_STATUS_E_FAILURE; 18556 } 18557 18558 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 18559 18560 dst->present = true; 18561 dst->req_type = src_data->request_type; 18562 dst->num_freq = src_data->neighbor_report_channel_count; 18563 dst->req_time = src_data->neighbor_report_request_timestamp; 18564 dst->resp_time = src_data->neighbor_report_response_timestamp; 18565 dst->btm_query_token = src_data->btm_query_token; 18566 dst->btm_query_reason = src_data->btm_query_reason_code; 18567 18568 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 18569 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 18570 return QDF_STATUS_SUCCESS; 18571 18572 if (!param_buf->roam_neighbor_report_chan_info) { 18573 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 18574 dst->num_freq); 18575 dst->num_freq = 0; 18576 /* return success as its optional tlv and we can print neighbor 18577 * report received info 18578 */ 18579 return QDF_STATUS_SUCCESS; 18580 } 18581 18582 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 18583 18584 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 18585 dst->num_freq = MAX_ROAM_SCAN_CHAN; 18586 18587 for (i = 0; i < dst->num_freq; i++) { 18588 dst->freq[i] = src_freq->channel; 18589 src_freq++; 18590 } 18591 18592 return QDF_STATUS_SUCCESS; 18593 } 18594 18595 /** 18596 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 18597 * @wmi_handle : handle to WMI. 18598 * @roam_param : pointer to hold roam set parameter 18599 * 18600 * Return: 0 on success and -ve on failure. 18601 */ 18602 static QDF_STATUS 18603 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 18604 struct vdev_set_params *roam_param) 18605 { 18606 QDF_STATUS ret; 18607 wmi_roam_set_param_cmd_fixed_param *cmd; 18608 wmi_buf_t buf; 18609 uint16_t len = sizeof(*cmd); 18610 18611 buf = wmi_buf_alloc(wmi_handle, len); 18612 if (!buf) 18613 return QDF_STATUS_E_NOMEM; 18614 18615 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 18616 WMITLV_SET_HDR(&cmd->tlv_header, 18617 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 18618 WMITLV_GET_STRUCT_TLVLEN 18619 (wmi_roam_set_param_cmd_fixed_param)); 18620 cmd->vdev_id = roam_param->vdev_id; 18621 cmd->param_id = roam_param->param_id; 18622 cmd->param_value = roam_param->param_value; 18623 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 18624 cmd->vdev_id, cmd->param_id, cmd->param_value); 18625 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 18626 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18627 WMI_ROAM_SET_PARAM_CMDID); 18628 if (QDF_IS_STATUS_ERROR(ret)) { 18629 wmi_err("Failed to send roam set param command, ret = %d", ret); 18630 wmi_buf_free(buf); 18631 } 18632 18633 return ret; 18634 } 18635 #else 18636 static inline QDF_STATUS 18637 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18638 struct wmi_roam_trigger_info *trig, uint8_t idx, 18639 uint8_t btm_idx) 18640 { 18641 return QDF_STATUS_E_NOSUPPORT; 18642 } 18643 18644 static inline QDF_STATUS 18645 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18646 struct wmi_roam_result *dst, uint8_t idx) 18647 { 18648 return QDF_STATUS_E_NOSUPPORT; 18649 } 18650 18651 static QDF_STATUS 18652 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18653 struct wmi_neighbor_report_data *dst, 18654 uint8_t idx, uint8_t rpt_idx) 18655 { 18656 return QDF_STATUS_E_NOSUPPORT; 18657 } 18658 18659 static QDF_STATUS 18660 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18661 struct wmi_roam_scan_data *dst, uint8_t idx, 18662 uint8_t chan_idx, uint8_t ap_idx) 18663 { 18664 return QDF_STATUS_E_NOSUPPORT; 18665 } 18666 #endif 18667 18668 #ifdef WLAN_FEATURE_PKT_CAPTURE 18669 static QDF_STATUS 18670 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 18671 struct mgmt_offload_event_params *params) 18672 { 18673 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 18674 wmi_mgmt_hdr *hdr; 18675 18676 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 18677 if (!param_tlvs) 18678 return QDF_STATUS_E_INVAL; 18679 18680 hdr = param_tlvs->fixed_param; 18681 if (!hdr) 18682 return QDF_STATUS_E_INVAL; 18683 18684 if (hdr->buf_len > param_tlvs->num_bufp) 18685 return QDF_STATUS_E_INVAL; 18686 18687 params->tsf_l32 = hdr->tsf_l32; 18688 params->chan_freq = hdr->chan_freq; 18689 params->rate_kbps = hdr->rate_kbps; 18690 params->rssi = hdr->rssi; 18691 params->buf_len = hdr->buf_len; 18692 params->tx_status = hdr->tx_status; 18693 params->buf = param_tlvs->bufp; 18694 params->tx_retry_cnt = hdr->tx_retry_cnt; 18695 return QDF_STATUS_SUCCESS; 18696 } 18697 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 18698 18699 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 18700 static QDF_STATUS 18701 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 18702 struct smu_event_params *params) 18703 { 18704 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 18705 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 18706 18707 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 18708 if (!param_buf) { 18709 wmi_err("Invalid smart monitor event"); 18710 return QDF_STATUS_E_INVAL; 18711 } 18712 18713 smu_event = param_buf->fixed_param; 18714 if (!smu_event) { 18715 wmi_err("smart monitor event fixed param is NULL"); 18716 return QDF_STATUS_E_INVAL; 18717 } 18718 18719 params->vdev_id = smu_event->vdev_id; 18720 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 18721 return QDF_STATUS_E_INVAL; 18722 18723 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 18724 18725 return QDF_STATUS_SUCCESS; 18726 } 18727 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 18728 18729 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 18730 /** 18731 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 18732 * 18733 * @wmi: wmi handle 18734 * @vdev_id: vdev id 18735 * @burst_mode: Indicates whether relation derived using FTM is needed for 18736 * each FTM frame or only aggregated result is required. 18737 * 18738 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 18739 * 18740 * Return: QDF_STATUS 18741 */ 18742 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 18743 uint32_t vdev_id, 18744 bool burst_mode) 18745 { 18746 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 18747 wmi_buf_t buf; 18748 int32_t len = sizeof(*cmd); 18749 18750 buf = wmi_buf_alloc(wmi, len); 18751 if (!buf) { 18752 wmi_err("wmi_buf_alloc failed"); 18753 return QDF_STATUS_E_NOMEM; 18754 } 18755 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 18756 WMITLV_SET_HDR(&cmd->tlv_header, 18757 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 18758 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 18759 cmd->vdev_id = vdev_id; 18760 cmd->agg_relation = burst_mode ? false : true; 18761 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 18762 wmi_err("Failed to send audio sync trigger cmd"); 18763 wmi_buf_free(buf); 18764 return QDF_STATUS_E_FAILURE; 18765 } 18766 18767 return QDF_STATUS_SUCCESS; 18768 } 18769 18770 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 18771 uint32_t vdev_id, 18772 uint64_t lpass_ts) 18773 { 18774 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 18775 wmi_buf_t buf; 18776 int32_t len = sizeof(*cmd); 18777 18778 buf = wmi_buf_alloc(wmi, len); 18779 if (!buf) { 18780 wmi_err("wmi_buf_alloc failed"); 18781 return QDF_STATUS_E_NOMEM; 18782 } 18783 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 18784 WMITLV_SET_HDR(&cmd->tlv_header, 18785 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 18786 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 18787 cmd->vdev_id = vdev_id; 18788 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 18789 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 18790 18791 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 18792 wmi_err("Failed to send audio qtime command"); 18793 wmi_buf_free(buf); 18794 return QDF_STATUS_E_FAILURE; 18795 } 18796 18797 return QDF_STATUS_SUCCESS; 18798 } 18799 18800 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 18801 wmi_unified_t wmi, void *buf, 18802 struct ftm_time_sync_start_stop_params *param) 18803 { 18804 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 18805 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 18806 18807 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 18808 if (!param_buf) { 18809 wmi_err("Invalid audio sync start stop event buffer"); 18810 return QDF_STATUS_E_FAILURE; 18811 } 18812 18813 resp_event = param_buf->fixed_param; 18814 if (!resp_event) { 18815 wmi_err("Invalid audio sync start stop fixed param buffer"); 18816 return QDF_STATUS_E_FAILURE; 18817 } 18818 18819 param->vdev_id = resp_event->vdev_id; 18820 param->timer_interval = resp_event->periodicity; 18821 param->num_reads = resp_event->reads_needed; 18822 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 18823 resp_event->qtimer_l32; 18824 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 18825 resp_event->mac_timer_l32; 18826 18827 wmi_debug("FTM time sync time_interval %d, num_reads %d", 18828 param->timer_interval, param->num_reads); 18829 18830 return QDF_STATUS_SUCCESS; 18831 } 18832 18833 static QDF_STATUS 18834 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 18835 struct ftm_time_sync_offset *param) 18836 { 18837 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 18838 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 18839 wmi_audio_sync_q_master_slave_times *q_pair; 18840 int iter; 18841 18842 param_buf = 18843 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 18844 if (!param_buf) { 18845 wmi_err("Invalid timesync ftm offset event buffer"); 18846 return QDF_STATUS_E_FAILURE; 18847 } 18848 18849 resp_event = param_buf->fixed_param; 18850 if (!resp_event) { 18851 wmi_err("Invalid timesync ftm offset fixed param buffer"); 18852 return QDF_STATUS_E_FAILURE; 18853 } 18854 18855 param->vdev_id = resp_event->vdev_id; 18856 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 18857 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 18858 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 18859 18860 q_pair = param_buf->audio_sync_q_master_slave_times; 18861 if (!q_pair) { 18862 wmi_err("Invalid q_master_slave_times buffer"); 18863 return QDF_STATUS_E_FAILURE; 18864 } 18865 18866 for (iter = 0; iter < param->num_qtime; iter++) { 18867 param->pairs[iter].qtime_initiator = ( 18868 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 18869 q_pair[iter].qmaster_l32; 18870 param->pairs[iter].qtime_target = ( 18871 (uint64_t)q_pair[iter].qslave_u32 << 32) | 18872 q_pair[iter].qslave_l32; 18873 } 18874 return QDF_STATUS_SUCCESS; 18875 } 18876 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 18877 18878 /** 18879 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 18880 * @wmi: wmi handle 18881 * @vdev_id: vdev id 18882 * 18883 * TSF_TSTAMP_READ_VALUE is the only operation supported 18884 * Return: QDF_STATUS_SUCCESS for success or error code 18885 */ 18886 static QDF_STATUS 18887 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 18888 { 18889 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 18890 wmi_buf_t buf; 18891 int32_t len = sizeof(*cmd); 18892 18893 buf = wmi_buf_alloc(wmi, len); 18894 if (!buf) 18895 return QDF_STATUS_E_NOMEM; 18896 18897 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 18898 WMITLV_SET_HDR(&cmd->tlv_header, 18899 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 18900 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 18901 cmd->vdev_id = vdev_id; 18902 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 18903 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 18904 if (wmi_unified_cmd_send(wmi, buf, len, 18905 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 18906 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 18907 __func__); 18908 wmi_buf_free(buf); 18909 return QDF_STATUS_E_FAILURE; 18910 } 18911 18912 return QDF_STATUS_SUCCESS; 18913 } 18914 18915 /** 18916 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 18917 * @wmi_handle: wmi handle 18918 * @param evt_buf: pointer to event buffer 18919 * @wmi_host_tsf_event param: Pointer to struct to hold event info 18920 * 18921 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 18922 */ 18923 static QDF_STATUS 18924 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18925 struct wmi_host_tsf_event *param) 18926 { 18927 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 18928 wmi_vdev_tsf_report_event_fixed_param *evt; 18929 18930 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 18931 if (!param_buf) { 18932 wmi_err("Invalid tsf report event buffer"); 18933 return QDF_STATUS_E_INVAL; 18934 } 18935 18936 evt = param_buf->fixed_param; 18937 param->vdev_id = evt->vdev_id; 18938 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 18939 param->tsf_low = evt->tsf_low; 18940 param->tsf_high = evt->tsf_high; 18941 param->qtimer_low = evt->qtimer_low; 18942 param->qtimer_high = evt->qtimer_high; 18943 param->tsf_id = evt->tsf_id; 18944 param->tsf_id_valid = evt->tsf_id_valid; 18945 param->mac_id = evt->mac_id; 18946 param->mac_id_valid = evt->mac_id_valid; 18947 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 18948 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 18949 param->tqm_timer_low = evt->tqm_timer_low; 18950 param->tqm_timer_high = evt->tqm_timer_high; 18951 param->use_tqm_timer = evt->use_tqm_timer; 18952 18953 return QDF_STATUS_SUCCESS; 18954 } 18955 18956 /** 18957 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 18958 * status tlv 18959 * @wmi_handle: wmi handle 18960 * @param evt_buf: pointer to event buffer 18961 * @param param: Pointer to hold csa switch count status event param 18962 * 18963 * Return: QDF_STATUS_SUCCESS for success or error code 18964 */ 18965 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 18966 wmi_unified_t wmi_handle, 18967 void *evt_buf, 18968 struct pdev_csa_switch_count_status *param) 18969 { 18970 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 18971 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 18972 18973 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 18974 evt_buf; 18975 if (!param_buf) { 18976 wmi_err("Invalid CSA status event"); 18977 return QDF_STATUS_E_INVAL; 18978 } 18979 18980 csa_status = param_buf->fixed_param; 18981 18982 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 18983 wmi_handle, 18984 csa_status->pdev_id); 18985 param->current_switch_count = csa_status->current_switch_count; 18986 param->num_vdevs = csa_status->num_vdevs; 18987 param->vdev_ids = param_buf->vdev_ids; 18988 18989 return QDF_STATUS_SUCCESS; 18990 } 18991 18992 #ifdef CONFIG_AFC_SUPPORT 18993 /** 18994 * send_afc_cmd_tlv() - Sends the AFC indication to FW 18995 * @wmi_handle: wmi handle 18996 * @pdev_id: Pdev id 18997 * @param: Pointer to hold AFC indication. 18998 * 18999 * Return: QDF_STATUS_SUCCESS for success or error code 19000 */ 19001 static 19002 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 19003 uint8_t pdev_id, 19004 struct reg_afc_resp_rx_ind_info *param) 19005 { 19006 wmi_buf_t buf; 19007 wmi_afc_cmd_fixed_param *cmd; 19008 uint32_t len; 19009 uint8_t *buf_ptr; 19010 QDF_STATUS ret; 19011 19012 len = sizeof(wmi_afc_cmd_fixed_param); 19013 buf = wmi_buf_alloc(wmi_handle, len); 19014 if (!buf) 19015 return QDF_STATUS_E_NOMEM; 19016 19017 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19018 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 19019 19020 WMITLV_SET_HDR(&cmd->tlv_header, 19021 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 19022 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 19023 19024 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 19025 wmi_handle, 19026 pdev_id); 19027 cmd->cmd_type = param->cmd_type; 19028 cmd->serv_resp_format = param->serv_resp_format; 19029 19030 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 19031 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 19032 if (QDF_IS_STATUS_ERROR(ret)) { 19033 wmi_err("Failed to send WMI_AFC_CMDID"); 19034 wmi_buf_free(buf); 19035 return QDF_STATUS_E_FAILURE; 19036 } 19037 19038 return QDF_STATUS_SUCCESS; 19039 } 19040 #endif 19041 19042 /** 19043 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 19044 * @wmi_handle: wmi handle 19045 * @param: Pointer to hold TX power info 19046 * 19047 * Return: QDF_STATUS_SUCCESS for success or error code 19048 */ 19049 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 19050 uint8_t vdev_id, 19051 struct reg_tpc_power_info *param) 19052 { 19053 wmi_buf_t buf; 19054 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 19055 wmi_vdev_ch_power_info *ch_power_info; 19056 uint8_t *buf_ptr; 19057 uint16_t idx; 19058 uint32_t len; 19059 QDF_STATUS ret; 19060 19061 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 19062 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 19063 19064 buf = wmi_buf_alloc(wmi_handle, len); 19065 if (!buf) 19066 return QDF_STATUS_E_NOMEM; 19067 19068 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19069 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 19070 19071 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 19072 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 19073 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 19074 19075 tpc_power_info_param->vdev_id = vdev_id; 19076 tpc_power_info_param->psd_power = param->is_psd_power; 19077 tpc_power_info_param->eirp_power = param->eirp_power; 19078 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 19079 wmi_debug("eirp_power = %d is_psd_power = %d power_type_6ghz = %d", 19080 tpc_power_info_param->eirp_power, 19081 tpc_power_info_param->psd_power, 19082 tpc_power_info_param->power_type_6ghz); 19083 19084 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 19085 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19086 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 19087 19088 buf_ptr += WMI_TLV_HDR_SIZE; 19089 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 19090 19091 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 19092 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 19093 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 19094 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 19095 ch_power_info[idx].chan_cfreq = 19096 param->chan_power_info[idx].chan_cfreq; 19097 ch_power_info[idx].tx_power = 19098 param->chan_power_info[idx].tx_power; 19099 wmi_debug("chan_cfreq = %d tx_power = %d", 19100 ch_power_info[idx].chan_cfreq, 19101 ch_power_info[idx].tx_power); 19102 buf_ptr += sizeof(wmi_vdev_ch_power_info); 19103 } 19104 19105 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 19106 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19107 WMI_VDEV_SET_TPC_POWER_CMDID); 19108 if (QDF_IS_STATUS_ERROR(ret)) 19109 wmi_buf_free(buf); 19110 19111 19112 return ret; 19113 } 19114 19115 /** 19116 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 19117 * @wmi_handle: wmi handle 19118 * @evt_buf: event buffer 19119 * @param: dpd status info 19120 * 19121 * Return: QDF_STATUS_SUCCESS for success or error code 19122 */ 19123 static QDF_STATUS 19124 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 19125 void *evt_buf, 19126 struct wmi_host_pdev_get_dpd_status_event *param) 19127 { 19128 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 19129 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 19130 19131 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 19132 if (!param_buf) { 19133 wmi_err("Invalid get dpd_status event"); 19134 return QDF_STATUS_E_INVAL; 19135 } 19136 19137 dpd_status = param_buf->fixed_param; 19138 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19139 (wmi_handle, dpd_status->pdev_id); 19140 param->dpd_status = dpd_status->dpd_status; 19141 19142 return QDF_STATUS_SUCCESS; 19143 } 19144 19145 static int 19146 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 19147 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 19148 { 19149 if (status->halphy_cal_valid_bmap && valid_bit) 19150 return (status->halphy_cal_status && valid_bit); 19151 19152 return 0; 19153 } 19154 19155 static QDF_STATUS 19156 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 19157 void *evt_buf, 19158 struct wmi_host_pdev_get_halphy_cal_status_event *param) 19159 { 19160 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 19161 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 19162 19163 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 19164 if (!param_buf) { 19165 wmi_err("Invalid get halphy cal status event"); 19166 return QDF_STATUS_E_INVAL; 19167 } 19168 19169 halphy_cal_status = param_buf->fixed_param; 19170 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19171 (wmi_handle, halphy_cal_status->pdev_id); 19172 param->halphy_cal_adc_status = 19173 convert_halphy_status(halphy_cal_status, 19174 WMI_HALPHY_CAL_ADC_BMAP); 19175 param->halphy_cal_bwfilter_status = 19176 convert_halphy_status(halphy_cal_status, 19177 WMI_HALPHY_CAL_BWFILTER_BMAP); 19178 param->halphy_cal_pdet_and_pal_status = 19179 convert_halphy_status(halphy_cal_status, 19180 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 19181 param->halphy_cal_rxdco_status = 19182 convert_halphy_status(halphy_cal_status, 19183 WMI_HALPHY_CAL_RXDCO_BMAP); 19184 param->halphy_cal_comb_txiq_rxiq_status = 19185 convert_halphy_status(halphy_cal_status, 19186 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 19187 param->halphy_cal_ibf_status = 19188 convert_halphy_status(halphy_cal_status, 19189 WMI_HALPHY_CAL_IBF_BMAP); 19190 param->halphy_cal_pa_droop_status = 19191 convert_halphy_status(halphy_cal_status, 19192 WMI_HALPHY_CAL_PA_DROOP_BMAP); 19193 param->halphy_cal_dac_status = 19194 convert_halphy_status(halphy_cal_status, 19195 WMI_HALPHY_CAL_DAC_BMAP); 19196 param->halphy_cal_ani_status = 19197 convert_halphy_status(halphy_cal_status, 19198 WMI_HALPHY_CAL_ANI_BMAP); 19199 param->halphy_cal_noise_floor_status = 19200 convert_halphy_status(halphy_cal_status, 19201 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 19202 19203 return QDF_STATUS_SUCCESS; 19204 } 19205 19206 /** 19207 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 19208 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 19209 * 19210 * Return: host_set_halphy_cal_status 19211 */ 19212 static enum wmi_host_set_halphy_cal_status 19213 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 19214 { 19215 if (fw_status == 0) 19216 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 19217 else if (fw_status == 1) 19218 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19219 19220 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 19221 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 19222 } 19223 19224 /** 19225 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 19226 * @wmi_handle: wmi handle 19227 * @evt_buf: event buffer 19228 * @param: set halphy cal status info 19229 * 19230 * Return: QDF_STATUS_SUCCESS for success or error code 19231 */ 19232 static QDF_STATUS 19233 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 19234 void *evt_buf, 19235 struct wmi_host_pdev_set_halphy_cal_event *param) 19236 { 19237 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 19238 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 19239 19240 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 19241 if (!param_buf) { 19242 wmi_err("Invalid set halphy_status event"); 19243 return QDF_STATUS_E_INVAL; 19244 } 19245 19246 set_halphy_status = param_buf->fixed_param; 19247 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 19248 (wmi_handle, set_halphy_status->pdev_id); 19249 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 19250 19251 return QDF_STATUS_SUCCESS; 19252 } 19253 19254 /** 19255 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 19256 * @wmi_handle: wmi handle 19257 * @evt_buf: pointer to event buffer 19258 * @len: length of the event buffer 19259 * @param: Pointer to hold install key complete event param 19260 * 19261 * Return: QDF_STATUS_SUCCESS for success or error code 19262 */ 19263 static QDF_STATUS 19264 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 19265 void *evt_buf, uint32_t len, 19266 struct wmi_install_key_comp_event *param) 19267 { 19268 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 19269 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 19270 19271 if (len < sizeof(*param_buf)) { 19272 wmi_err("invalid event buf len %d", len); 19273 return QDF_STATUS_E_INVAL; 19274 } 19275 19276 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 19277 if (!param_buf) { 19278 wmi_err("received null buf from target"); 19279 return QDF_STATUS_E_INVAL; 19280 } 19281 19282 key_fp = param_buf->fixed_param; 19283 if (!key_fp) { 19284 wmi_err("received null event data from target"); 19285 return QDF_STATUS_E_INVAL; 19286 } 19287 19288 param->vdev_id = key_fp->vdev_id; 19289 param->key_ix = key_fp->key_ix; 19290 param->key_flags = key_fp->key_flags; 19291 param->status = key_fp->status; 19292 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 19293 param->peer_macaddr); 19294 19295 return QDF_STATUS_SUCCESS; 19296 } 19297 19298 static QDF_STATUS 19299 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 19300 struct wmi_host_send_set_halphy_cal_info *param) 19301 { 19302 wmi_buf_t buf; 19303 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 19304 QDF_STATUS ret; 19305 uint32_t len; 19306 19307 len = sizeof(*cmd); 19308 19309 buf = wmi_buf_alloc(wmi_handle, len); 19310 if (!buf) 19311 return QDF_STATUS_E_FAILURE; 19312 19313 cmd = (void *)wmi_buf_data(buf); 19314 19315 WMITLV_SET_HDR(&cmd->tlv_header, 19316 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 19317 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 19318 19319 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 19320 param->pdev_id); 19321 cmd->online_halphy_cals_bmap = param->value; 19322 cmd->home_scan_channel = param->chan_sel; 19323 19324 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19325 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 19326 if (QDF_IS_STATUS_ERROR(ret)) { 19327 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 19328 wmi_buf_free(buf); 19329 } 19330 19331 return ret; 19332 } 19333 19334 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19335 /** 19336 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 19337 * @wmi: wmi handle 19338 * @params: set MAC address command params 19339 * 19340 * Return: QDF_STATUS_SUCCESS for success or error code 19341 */ 19342 static QDF_STATUS 19343 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 19344 struct set_mac_addr_params *params) 19345 { 19346 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 19347 wmi_buf_t buf; 19348 int32_t len = sizeof(*cmd); 19349 19350 buf = wmi_buf_alloc(wmi, len); 19351 if (!buf) 19352 return QDF_STATUS_E_NOMEM; 19353 19354 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 19355 WMITLV_SET_HDR( 19356 &cmd->tlv_header, 19357 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 19358 WMITLV_GET_STRUCT_TLVLEN 19359 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 19360 cmd->vdev_id = params->vdev_id; 19361 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 19362 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 19363 19364 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 19365 QDF_MAC_ADDR_FMT, cmd->vdev_id, 19366 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 19367 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 19368 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 19369 if (wmi_unified_cmd_send(wmi, buf, len, 19370 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 19371 wmi_buf_free(buf); 19372 return QDF_STATUS_E_FAILURE; 19373 } 19374 19375 return QDF_STATUS_SUCCESS; 19376 } 19377 19378 /** 19379 * extract_update_mac_address_event_tlv() - extract update MAC address event 19380 * @wmi_handle: WMI handle 19381 * @evt_buf: event buffer 19382 * @vdev_id: VDEV ID 19383 * @status: FW status of the set MAC address operation 19384 * 19385 * Return: QDF_STATUS 19386 */ 19387 static QDF_STATUS extract_update_mac_address_event_tlv( 19388 wmi_unified_t wmi_handle, void *evt_buf, 19389 uint8_t *vdev_id, uint8_t *status) 19390 { 19391 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 19392 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 19393 19394 param_buf = 19395 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 19396 19397 event = param_buf->fixed_param; 19398 19399 *vdev_id = event->vdev_id; 19400 *status = event->status; 19401 19402 return QDF_STATUS_SUCCESS; 19403 } 19404 #endif 19405 19406 #ifdef WLAN_FEATURE_11BE_MLO 19407 /** 19408 * extract_quiet_offload_event_tlv() - extract quiet offload event 19409 * @wmi_handle: WMI handle 19410 * @evt_buf: event buffer 19411 * @mld_mac: mld mac address 19412 * @link_mac: link mac address 19413 * @link_id: link id 19414 * @quiet_status: quiet is started or stopped 19415 * 19416 * Return: QDF_STATUS 19417 */ 19418 static QDF_STATUS extract_quiet_offload_event_tlv( 19419 wmi_unified_t wmi_handle, void *evt_buf, 19420 struct vdev_sta_quiet_event *quiet_event) 19421 { 19422 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 19423 wmi_quiet_event_fixed_param *event; 19424 19425 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 19426 19427 event = param_buf->fixed_param; 19428 19429 if (!(event->mld_mac_address_present && event->linkid_present) && 19430 !event->link_mac_address_present) { 19431 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 19432 event->mld_mac_address_present, 19433 event->linkid_present, 19434 event->link_mac_address_present); 19435 return QDF_STATUS_E_INVAL; 19436 } 19437 19438 if (event->mld_mac_address_present) 19439 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 19440 quiet_event->mld_mac.bytes); 19441 if (event->link_mac_address_present) 19442 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 19443 quiet_event->link_mac.bytes); 19444 if (event->linkid_present) 19445 quiet_event->link_id = event->linkid; 19446 quiet_event->quiet_status = (event->quiet_status == 19447 WMI_QUIET_EVENT_START); 19448 19449 return QDF_STATUS_SUCCESS; 19450 } 19451 #endif 19452 19453 /** 19454 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 19455 * @wmi_handle: wmi handle 19456 * @params: RxFilter params 19457 * 19458 * Return: QDF_STATUS_SUCCESS for success or error code 19459 */ 19460 static QDF_STATUS 19461 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 19462 struct vdev_pn_mgmt_rxfilter_params *params) 19463 { 19464 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 19465 wmi_buf_t buf; 19466 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 19467 19468 if (!is_service_enabled_tlv(wmi_handle, 19469 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 19470 wmi_err("Rx PN Replay Check not supported by target"); 19471 return QDF_STATUS_E_NOSUPPORT; 19472 } 19473 19474 buf = wmi_buf_alloc(wmi_handle, len); 19475 if (!buf) { 19476 wmi_err("wmi buf alloc failed"); 19477 return QDF_STATUS_E_NOMEM; 19478 } 19479 19480 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 19481 WMITLV_SET_HDR( 19482 &cmd->tlv_header, 19483 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 19484 WMITLV_GET_STRUCT_TLVLEN 19485 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 19486 19487 cmd->vdev_id = params->vdev_id; 19488 cmd->pn_rx_filter = params->pn_rxfilter; 19489 19490 if (wmi_unified_cmd_send(wmi_handle, buf, len, 19491 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 19492 wmi_err("Failed to send WMI command"); 19493 wmi_buf_free(buf); 19494 return QDF_STATUS_E_FAILURE; 19495 } 19496 19497 return QDF_STATUS_SUCCESS; 19498 } 19499 19500 static QDF_STATUS 19501 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19502 uint8_t *pdev_id, uint8_t *software_image, 19503 uint8_t *chip_info, 19504 uint32_t *pktlog_json_version) 19505 { 19506 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 19507 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 19508 19509 param_buf = 19510 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 19511 19512 event = param_buf->fixed_param; 19513 19514 if ((event->software_image[0] == '\0') || 19515 (event->chip_info[0] == '\0')) { 19516 *pdev_id = event->pdev_id; 19517 return QDF_STATUS_E_INVAL; 19518 } 19519 19520 qdf_mem_copy(software_image, event->software_image, 40); 19521 qdf_mem_copy(chip_info, event->chip_info, 40); 19522 *pktlog_json_version = event->pktlog_defs_json_version; 19523 *pdev_id = event->pdev_id; 19524 return QDF_STATUS_SUCCESS; 19525 } 19526 19527 #ifdef HEALTH_MON_SUPPORT 19528 /** 19529 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 19530 * fw 19531 * @wmi_handle: wmi handle 19532 * @evt_buf: pointer to event buffer 19533 * @params: health monitor params 19534 * 19535 * Return: QDF_STATUS_SUCCESS for success or error code 19536 */ 19537 static QDF_STATUS 19538 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 19539 void *evt_buf, 19540 struct wmi_health_mon_params *param) 19541 { 19542 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 19543 wmi_health_mon_init_done_fixed_param *event; 19544 19545 param_buf = 19546 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 19547 19548 event = param_buf->fixed_param; 19549 19550 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 19551 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 19552 param->initial_upload_period_ms = event->initial_upload_period_ms; 19553 param->read_index = 0; 19554 19555 return QDF_STATUS_SUCCESS; 19556 } 19557 #endif /* HEALTH_MON_SUPPORT */ 19558 19559 /** 19560 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 19561 * @wmi_handle: wmi handle 19562 * @evt_buf: pointer to event buffer 19563 * @pdev stats: Pointer to hold pdev telemetry stats 19564 * 19565 * Return: QDF_STATUS_SUCCESS for success or error code 19566 */ 19567 static QDF_STATUS 19568 extract_pdev_telemetry_stats_tlv( 19569 wmi_unified_t wmi_handle, void *evt_buf, 19570 struct wmi_host_pdev_telemetry_stats *pdev_stats) 19571 { 19572 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 19573 wmi_pdev_telemetry_stats *ev; 19574 19575 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 19576 19577 if (param_buf->pdev_telemetry_stats) { 19578 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 19579 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 19580 ev->avg_chan_lat_per_ac, 19581 sizeof(ev->avg_chan_lat_per_ac)); 19582 pdev_stats->estimated_air_time_per_ac = 19583 ev->estimated_air_time_per_ac; 19584 } 19585 19586 return QDF_STATUS_SUCCESS; 19587 } 19588 19589 static QDF_STATUS 19590 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 19591 struct set_rx_mac_filter *param) 19592 { 19593 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 19594 uint32_t len; 19595 wmi_buf_t buf; 19596 int ret; 19597 19598 if (!wmi_handle) { 19599 wmi_err("WMA context is invalid!"); 19600 return QDF_STATUS_E_INVAL; 19601 } 19602 19603 len = sizeof(*cmd); 19604 buf = wmi_buf_alloc(wmi_handle, len); 19605 if (!buf) { 19606 wmi_err("Failed allocate wmi buffer"); 19607 return QDF_STATUS_E_NOMEM; 19608 } 19609 19610 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 19611 wmi_buf_data(buf); 19612 19613 WMITLV_SET_HDR( 19614 &cmd->tlv_header, 19615 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 19616 WMITLV_GET_STRUCT_TLVLEN( 19617 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 19618 19619 cmd->vdev_id = param->vdev_id; 19620 cmd->freq = param->freq; 19621 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 19622 if (param->set) 19623 cmd->enable = 1; 19624 else 19625 cmd->enable = 0; 19626 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 19627 param->vdev_id, param->freq, param->set, 19628 QDF_MAC_ADDR_REF(param->mac)); 19629 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19630 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 19631 if (ret) { 19632 wmi_err("Failed to send action frame random mac cmd"); 19633 wmi_buf_free(buf); 19634 return QDF_STATUS_E_FAILURE; 19635 } 19636 19637 return QDF_STATUS_SUCCESS; 19638 } 19639 19640 struct wmi_ops tlv_ops = { 19641 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 19642 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 19643 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 19644 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 19645 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 19646 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 19647 .send_peer_param_cmd = send_peer_param_cmd_tlv, 19648 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 19649 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 19650 .send_peer_create_cmd = send_peer_create_cmd_tlv, 19651 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 19652 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 19653 .send_peer_rx_reorder_queue_setup_cmd = 19654 send_peer_rx_reorder_queue_setup_cmd_tlv, 19655 .send_peer_rx_reorder_queue_remove_cmd = 19656 send_peer_rx_reorder_queue_remove_cmd_tlv, 19657 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 19658 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 19659 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 19660 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 19661 .send_suspend_cmd = send_suspend_cmd_tlv, 19662 .send_resume_cmd = send_resume_cmd_tlv, 19663 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 19664 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 19665 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 19666 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 19667 .send_dbglog_cmd = send_dbglog_cmd_tlv, 19668 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 19669 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 19670 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 19671 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 19672 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 19673 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 19674 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 19675 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 19676 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 19677 .send_scan_start_cmd = send_scan_start_cmd_tlv, 19678 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 19679 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 19680 .send_mgmt_cmd = send_mgmt_cmd_tlv, 19681 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 19682 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 19683 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 19684 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 19685 .send_set_sta_uapsd_auto_trig_cmd = 19686 send_set_sta_uapsd_auto_trig_cmd_tlv, 19687 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 19688 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 19689 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 19690 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 19691 .send_lro_config_cmd = send_lro_config_cmd_tlv, 19692 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 19693 .send_probe_rsp_tmpl_send_cmd = 19694 send_probe_rsp_tmpl_send_cmd_tlv, 19695 .send_p2p_go_set_beacon_ie_cmd = 19696 send_p2p_go_set_beacon_ie_cmd_tlv, 19697 .send_setup_install_key_cmd = 19698 send_setup_install_key_cmd_tlv, 19699 .send_scan_probe_setoui_cmd = 19700 send_scan_probe_setoui_cmd_tlv, 19701 #ifdef IPA_OFFLOAD 19702 .send_ipa_offload_control_cmd = 19703 send_ipa_offload_control_cmd_tlv, 19704 #endif 19705 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 19706 .send_pno_start_cmd = send_pno_start_cmd_tlv, 19707 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 19708 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 19709 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 19710 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 19711 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 19712 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 19713 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 19714 .send_unified_ll_stats_get_sta_cmd = 19715 send_unified_ll_stats_get_sta_cmd_tlv, 19716 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 19717 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 19718 .send_congestion_cmd = send_congestion_cmd_tlv, 19719 .send_snr_request_cmd = send_snr_request_cmd_tlv, 19720 .send_snr_cmd = send_snr_cmd_tlv, 19721 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 19722 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 19723 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 19724 #endif 19725 #ifdef WLAN_SUPPORT_GREEN_AP 19726 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 19727 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 19728 .extract_green_ap_egap_status_info = 19729 extract_green_ap_egap_status_info_tlv, 19730 #endif 19731 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 19732 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 19733 #ifdef FEATURE_OEM_DATA 19734 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 19735 #endif 19736 #ifdef WLAN_FEATURE_CIF_CFR 19737 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 19738 #endif 19739 .send_dfs_phyerr_filter_offload_en_cmd = 19740 send_dfs_phyerr_filter_offload_en_cmd_tlv, 19741 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 19742 .send_process_dhcpserver_offload_cmd = 19743 send_process_dhcpserver_offload_cmd_tlv, 19744 .send_pdev_set_regdomain_cmd = 19745 send_pdev_set_regdomain_cmd_tlv, 19746 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 19747 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 19748 .save_fw_version_cmd = save_fw_version_cmd_tlv, 19749 .check_and_update_fw_version = 19750 check_and_update_fw_version_cmd_tlv, 19751 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 19752 .send_enable_specific_fw_logs_cmd = 19753 send_enable_specific_fw_logs_cmd_tlv, 19754 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 19755 .send_unit_test_cmd = send_unit_test_cmd_tlv, 19756 #ifdef FEATURE_WLAN_APF 19757 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 19758 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 19759 .send_apf_write_work_memory_cmd = 19760 wmi_send_apf_write_work_memory_cmd_tlv, 19761 .send_apf_read_work_memory_cmd = 19762 wmi_send_apf_read_work_memory_cmd_tlv, 19763 .extract_apf_read_memory_resp_event = 19764 wmi_extract_apf_read_memory_resp_event_tlv, 19765 #endif /* FEATURE_WLAN_APF */ 19766 .init_cmd_send = init_cmd_send_tlv, 19767 .send_vdev_set_custom_aggr_size_cmd = 19768 send_vdev_set_custom_aggr_size_cmd_tlv, 19769 .send_vdev_set_qdepth_thresh_cmd = 19770 send_vdev_set_qdepth_thresh_cmd_tlv, 19771 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 19772 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 19773 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 19774 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 19775 .send_periodic_chan_stats_config_cmd = 19776 send_periodic_chan_stats_config_cmd_tlv, 19777 #ifdef WLAN_IOT_SIM_SUPPORT 19778 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 19779 #endif 19780 .send_vdev_spectral_configure_cmd = 19781 send_vdev_spectral_configure_cmd_tlv, 19782 .send_vdev_spectral_enable_cmd = 19783 send_vdev_spectral_enable_cmd_tlv, 19784 #ifdef WLAN_CONV_SPECTRAL_ENABLE 19785 .extract_pdev_sscan_fw_cmd_fixed_param = 19786 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 19787 .extract_pdev_sscan_fft_bin_index = 19788 extract_pdev_sscan_fft_bin_index_tlv, 19789 .extract_pdev_spectral_session_chan_info = 19790 extract_pdev_spectral_session_chan_info_tlv, 19791 .extract_pdev_spectral_session_detector_info = 19792 extract_pdev_spectral_session_detector_info_tlv, 19793 .extract_spectral_caps_fixed_param = 19794 extract_spectral_caps_fixed_param_tlv, 19795 .extract_spectral_scan_bw_caps = 19796 extract_spectral_scan_bw_caps_tlv, 19797 .extract_spectral_fft_size_caps = 19798 extract_spectral_fft_size_caps_tlv, 19799 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 19800 .send_thermal_mitigation_param_cmd = 19801 send_thermal_mitigation_param_cmd_tlv, 19802 .send_process_update_edca_param_cmd = 19803 send_process_update_edca_param_cmd_tlv, 19804 .send_bss_color_change_enable_cmd = 19805 send_bss_color_change_enable_cmd_tlv, 19806 .send_coex_config_cmd = send_coex_config_cmd_tlv, 19807 .send_set_country_cmd = send_set_country_cmd_tlv, 19808 .send_addba_send_cmd = send_addba_send_cmd_tlv, 19809 .send_delba_send_cmd = send_delba_send_cmd_tlv, 19810 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 19811 .get_target_cap_from_service_ready = extract_service_ready_tlv, 19812 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 19813 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 19814 .extract_host_mem_req = extract_host_mem_req_tlv, 19815 .save_service_bitmap = save_service_bitmap_tlv, 19816 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 19817 .is_service_enabled = is_service_enabled_tlv, 19818 .save_fw_version = save_fw_version_in_service_ready_tlv, 19819 .ready_extract_init_status = ready_extract_init_status_tlv, 19820 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 19821 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 19822 .extract_ready_event_params = extract_ready_event_params_tlv, 19823 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 19824 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 19825 .extract_frame_pn_params = extract_frame_pn_params_tlv, 19826 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 19827 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 19828 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 19829 #ifdef FEATURE_WLAN_SCAN_PNO 19830 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 19831 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 19832 #endif 19833 .extract_unit_test = extract_unit_test_tlv, 19834 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 19835 .extract_bcn_stats = extract_bcn_stats_tlv, 19836 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 19837 .extract_chan_stats = extract_chan_stats_tlv, 19838 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 19839 .extract_profile_ctx = extract_profile_ctx_tlv, 19840 .extract_profile_data = extract_profile_data_tlv, 19841 .send_fw_test_cmd = send_fw_test_cmd_tlv, 19842 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 19843 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 19844 .extract_service_ready_ext = extract_service_ready_ext_tlv, 19845 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 19846 .extract_dbs_or_sbs_service_ready_ext2 = 19847 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 19848 .extract_hw_mode_cap_service_ready_ext = 19849 extract_hw_mode_cap_service_ready_ext_tlv, 19850 .extract_mac_phy_cap_service_ready_ext = 19851 extract_mac_phy_cap_service_ready_ext_tlv, 19852 .extract_mac_phy_cap_service_ready_ext2 = 19853 extract_mac_phy_cap_service_ready_ext2_tlv, 19854 .extract_reg_cap_service_ready_ext = 19855 extract_reg_cap_service_ready_ext_tlv, 19856 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 19857 .extract_dbr_ring_cap_service_ready_ext = 19858 extract_dbr_ring_cap_service_ready_ext_tlv, 19859 .extract_dbr_ring_cap_service_ready_ext2 = 19860 extract_dbr_ring_cap_service_ready_ext2_tlv, 19861 .extract_scan_radio_cap_service_ready_ext2 = 19862 extract_scan_radio_cap_service_ready_ext2_tlv, 19863 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 19864 .extract_sar_cap_service_ready_ext = 19865 extract_sar_cap_service_ready_ext_tlv, 19866 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 19867 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 19868 .extract_fips_event_data = extract_fips_event_data_tlv, 19869 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19870 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 19871 #endif 19872 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 19873 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 19874 #endif 19875 #ifdef WLAN_FEATURE_DISA 19876 .extract_encrypt_decrypt_resp_event = 19877 extract_encrypt_decrypt_resp_event_tlv, 19878 #endif 19879 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 19880 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 19881 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 19882 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 19883 #endif 19884 .extract_get_pn_data = extract_get_pn_data_tlv, 19885 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 19886 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 19887 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 19888 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 19889 #ifdef WLAN_FEATURE_DISA 19890 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 19891 #endif 19892 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 19893 .send_wlan_profile_hist_intvl_cmd = 19894 send_wlan_profile_hist_intvl_cmd_tlv, 19895 .is_management_record = is_management_record_tlv, 19896 .is_diag_event = is_diag_event_tlv, 19897 #ifdef WLAN_FEATURE_ACTION_OUI 19898 .send_action_oui_cmd = send_action_oui_cmd_tlv, 19899 #endif 19900 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 19901 #ifdef QCA_SUPPORT_AGILE_DFS 19902 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 19903 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 19904 #endif 19905 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 19906 .extract_reg_chan_list_update_event = 19907 extract_reg_chan_list_update_event_tlv, 19908 #ifdef CONFIG_BAND_6GHZ 19909 .extract_reg_chan_list_ext_update_event = 19910 extract_reg_chan_list_ext_update_event_tlv, 19911 #ifdef CONFIG_AFC_SUPPORT 19912 .extract_afc_event = extract_afc_event_tlv, 19913 #endif 19914 #endif 19915 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 19916 .extract_num_rf_characterization_entries = 19917 extract_num_rf_characterization_entries_tlv, 19918 .extract_rf_characterization_entries = 19919 extract_rf_characterization_entries_tlv, 19920 #endif 19921 .extract_chainmask_tables = 19922 extract_chainmask_tables_tlv, 19923 .extract_thermal_stats = extract_thermal_stats_tlv, 19924 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 19925 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 19926 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 19927 #ifdef DFS_COMPONENT_ENABLE 19928 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 19929 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 19930 .extract_dfs_radar_detection_event = 19931 extract_dfs_radar_detection_event_tlv, 19932 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 19933 #endif 19934 .convert_pdev_id_host_to_target = 19935 convert_host_pdev_id_to_target_pdev_id_legacy, 19936 .convert_pdev_id_target_to_host = 19937 convert_target_pdev_id_to_host_pdev_id_legacy, 19938 19939 .convert_host_pdev_id_to_target = 19940 convert_host_pdev_id_to_target_pdev_id, 19941 .convert_target_pdev_id_to_host = 19942 convert_target_pdev_id_to_host_pdev_id, 19943 19944 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 19945 19946 .convert_phy_id_host_to_target = 19947 convert_host_phy_id_to_target_phy_id_legacy, 19948 .convert_phy_id_target_to_host = 19949 convert_target_phy_id_to_host_phy_id_legacy, 19950 19951 .convert_host_phy_id_to_target = 19952 convert_host_phy_id_to_target_phy_id, 19953 .convert_target_phy_id_to_host = 19954 convert_target_phy_id_to_host_phy_id, 19955 19956 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 19957 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 19958 .extract_reg_11d_new_country_event = 19959 extract_reg_11d_new_country_event_tlv, 19960 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 19961 .extract_reg_ch_avoid_event = 19962 extract_reg_ch_avoid_event_tlv, 19963 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 19964 .extract_obss_detection_info = extract_obss_detection_info_tlv, 19965 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 19966 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 19967 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 19968 .wmi_check_command_params = wmitlv_check_command_tlv_params, 19969 .extract_comb_phyerr = extract_comb_phyerr_tlv, 19970 .extract_single_phyerr = extract_single_phyerr_tlv, 19971 #ifdef QCA_SUPPORT_CP_STATS 19972 .extract_cca_stats = extract_cca_stats_tlv, 19973 #endif 19974 .extract_esp_estimation_ev_param = 19975 extract_esp_estimation_ev_param_tlv, 19976 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 19977 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 19978 #ifdef OBSS_PD 19979 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 19980 .send_obss_spatial_reuse_set_def_thresh = 19981 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 19982 .send_self_srg_bss_color_bitmap_set = 19983 send_self_srg_bss_color_bitmap_set_cmd_tlv, 19984 .send_self_srg_partial_bssid_bitmap_set = 19985 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 19986 .send_self_srg_obss_color_enable_bitmap = 19987 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 19988 .send_self_srg_obss_bssid_enable_bitmap = 19989 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 19990 .send_self_non_srg_obss_color_enable_bitmap = 19991 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 19992 .send_self_non_srg_obss_bssid_enable_bitmap = 19993 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 19994 #endif 19995 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 19996 .extract_ctl_failsafe_check_ev_param = 19997 extract_ctl_failsafe_check_ev_param_tlv, 19998 #ifdef WIFI_POS_CONVERGED 19999 .extract_oem_response_param = extract_oem_response_param_tlv, 20000 #endif /* WIFI_POS_CONVERGED */ 20001 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20002 .extract_pasn_peer_create_req_event = 20003 extract_pasn_peer_create_req_event_tlv, 20004 .extract_pasn_peer_delete_req_event = 20005 extract_pasn_peer_delete_req_event_tlv, 20006 .send_rtt_pasn_auth_status_cmd = 20007 send_rtt_pasn_auth_status_cmd_tlv, 20008 .send_rtt_pasn_deauth_cmd = 20009 send_rtt_pasn_deauth_cmd_tlv, 20010 #endif 20011 #ifdef WLAN_MWS_INFO_DEBUGFS 20012 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 20013 #endif 20014 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 20015 #ifdef FEATURE_ANI_LEVEL_REQUEST 20016 .send_ani_level_cmd = send_ani_level_cmd_tlv, 20017 .extract_ani_level = extract_ani_level_tlv, 20018 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 20019 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 20020 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 20021 .extract_roam_result_stats = extract_roam_result_stats_tlv, 20022 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 20023 #ifdef WLAN_FEATURE_PKT_CAPTURE 20024 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 20025 #endif 20026 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20027 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 20028 #endif 20029 20030 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20031 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 20032 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 20033 .extract_time_sync_ftm_start_stop_event = 20034 extract_time_sync_ftm_start_stop_event_tlv, 20035 .extract_time_sync_ftm_offset_event = 20036 extract_time_sync_ftm_offset_event_tlv, 20037 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20038 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 20039 .send_injector_config_cmd = send_injector_config_cmd_tlv, 20040 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 20041 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 20042 #ifdef FEATURE_MEC_OFFLOAD 20043 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 20044 #endif 20045 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 20046 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 20047 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 20048 .extract_cp_stats_more_pending = 20049 extract_cp_stats_more_pending_tlv, 20050 .extract_halphy_stats_end_of_event = 20051 extract_halphy_stats_end_of_event_tlv, 20052 .extract_halphy_stats_event_count = 20053 extract_halphy_stats_event_count_tlv, 20054 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 20055 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 20056 .extract_pdev_csa_switch_count_status = 20057 extract_pdev_csa_switch_count_status_tlv, 20058 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 20059 #ifdef CONFIG_AFC_SUPPORT 20060 .send_afc_cmd = send_afc_cmd_tlv, 20061 #endif 20062 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 20063 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 20064 .send_vdev_set_ltf_key_seed_cmd = 20065 send_vdev_set_ltf_key_seed_cmd_tlv, 20066 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 20067 .send_set_halphy_cal = send_set_halphy_cal_tlv, 20068 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 20069 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20070 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 20071 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 20072 .send_mgmt_rx_reo_filter_config_cmd = 20073 send_mgmt_rx_reo_filter_config_cmd_tlv, 20074 #endif 20075 20076 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 20077 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 20078 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 20079 20080 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20081 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 20082 .extract_update_mac_address_event = 20083 extract_update_mac_address_event_tlv, 20084 #endif 20085 20086 #ifdef WLAN_FEATURE_11BE_MLO 20087 .extract_quiet_offload_event = 20088 extract_quiet_offload_event_tlv, 20089 #endif 20090 20091 #ifdef WLAN_SUPPORT_PPEDS 20092 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 20093 #endif /* WLAN_SUPPORT_PPEDS */ 20094 20095 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 20096 .extract_pktlog_decode_info_event = 20097 extract_pktlog_decode_info_event_tlv, 20098 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 20099 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 20100 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 20101 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 20102 #endif 20103 #ifdef WLAN_FEATURE_DBAM_CONFIG 20104 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 20105 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 20106 #endif 20107 #ifdef FEATURE_SET 20108 .feature_set_cmd_send = feature_set_cmd_send_tlv, 20109 #endif 20110 #ifdef HEALTH_MON_SUPPORT 20111 .extract_health_mon_init_done_info_event = 20112 extract_health_mon_init_done_info_event_tlv, 20113 #endif /* HEALTH_MON_SUPPORT */ 20114 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 20115 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 20116 }; 20117 20118 #ifdef WLAN_FEATURE_11BE_MLO 20119 static void populate_tlv_events_id_mlo(uint32_t *event_ids) 20120 { 20121 event_ids[wmi_mlo_setup_complete_event_id] = 20122 WMI_MLO_SETUP_COMPLETE_EVENTID; 20123 event_ids[wmi_mlo_teardown_complete_event_id] = 20124 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 20125 event_ids[wmi_mlo_link_set_active_resp_eventid] = 20126 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 20127 event_ids[wmi_vdev_quiet_offload_eventid] = 20128 WMI_QUIET_HANDLING_EVENTID; 20129 } 20130 #else /* WLAN_FEATURE_11BE_MLO */ 20131 static inline void populate_tlv_events_id_mlo(uint32_t *event_ids) 20132 { 20133 } 20134 #endif /* WLAN_FEATURE_11BE_MLO */ 20135 20136 /** 20137 * populate_tlv_event_id() - populates wmi event ids 20138 * 20139 * @param event_ids: Pointer to hold event ids 20140 * Return: None 20141 */ 20142 static void populate_tlv_events_id(uint32_t *event_ids) 20143 { 20144 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 20145 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 20146 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 20147 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20148 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 20149 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 20150 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 20151 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 20152 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 20153 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 20154 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 20155 event_ids[wmi_service_ready_ext_event_id] = 20156 WMI_SERVICE_READY_EXT_EVENTID; 20157 event_ids[wmi_service_ready_ext2_event_id] = 20158 WMI_SERVICE_READY_EXT2_EVENTID; 20159 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 20160 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 20161 event_ids[wmi_vdev_install_key_complete_event_id] = 20162 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 20163 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 20164 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 20165 20166 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 20167 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 20168 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 20169 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 20170 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 20171 event_ids[wmi_peer_estimated_linkspeed_event_id] = 20172 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 20173 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 20174 event_ids[wmi_peer_create_conf_event_id] = 20175 WMI_PEER_CREATE_CONF_EVENTID; 20176 event_ids[wmi_peer_delete_response_event_id] = 20177 WMI_PEER_DELETE_RESP_EVENTID; 20178 event_ids[wmi_peer_delete_all_response_event_id] = 20179 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 20180 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 20181 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 20182 event_ids[wmi_tbttoffset_update_event_id] = 20183 WMI_TBTTOFFSET_UPDATE_EVENTID; 20184 event_ids[wmi_ext_tbttoffset_update_event_id] = 20185 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 20186 event_ids[wmi_offload_bcn_tx_status_event_id] = 20187 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 20188 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 20189 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 20190 event_ids[wmi_mgmt_tx_completion_event_id] = 20191 WMI_MGMT_TX_COMPLETION_EVENTID; 20192 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 20193 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 20194 event_ids[wmi_tx_delba_complete_event_id] = 20195 WMI_TX_DELBA_COMPLETE_EVENTID; 20196 event_ids[wmi_tx_addba_complete_event_id] = 20197 WMI_TX_ADDBA_COMPLETE_EVENTID; 20198 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 20199 20200 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 20201 20202 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 20203 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 20204 20205 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 20206 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 20207 20208 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 20209 20210 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 20211 event_ids[wmi_p2p_lo_stop_event_id] = 20212 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 20213 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 20214 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 20215 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 20216 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 20217 event_ids[wmi_d0_wow_disable_ack_event_id] = 20218 WMI_D0_WOW_DISABLE_ACK_EVENTID; 20219 event_ids[wmi_wow_initial_wakeup_event_id] = 20220 WMI_WOW_INITIAL_WAKEUP_EVENTID; 20221 20222 event_ids[wmi_rtt_meas_report_event_id] = 20223 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 20224 event_ids[wmi_tsf_meas_report_event_id] = 20225 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 20226 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 20227 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 20228 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 20229 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 20230 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 20231 event_ids[wmi_diag_event_id_log_supported_event_id] = 20232 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 20233 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 20234 event_ids[wmi_nlo_scan_complete_event_id] = 20235 WMI_NLO_SCAN_COMPLETE_EVENTID; 20236 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 20237 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 20238 20239 event_ids[wmi_gtk_offload_status_event_id] = 20240 WMI_GTK_OFFLOAD_STATUS_EVENTID; 20241 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 20242 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 20243 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 20244 20245 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 20246 20247 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 20248 20249 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 20250 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 20251 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 20252 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 20253 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 20254 event_ids[wmi_wlan_profile_data_event_id] = 20255 WMI_WLAN_PROFILE_DATA_EVENTID; 20256 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 20257 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 20258 event_ids[wmi_vdev_get_keepalive_event_id] = 20259 WMI_VDEV_GET_KEEPALIVE_EVENTID; 20260 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 20261 20262 event_ids[wmi_diag_container_event_id] = 20263 WMI_DIAG_DATA_CONTAINER_EVENTID; 20264 20265 event_ids[wmi_host_auto_shutdown_event_id] = 20266 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 20267 20268 event_ids[wmi_update_whal_mib_stats_event_id] = 20269 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 20270 20271 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 20272 event_ids[wmi_update_vdev_rate_stats_event_id] = 20273 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 20274 20275 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 20276 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 20277 20278 /** Set OCB Sched Response, deprecated */ 20279 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 20280 20281 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 20282 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 20283 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 20284 20285 /* GPIO Event */ 20286 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 20287 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 20288 20289 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 20290 event_ids[wmi_rfkill_state_change_event_id] = 20291 WMI_RFKILL_STATE_CHANGE_EVENTID; 20292 20293 /* TDLS Event */ 20294 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 20295 20296 event_ids[wmi_batch_scan_enabled_event_id] = 20297 WMI_BATCH_SCAN_ENABLED_EVENTID; 20298 event_ids[wmi_batch_scan_result_event_id] = 20299 WMI_BATCH_SCAN_RESULT_EVENTID; 20300 /* OEM Event */ 20301 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 20302 event_ids[wmi_oem_meas_report_event_id] = 20303 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 20304 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 20305 20306 /* NAN Event */ 20307 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 20308 20309 /* LPI Event */ 20310 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 20311 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 20312 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 20313 20314 /* ExtScan events */ 20315 event_ids[wmi_extscan_start_stop_event_id] = 20316 WMI_EXTSCAN_START_STOP_EVENTID; 20317 event_ids[wmi_extscan_operation_event_id] = 20318 WMI_EXTSCAN_OPERATION_EVENTID; 20319 event_ids[wmi_extscan_table_usage_event_id] = 20320 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 20321 event_ids[wmi_extscan_cached_results_event_id] = 20322 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 20323 event_ids[wmi_extscan_wlan_change_results_event_id] = 20324 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 20325 event_ids[wmi_extscan_hotlist_match_event_id] = 20326 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 20327 event_ids[wmi_extscan_capabilities_event_id] = 20328 WMI_EXTSCAN_CAPABILITIES_EVENTID; 20329 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 20330 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 20331 20332 /* mDNS offload events */ 20333 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 20334 20335 /* SAP Authentication offload events */ 20336 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 20337 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 20338 20339 /** Out-of-context-of-bss (OCB) events */ 20340 event_ids[wmi_ocb_set_config_resp_event_id] = 20341 WMI_OCB_SET_CONFIG_RESP_EVENTID; 20342 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 20343 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 20344 event_ids[wmi_dcc_get_stats_resp_event_id] = 20345 WMI_DCC_GET_STATS_RESP_EVENTID; 20346 event_ids[wmi_dcc_update_ndl_resp_event_id] = 20347 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 20348 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 20349 /* System-On-Chip events */ 20350 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 20351 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 20352 event_ids[wmi_soc_hw_mode_transition_event_id] = 20353 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 20354 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 20355 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 20356 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 20357 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 20358 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 20359 #endif 20360 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 20361 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 20362 event_ids[wmi_vdev_ocac_complete_event_id] = 20363 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 20364 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 20365 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 20366 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 20367 #ifdef CONFIG_AFC_SUPPORT 20368 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 20369 #endif 20370 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 20371 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 20372 event_ids[wmi_peer_sta_ps_statechg_event_id] = 20373 WMI_PEER_STA_PS_STATECHG_EVENTID; 20374 event_ids[wmi_pdev_channel_hopping_event_id] = 20375 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 20376 event_ids[wmi_offchan_data_tx_completion_event] = 20377 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 20378 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 20379 event_ids[wmi_dfs_radar_detection_event_id] = 20380 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 20381 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 20382 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 20383 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 20384 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 20385 event_ids[wmi_service_available_event_id] = 20386 WMI_SERVICE_AVAILABLE_EVENTID; 20387 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 20388 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 20389 /* NDP events */ 20390 event_ids[wmi_ndp_initiator_rsp_event_id] = 20391 WMI_NDP_INITIATOR_RSP_EVENTID; 20392 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 20393 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 20394 event_ids[wmi_ndp_responder_rsp_event_id] = 20395 WMI_NDP_RESPONDER_RSP_EVENTID; 20396 event_ids[wmi_ndp_end_indication_event_id] = 20397 WMI_NDP_END_INDICATION_EVENTID; 20398 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 20399 event_ids[wmi_ndl_schedule_update_event_id] = 20400 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 20401 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 20402 20403 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 20404 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 20405 event_ids[wmi_pdev_chip_power_stats_event_id] = 20406 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 20407 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 20408 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 20409 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 20410 event_ids[wmi_apf_capability_info_event_id] = 20411 WMI_BPF_CAPABILIY_INFO_EVENTID; 20412 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 20413 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 20414 event_ids[wmi_report_rx_aggr_failure_event_id] = 20415 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 20416 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 20417 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 20418 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 20419 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 20420 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 20421 event_ids[wmi_pdev_hw_mode_transition_event_id] = 20422 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 20423 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 20424 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 20425 event_ids[wmi_coex_bt_activity_event_id] = 20426 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 20427 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 20428 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 20429 event_ids[wmi_radio_tx_power_level_stats_event_id] = 20430 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 20431 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 20432 event_ids[wmi_dma_buf_release_event_id] = 20433 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 20434 event_ids[wmi_sap_obss_detection_report_event_id] = 20435 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 20436 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 20437 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 20438 event_ids[wmi_obss_color_collision_report_event_id] = 20439 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 20440 event_ids[wmi_pdev_div_rssi_antid_event_id] = 20441 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 20442 #ifdef WLAN_SUPPORT_TWT 20443 event_ids[wmi_twt_enable_complete_event_id] = 20444 WMI_TWT_ENABLE_COMPLETE_EVENTID; 20445 event_ids[wmi_twt_disable_complete_event_id] = 20446 WMI_TWT_DISABLE_COMPLETE_EVENTID; 20447 event_ids[wmi_twt_add_dialog_complete_event_id] = 20448 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 20449 event_ids[wmi_twt_del_dialog_complete_event_id] = 20450 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 20451 event_ids[wmi_twt_pause_dialog_complete_event_id] = 20452 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 20453 event_ids[wmi_twt_resume_dialog_complete_event_id] = 20454 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 20455 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 20456 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 20457 event_ids[wmi_twt_session_stats_event_id] = 20458 WMI_TWT_SESSION_STATS_EVENTID; 20459 event_ids[wmi_twt_notify_event_id] = 20460 WMI_TWT_NOTIFY_EVENTID; 20461 event_ids[wmi_twt_ack_complete_event_id] = 20462 WMI_TWT_ACK_EVENTID; 20463 #endif 20464 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 20465 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 20466 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 20467 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 20468 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 20469 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 20470 event_ids[wmi_pdev_interop_issues_ap_event_id] = 20471 WMI_PDEV_RAP_INFO_EVENTID; 20472 #endif 20473 #ifdef AST_HKV1_WORKAROUND 20474 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 20475 #endif 20476 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 20477 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 20478 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 20479 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 20480 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 20481 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 20482 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 20483 event_ids[wmi_pdev_cold_boot_cal_event_id] = 20484 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 20485 #ifdef WLAN_MWS_INFO_DEBUGFS 20486 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 20487 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 20488 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 20489 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 20490 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 20491 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 20492 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 20493 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 20494 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 20495 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 20496 #endif 20497 event_ids[wmi_coex_report_antenna_isolation_event_id] = 20498 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 20499 event_ids[wmi_peer_ratecode_list_event_id] = 20500 WMI_PEER_RATECODE_LIST_EVENTID; 20501 event_ids[wmi_chan_rf_characterization_info_event_id] = 20502 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 20503 event_ids[wmi_roam_auth_offload_event_id] = 20504 WMI_ROAM_PREAUTH_START_EVENTID; 20505 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 20506 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 20507 event_ids[wmi_motion_det_base_line_host_eventid] = 20508 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 20509 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 20510 event_ids[wmi_peer_tx_pn_response_event_id] = 20511 WMI_PEER_TX_PN_RESPONSE_EVENTID; 20512 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 20513 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 20514 event_ids[wmi_mgmt_offload_data_event_id] = 20515 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 20516 event_ids[wmi_nan_dmesg_event_id] = 20517 WMI_NAN_DMESG_EVENTID; 20518 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 20519 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 20520 event_ids[wmi_roam_pmkid_request_event_id] = 20521 WMI_ROAM_PMKID_REQUEST_EVENTID; 20522 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20523 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 20524 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 20525 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 20526 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 20527 #endif 20528 event_ids[wmi_roam_scan_chan_list_id] = 20529 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 20530 event_ids[wmi_muedca_params_config_eventid] = 20531 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 20532 event_ids[wmi_pdev_sscan_fw_param_eventid] = 20533 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 20534 event_ids[wmi_roam_cap_report_event_id] = 20535 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 20536 event_ids[wmi_vdev_bcn_latency_event_id] = 20537 WMI_VDEV_BCN_LATENCY_EVENTID; 20538 event_ids[wmi_vdev_disconnect_event_id] = 20539 WMI_VDEV_DISCONNECT_EVENTID; 20540 event_ids[wmi_peer_create_conf_event_id] = 20541 WMI_PEER_CREATE_CONF_EVENTID; 20542 event_ids[wmi_pdev_cp_fwstats_eventid] = 20543 WMI_CTRL_PATH_STATS_EVENTID; 20544 event_ids[wmi_pdev_halphy_fwstats_eventid] = 20545 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 20546 event_ids[wmi_vdev_send_big_data_p2_eventid] = 20547 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 20548 event_ids[wmi_pdev_get_dpd_status_event_id] = 20549 WMI_PDEV_GET_DPD_STATUS_EVENTID; 20550 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20551 event_ids[wmi_vdev_smart_monitor_event_id] = 20552 WMI_VDEV_SMART_MONITOR_EVENTID; 20553 #endif 20554 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 20555 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 20556 event_ids[wmi_pdev_set_halphy_cal_event_id] = 20557 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 20558 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 20559 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 20560 #ifdef WLAN_MGMT_RX_REO_SUPPORT 20561 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 20562 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 20563 #endif 20564 populate_tlv_events_id_mlo(event_ids); 20565 event_ids[wmi_roam_frame_event_id] = 20566 WMI_ROAM_FRAME_EVENTID; 20567 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 20568 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 20569 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 20570 #endif 20571 #ifdef WLAN_FEATURE_MCC_QUOTA 20572 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 20573 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 20574 #endif 20575 event_ids[wmi_peer_rx_pn_response_event_id] = 20576 WMI_PEER_RX_PN_RESPONSE_EVENTID; 20577 event_ids[wmi_extract_pktlog_decode_info_eventid] = 20578 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 20579 #ifdef QCA_RSSI_DB2DBM 20580 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 20581 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 20582 #endif 20583 #ifdef MULTI_CLIENT_LL_SUPPORT 20584 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 20585 #endif 20586 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20587 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 20588 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 20589 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 20590 WMI_RTT_PASN_PEER_DELETE_EVENTID; 20591 #endif 20592 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 20593 event_ids[wmi_get_roam_vendor_control_param_event_id] = 20594 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 20595 #endif 20596 #ifdef WLAN_FEATURE_DBAM_CONFIG 20597 event_ids[wmi_coex_dbam_complete_event_id] = 20598 WMI_COEX_DBAM_COMPLETE_EVENTID; 20599 #endif 20600 event_ids[wmi_spectral_capabilities_eventid] = 20601 WMI_SPECTRAL_CAPABILITIES_EVENTID; 20602 #ifdef WLAN_FEATURE_COAP 20603 event_ids[wmi_wow_coap_buf_info_eventid] = 20604 WMI_WOW_COAP_BUF_INFO_EVENTID; 20605 #endif 20606 #ifdef HEALTH_MON_SUPPORT 20607 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 20608 WMI_HEALTH_MON_INIT_DONE_EVENTID; 20609 #endif /* HEALTH_MON_SUPPORT */ 20610 } 20611 20612 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 20613 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 20614 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20615 { 20616 wmi_service[wmi_service_get_station_in_ll_stats_req] = 20617 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 20618 } 20619 #else 20620 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20621 { 20622 } 20623 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 20624 #else 20625 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 20626 { 20627 } 20628 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 20629 20630 #ifdef WLAN_FEATURE_11BE_MLO 20631 static void populate_tlv_service_mlo(uint32_t *wmi_service) 20632 { 20633 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 20634 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 20635 } 20636 #else /* WLAN_FEATURE_11BE_MLO */ 20637 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 20638 { 20639 } 20640 #endif /* WLAN_FEATURE_11BE_MLO */ 20641 20642 /** 20643 * populate_tlv_service() - populates wmi services 20644 * 20645 * @param wmi_service: Pointer to hold wmi_service 20646 * Return: None 20647 */ 20648 static void populate_tlv_service(uint32_t *wmi_service) 20649 { 20650 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 20651 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 20652 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 20653 wmi_service[wmi_service_roam_scan_offload] = 20654 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 20655 wmi_service[wmi_service_bcn_miss_offload] = 20656 WMI_SERVICE_BCN_MISS_OFFLOAD; 20657 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 20658 wmi_service[wmi_service_sta_advanced_pwrsave] = 20659 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 20660 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 20661 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 20662 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 20663 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 20664 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 20665 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 20666 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 20667 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 20668 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 20669 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 20670 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 20671 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 20672 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 20673 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 20674 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 20675 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 20676 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 20677 wmi_service[wmi_service_packet_power_save] = 20678 WMI_SERVICE_PACKET_POWER_SAVE; 20679 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 20680 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 20681 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 20682 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 20683 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 20684 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 20685 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 20686 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 20687 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 20688 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 20689 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 20690 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 20691 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 20692 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 20693 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 20694 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 20695 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 20696 wmi_service[wmi_service_mcc_bcn_interval_change] = 20697 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 20698 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 20699 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 20700 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 20701 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 20702 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 20703 wmi_service[wmi_service_lte_ant_share_support] = 20704 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 20705 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 20706 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 20707 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 20708 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 20709 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 20710 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 20711 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 20712 wmi_service[wmi_service_bcn_txrate_override] = 20713 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 20714 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 20715 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 20716 wmi_service[wmi_service_estimate_linkspeed] = 20717 WMI_SERVICE_ESTIMATE_LINKSPEED; 20718 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 20719 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 20720 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 20721 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 20722 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 20723 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 20724 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 20725 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 20726 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 20727 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 20728 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 20729 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 20730 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 20731 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 20732 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 20733 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 20734 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 20735 wmi_service[wmi_service_sap_auth_offload] = 20736 WMI_SERVICE_SAP_AUTH_OFFLOAD; 20737 wmi_service[wmi_service_dual_band_simultaneous_support] = 20738 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 20739 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 20740 wmi_service[wmi_service_ap_arpns_offload] = 20741 WMI_SERVICE_AP_ARPNS_OFFLOAD; 20742 wmi_service[wmi_service_per_band_chainmask_support] = 20743 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 20744 wmi_service[wmi_service_packet_filter_offload] = 20745 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 20746 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 20747 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 20748 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 20749 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 20750 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 20751 wmi_service[wmi_service_multiple_vdev_restart] = 20752 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 20753 wmi_service[wmi_service_smart_antenna_sw_support] = 20754 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 20755 wmi_service[wmi_service_smart_antenna_hw_support] = 20756 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 20757 20758 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 20759 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 20760 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 20761 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 20762 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 20763 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 20764 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 20765 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 20766 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 20767 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 20768 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 20769 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 20770 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 20771 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 20772 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 20773 wmi_service[wmi_service_periodic_chan_stat_support] = 20774 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 20775 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 20776 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 20777 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 20778 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 20779 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 20780 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 20781 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 20782 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 20783 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 20784 wmi_service[wmi_service_unified_wow_capability] = 20785 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 20786 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 20787 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 20788 wmi_service[wmi_service_sync_delete_cmds] = 20789 WMI_SERVICE_SYNC_DELETE_CMDS; 20790 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 20791 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 20792 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 20793 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 20794 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 20795 wmi_service[wmi_service_deprecated_replace] = 20796 WMI_SERVICE_DEPRECATED_REPLACE; 20797 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 20798 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 20799 wmi_service[wmi_service_enhanced_mcast_filter] = 20800 WMI_SERVICE_ENHANCED_MCAST_FILTER; 20801 wmi_service[wmi_service_half_rate_quarter_rate_support] = 20802 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 20803 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 20804 wmi_service[wmi_service_p2p_listen_offload_support] = 20805 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 20806 wmi_service[wmi_service_mark_first_wakeup_packet] = 20807 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 20808 wmi_service[wmi_service_multiple_mcast_filter_set] = 20809 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 20810 wmi_service[wmi_service_host_managed_rx_reorder] = 20811 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 20812 wmi_service[wmi_service_flash_rdwr_support] = 20813 WMI_SERVICE_FLASH_RDWR_SUPPORT; 20814 wmi_service[wmi_service_wlan_stats_report] = 20815 WMI_SERVICE_WLAN_STATS_REPORT; 20816 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 20817 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 20818 wmi_service[wmi_service_dfs_phyerr_offload] = 20819 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 20820 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 20821 wmi_service[wmi_service_fw_mem_dump_support] = 20822 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 20823 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 20824 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 20825 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 20826 wmi_service[wmi_service_hw_data_filtering] = 20827 WMI_SERVICE_HW_DATA_FILTERING; 20828 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 20829 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 20830 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 20831 wmi_service[wmi_service_extended_nss_support] = 20832 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 20833 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 20834 wmi_service[wmi_service_bcn_offload_start_stop_support] = 20835 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 20836 wmi_service[wmi_service_offchan_data_tid_support] = 20837 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 20838 wmi_service[wmi_service_support_dma] = 20839 WMI_SERVICE_SUPPORT_DIRECT_DMA; 20840 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 20841 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 20842 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 20843 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 20844 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 20845 wmi_service[wmi_service_11k_neighbour_report_support] = 20846 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 20847 wmi_service[wmi_service_ap_obss_detection_offload] = 20848 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 20849 wmi_service[wmi_service_bss_color_offload] = 20850 WMI_SERVICE_BSS_COLOR_OFFLOAD; 20851 wmi_service[wmi_service_gmac_offload_support] = 20852 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 20853 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 20854 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 20855 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 20856 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 20857 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 20858 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 20859 wmi_service[wmi_service_listen_interval_offload_support] = 20860 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 20861 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 20862 wmi_service[wmi_service_obss_spatial_reuse] = 20863 WMI_SERVICE_OBSS_SPATIAL_REUSE; 20864 wmi_service[wmi_service_per_vdev_chain_support] = 20865 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 20866 wmi_service[wmi_service_new_htt_msg_format] = 20867 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 20868 wmi_service[wmi_service_peer_unmap_cnf_support] = 20869 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 20870 wmi_service[wmi_service_beacon_reception_stats] = 20871 WMI_SERVICE_BEACON_RECEPTION_STATS; 20872 wmi_service[wmi_service_vdev_latency_config] = 20873 WMI_SERVICE_VDEV_LATENCY_CONFIG; 20874 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 20875 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 20876 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 20877 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 20878 wmi_service[wmi_service_nan_disable_support] = 20879 WMI_SERVICE_NAN_DISABLE_SUPPORT; 20880 wmi_service[wmi_service_sta_plus_sta_support] = 20881 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 20882 wmi_service[wmi_service_hw_db2dbm_support] = 20883 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 20884 wmi_service[wmi_service_wlm_stats_support] = 20885 WMI_SERVICE_WLM_STATS_REQUEST; 20886 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 20887 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 20888 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 20889 wmi_service[wmi_service_cfr_capture_support] = 20890 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 20891 wmi_service[wmi_service_bcast_twt_support] = 20892 WMI_SERVICE_BROADCAST_TWT; 20893 wmi_service[wmi_service_wpa3_ft_sae_support] = 20894 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 20895 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 20896 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 20897 wmi_service[wmi_service_ft_fils] = 20898 WMI_SERVICE_WPA3_FT_FILS; 20899 wmi_service[wmi_service_adaptive_11r_support] = 20900 WMI_SERVICE_ADAPTIVE_11R_ROAM; 20901 wmi_service[wmi_service_tx_compl_tsf64] = 20902 WMI_SERVICE_TX_COMPL_TSF64; 20903 wmi_service[wmi_service_data_stall_recovery_support] = 20904 WMI_SERVICE_DSM_ROAM_FILTER; 20905 wmi_service[wmi_service_vdev_delete_all_peer] = 20906 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 20907 wmi_service[wmi_service_three_way_coex_config_legacy] = 20908 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 20909 wmi_service[wmi_service_rx_fse_support] = 20910 WMI_SERVICE_RX_FSE_SUPPORT; 20911 wmi_service[wmi_service_sae_roam_support] = 20912 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 20913 wmi_service[wmi_service_owe_roam_support] = 20914 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 20915 wmi_service[wmi_service_6ghz_support] = 20916 WMI_SERVICE_6GHZ_SUPPORT; 20917 wmi_service[wmi_service_bw_165mhz_support] = 20918 WMI_SERVICE_BW_165MHZ_SUPPORT; 20919 wmi_service[wmi_service_bw_restricted_80p80_support] = 20920 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 20921 wmi_service[wmi_service_packet_capture_support] = 20922 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 20923 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 20924 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 20925 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 20926 wmi_service[wmi_service_multiple_vdev_restart_ext] = 20927 WMI_SERVICE_UNAVAILABLE; 20928 wmi_service[wmi_service_time_sync_ftm] = 20929 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 20930 wmi_service[wmi_service_nss_ratio_to_host_support] = 20931 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 20932 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 20933 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 20934 wmi_service[wmi_beacon_protection_support] = 20935 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 20936 wmi_service[wmi_service_sta_nan_ndi_four_port] = 20937 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 20938 wmi_service[wmi_service_host_scan_stop_vdev_all] = 20939 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 20940 wmi_service[wmi_support_extend_address] = 20941 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 20942 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 20943 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 20944 wmi_service[wmi_service_suiteb_roam_support] = 20945 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 20946 wmi_service[wmi_service_no_interband_mcc_support] = 20947 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 20948 wmi_service[wmi_service_dual_sta_roam_support] = 20949 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 20950 wmi_service[wmi_service_peer_create_conf] = 20951 WMI_SERVICE_PEER_CREATE_CONF; 20952 wmi_service[wmi_service_configure_roam_trigger_param_support] = 20953 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 20954 wmi_service[wmi_service_5dot9_ghz_support] = 20955 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 20956 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 20957 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 20958 wmi_service[wmi_service_cfr_capture_count_support] = 20959 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 20960 wmi_service[wmi_service_ocv_support] = 20961 WMI_SERVICE_OCV_SUPPORT; 20962 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 20963 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 20964 wmi_service[wmi_service_thermal_multi_client_support] = 20965 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 20966 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 20967 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 20968 wmi_service[wmi_service_fse_cmem_alloc_support] = 20969 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 20970 wmi_service[wmi_service_scan_conf_per_ch_support] = 20971 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 20972 wmi_service[wmi_service_csa_beacon_template] = 20973 WMI_SERVICE_CSA_BEACON_TEMPLATE; 20974 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 20975 wmi_service[wmi_service_rtt_11az_ntb_support] = 20976 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 20977 wmi_service[wmi_service_rtt_11az_tb_support] = 20978 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 20979 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 20980 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 20981 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 20982 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 20983 #endif 20984 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 20985 wmi_service[wmi_service_igmp_offload_support] = 20986 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 20987 #endif 20988 20989 #ifdef FEATURE_WLAN_TDLS 20990 #ifdef WLAN_FEATURE_11AX 20991 wmi_service[wmi_service_tdls_ax_support] = 20992 WMI_SERVICE_11AX_TDLS_SUPPORT; 20993 wmi_service[wmi_service_tdls_6g_support] = 20994 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 20995 #endif 20996 wmi_service[wmi_service_tdls_wideband_support] = 20997 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 20998 #endif 20999 21000 #ifdef WLAN_SUPPORT_TWT 21001 wmi_service[wmi_service_twt_bcast_req_support] = 21002 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 21003 wmi_service[wmi_service_twt_bcast_resp_support] = 21004 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 21005 wmi_service[wmi_service_twt_nudge] = 21006 WMI_SERVICE_TWT_NUDGE; 21007 wmi_service[wmi_service_all_twt] = 21008 WMI_SERVICE_TWT_ALL_DIALOG_ID; 21009 wmi_service[wmi_service_twt_statistics] = 21010 WMI_SERVICE_TWT_STATS; 21011 #endif 21012 wmi_service[wmi_service_spectral_scan_disabled] = 21013 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 21014 wmi_service[wmi_service_sae_eapol_offload_support] = 21015 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 21016 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 21017 21018 wmi_service[wmi_service_wapi_concurrency_supported] = 21019 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 21020 wmi_service[wmi_service_sap_connected_d3_wow] = 21021 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21022 wmi_service[wmi_service_go_connected_d3_wow] = 21023 WMI_SERVICE_SAP_CONNECTED_D3WOW; 21024 wmi_service[wmi_service_ext_tpc_reg_support] = 21025 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 21026 wmi_service[wmi_service_ndi_txbf_support] = 21027 WMI_SERVICE_NDI_TXBF_SUPPORT; 21028 wmi_service[wmi_service_reg_cc_ext_event_support] = 21029 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 21030 wmi_service[wmi_service_bang_radar_320_support] = 21031 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 21032 #if defined(CONFIG_BAND_6GHZ) 21033 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 21034 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 21035 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 21036 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 21037 #endif 21038 wmi_service[wmi_service_dcs_awgn_int_support] = 21039 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 21040 wmi_populate_service_11be(wmi_service); 21041 21042 #ifdef WLAN_FEATURE_BIG_DATA_STATS 21043 wmi_service[wmi_service_big_data_support] = 21044 WMI_SERVICE_BIG_DATA_SUPPORT; 21045 #endif 21046 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 21047 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 21048 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 21049 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 21050 wmi_service[wmi_service_halphy_cal_status] = 21051 WMI_SERVICE_HALPHY_CAL_STATUS; 21052 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 21053 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 21054 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 21055 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 21056 wmi_service[wmi_service_ema_multiple_group_supported] = 21057 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 21058 wmi_service[wmi_service_large_beacon_supported] = 21059 WMI_SERVICE_LARGE_BEACON_SUPPORT; 21060 wmi_service[wmi_service_aoa_for_rcc_supported] = 21061 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 21062 #ifdef WLAN_FEATURE_P2P_P2P_STA 21063 wmi_service[wmi_service_p2p_p2p_cc_support] = 21064 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 21065 #endif 21066 #ifdef THERMAL_STATS_SUPPORT 21067 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 21068 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 21069 #endif 21070 wmi_service[wmi_service_hw_mode_policy_offload_support] = 21071 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 21072 wmi_service[wmi_service_mgmt_rx_reo_supported] = 21073 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 21074 wmi_service[wmi_service_phy_dma_byte_swap_support] = 21075 WMI_SERVICE_UNAVAILABLE; 21076 wmi_service[wmi_service_spectral_session_info_support] = 21077 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 21078 wmi_service[wmi_service_umac_hang_recovery_support] = 21079 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 21080 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 21081 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21082 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 21083 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 21084 #endif 21085 wmi_service[wmi_service_probe_all_bw_support] = 21086 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 21087 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 21088 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 21089 #ifdef QCA_UNDECODED_METADATA_SUPPORT 21090 wmi_service[wmi_service_fp_phy_err_filter_support] = 21091 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 21092 #endif 21093 populate_tlv_service_mlo(wmi_service); 21094 wmi_service[wmi_service_pdev_rate_config_support] = 21095 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 21096 wmi_service[wmi_service_multi_peer_group_cmd_support] = 21097 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 21098 #ifdef WLAN_FEATURE_11BE 21099 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 21100 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 21101 #endif 21102 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 21103 wmi_service[wmi_service_combined_set_param_support] = 21104 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 21105 #endif 21106 wmi_service[wmi_service_pn_replay_check_support] = 21107 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 21108 #ifdef QCA_RSSI_DB2DBM 21109 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 21110 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 21111 #endif 21112 wmi_service[wmi_service_pktlog_decode_info_support] = 21113 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 21114 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21115 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 21116 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 21117 #endif 21118 #ifdef MULTI_CLIENT_LL_SUPPORT 21119 wmi_service[wmi_service_configure_multi_client_ll_support] = 21120 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 21121 #endif 21122 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 21123 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 21124 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 21125 #endif 21126 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 21127 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 21128 #ifdef FEATURE_SET 21129 wmi_service[wmi_service_feature_set_event_support] = 21130 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 21131 #endif 21132 #ifdef WLAN_FEATURE_SR 21133 wmi_service[wmi_service_obss_per_packet_sr_support] = 21134 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 21135 #endif 21136 } 21137 21138 /** 21139 * wmi_ocb_ut_attach() - Attach OCB test framework 21140 * @wmi_handle: wmi handle 21141 * 21142 * Return: None 21143 */ 21144 #ifdef WLAN_OCB_UT 21145 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 21146 #else 21147 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 21148 { 21149 return; 21150 } 21151 #endif 21152 21153 /** 21154 * wmi_tlv_attach() - Attach TLV APIs 21155 * 21156 * Return: None 21157 */ 21158 void wmi_tlv_attach(wmi_unified_t wmi_handle) 21159 { 21160 wmi_handle->ops = &tlv_ops; 21161 wmi_ocb_ut_attach(wmi_handle); 21162 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 21163 #ifdef WMI_INTERFACE_EVENT_LOGGING 21164 /* Skip saving WMI_CMD_HDR and TLV HDR */ 21165 wmi_handle->soc->buf_offset_command = 8; 21166 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 21167 wmi_handle->soc->buf_offset_event = 4; 21168 #endif 21169 populate_tlv_events_id(wmi_handle->wmi_events); 21170 populate_tlv_service(wmi_handle->services); 21171 wmi_wds_attach_tlv(wmi_handle); 21172 wmi_twt_attach_tlv(wmi_handle); 21173 wmi_extscan_attach_tlv(wmi_handle); 21174 wmi_smart_ant_attach_tlv(wmi_handle); 21175 wmi_dbr_attach_tlv(wmi_handle); 21176 wmi_atf_attach_tlv(wmi_handle); 21177 wmi_ap_attach_tlv(wmi_handle); 21178 wmi_bcn_attach_tlv(wmi_handle); 21179 wmi_ocb_attach_tlv(wmi_handle); 21180 wmi_nan_attach_tlv(wmi_handle); 21181 wmi_p2p_attach_tlv(wmi_handle); 21182 wmi_interop_issues_ap_attach_tlv(wmi_handle); 21183 wmi_dcs_attach_tlv(wmi_handle); 21184 wmi_roam_attach_tlv(wmi_handle); 21185 wmi_concurrency_attach_tlv(wmi_handle); 21186 wmi_pmo_attach_tlv(wmi_handle); 21187 wmi_sta_attach_tlv(wmi_handle); 21188 wmi_11ax_bss_color_attach_tlv(wmi_handle); 21189 wmi_fwol_attach_tlv(wmi_handle); 21190 wmi_vdev_attach_tlv(wmi_handle); 21191 wmi_cfr_attach_tlv(wmi_handle); 21192 wmi_cp_stats_attach_tlv(wmi_handle); 21193 wmi_gpio_attach_tlv(wmi_handle); 21194 wmi_11be_attach_tlv(wmi_handle); 21195 wmi_coap_attach_tlv(wmi_handle); 21196 } 21197 qdf_export_symbol(wmi_tlv_attach); 21198 21199 /** 21200 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 21201 * 21202 * Return: None 21203 */ 21204 void wmi_tlv_init(void) 21205 { 21206 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 21207 } 21208