1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "wmi_unified_api.h" 20 #include "wmi.h" 21 #include "wmi_version.h" 22 #include "wmi_unified_priv.h" 23 #include "wmi_version_whitelist.h" 24 #include <qdf_module.h> 25 #include <wlan_defs.h> 26 #include <wlan_cmn.h> 27 #include <htc_services.h> 28 #ifdef FEATURE_WLAN_APF 29 #include "wmi_unified_apf_tlv.h" 30 #endif 31 #ifdef WLAN_FEATURE_ACTION_OUI 32 #include "wmi_unified_action_oui_tlv.h" 33 #endif 34 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 35 #include "wlan_pmo_hw_filter_public_struct.h" 36 #endif 37 #include <wlan_utility.h> 38 #ifdef WLAN_SUPPORT_GREEN_AP 39 #include "wlan_green_ap_api.h" 40 #endif 41 42 #include "wmi_unified_twt_api.h" 43 #include "wmi_unified_wds_api.h" 44 45 #ifdef WLAN_POLICY_MGR_ENABLE 46 #include "wlan_policy_mgr_public_struct.h" 47 #endif 48 49 #ifdef WMI_SMART_ANT_SUPPORT 50 #include "wmi_unified_smart_ant_api.h" 51 #endif 52 53 #ifdef WMI_DBR_SUPPORT 54 #include "wmi_unified_dbr_api.h" 55 #endif 56 57 #ifdef WMI_ATF_SUPPORT 58 #include "wmi_unified_atf_api.h" 59 #endif 60 61 #ifdef WMI_AP_SUPPORT 62 #include "wmi_unified_ap_api.h" 63 #endif 64 65 #include <wmi_unified_vdev_api.h> 66 #include <wmi_unified_vdev_tlv.h> 67 #include <wmi_unified_11be_tlv.h> 68 69 /* 70 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 71 * then channel_list may fill the upper 12 bits with channel flags, 72 * while using only the lower 20 bits for channel frequency. 73 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 74 * then channel_list only holds the frequency value. 75 */ 76 #define CHAN_LIST_FLAG_MASK_POS 20 77 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 78 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 79 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 80 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 81 82 /* HTC service ids for WMI for multi-radio */ 83 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 84 WMI_CONTROL_SVC_WMAC1, 85 WMI_CONTROL_SVC_WMAC2}; 86 87 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 88 /*Populate peer_param array whose index as host id and 89 *value as target id 90 */ 91 static const uint32_t peer_param_tlv[] = { 92 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 93 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 94 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 95 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 96 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 97 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 98 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 99 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 100 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 101 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 102 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 103 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 104 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 105 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 106 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 107 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 108 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 109 [WMI_HOST_PEER_SET_MU_WHITELIST] = WMI_PEER_SET_MU_WHITELIST, 110 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 111 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 112 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 113 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 114 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 115 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 116 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 117 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 118 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 119 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 120 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 121 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 122 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 123 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 124 }; 125 126 /** 127 * Populate pdev_param_value whose index is host param and value is target 128 * param 129 */ 130 static const uint32_t pdev_param_tlv[] = { 131 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 132 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 133 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 134 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 135 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 136 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 137 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 138 [wmi_pdev_param_resmgr_offchan_mode] = 139 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 140 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 141 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 142 [wmi_pdev_param_non_agg_sw_retry_th] = 143 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 144 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 145 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 146 [wmi_pdev_param_ac_aggrsize_scaling] = 147 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 148 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 149 [wmi_pdev_param_ltr_ac_latency_be] = 150 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 151 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 152 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 153 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 154 [wmi_pdev_param_ltr_ac_latency_timeout] = 155 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 156 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 157 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 158 [wmi_pdev_param_ltr_tx_activity_timeout] = 159 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 160 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 161 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 162 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 163 [wmi_pdev_param_pcielp_txbuf_watermark] = 164 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 165 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 166 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 167 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 168 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 169 [wmi_pdev_param_pdev_stats_update_period] = 170 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 171 [wmi_pdev_param_vdev_stats_update_period] = 172 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 173 [wmi_pdev_param_peer_stats_update_period] = 174 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 175 [wmi_pdev_param_bcnflt_stats_update_period] = 176 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 177 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 178 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 179 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 180 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 181 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 182 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 183 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 184 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 185 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 186 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 187 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 188 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 189 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 190 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 191 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 192 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 193 [wmi_pdev_param_low_power_rf_enable] = 194 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 195 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 196 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 197 [wmi_pdev_param_power_collapse_enable] = 198 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 199 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 200 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 201 [wmi_pdev_param_audio_over_wlan_latency] = 202 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 203 [wmi_pdev_param_audio_over_wlan_enable] = 204 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 205 [wmi_pdev_param_whal_mib_stats_update_enable] = 206 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 207 [wmi_pdev_param_vdev_rate_stats_update_period] = 208 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 209 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 210 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 211 [wmi_pdev_param_adaptive_early_rx_enable] = 212 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 213 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 214 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 215 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 216 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 217 [wmi_pdev_param_early_rx_fix_sleep_slop] = 218 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 219 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 220 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 221 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 222 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 223 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 224 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 225 [wmi_pdev_param_bto_fix_bcn_timeout] = 226 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 227 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 228 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 229 [wmi_pdev_param_ce_bto_combo_ce_value] = 230 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 231 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 232 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 233 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 234 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 235 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 236 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 237 [wmi_pdev_param_soft_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 238 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 239 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 240 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 241 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 242 [wmi_pdev_peer_sta_ps_statechg_enable] = 243 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 244 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 245 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 246 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 247 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 248 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 249 [wmi_pdev_param_set_mcast_bcast_echo] = 250 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 251 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 252 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 253 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 254 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 255 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 256 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 257 [wmi_pdev_param_enable_per_tid_amsdu] = 258 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 259 [wmi_pdev_param_enable_per_tid_ampdu] = 260 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 261 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 262 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 263 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 264 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 265 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 266 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 267 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 268 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 269 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 270 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 271 [wmi_pdev_param_atf_obss_noise_sch] = 272 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 273 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 274 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 275 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 276 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 277 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 278 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 279 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 280 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 281 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 282 [wmi_pdev_param_set_disable_reset_cmdid] = 283 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 284 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 285 [wmi_pdev_param_txbf_sound_period_cmdid] = 286 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 287 [wmi_pdev_param_set_burst_mode_cmdid] = 288 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 289 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 290 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 291 [wmi_pdev_param_set_promisc_mode_cmdid] = 292 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 293 [wmi_pdev_param_set_ppdu_duration_cmdid] = 294 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 295 [wmi_pdev_param_remove_mcast2ucast_buffer] = 296 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 297 [wmi_pdev_param_set_mcast2ucast_buffer] = 298 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 299 [wmi_pdev_param_set_mcast2ucast_mode] = 300 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 301 [wmi_pdev_param_smart_antenna_default_antenna] = 302 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 303 [wmi_pdev_param_fast_channel_reset] = 304 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 305 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 306 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 307 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 308 [wmi_pdev_param_antenna_gain_half_db] = 309 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 310 [wmi_pdev_param_esp_indication_period] = 311 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 312 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 313 [wmi_pdev_param_esp_airtime_fraction] = 314 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 315 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 316 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 317 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 318 /* Trigger interval for all trigger types. */ 319 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 320 [wmi_pdev_param_sub_channel_marking] = 321 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 322 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 323 [wmi_pdev_param_equal_ru_allocation_enable] = 324 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 325 [wmi_pdev_param_per_peer_prd_cfr_enable] = 326 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 327 [wmi_pdev_param_nav_override_config] = 328 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 329 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 330 [wmi_pdev_param_set_prb_rsp_ttl] = 331 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 332 [wmi_pdev_param_set_mu_ppdu_duration] = 333 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 334 [wmi_pdev_param_set_tbtt_ctrl] = 335 WMI_PDEV_PARAM_SET_TBTT_CTRL, 336 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 337 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 338 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 339 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 340 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 341 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 342 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 343 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 344 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 345 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 346 [wmi_pdev_param_sr_trigger_margin] = WMI_PDEV_PARAM_SR_TRIGGER_MARGIN, 347 [wmi_pdev_param_pream_punct_bw] = WMI_PDEV_PARAM_SET_PREAM_PUNCT_BW, 348 [wmi_pdev_param_enable_mbssid_ctrl_frame] = WMI_PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME, 349 [wmi_pdev_param_set_mesh_params] = WMI_PDEV_PARAM_SET_MESH_PARAMS, 350 [wmi_pdev_param_mpd_userpd_ssr] = WMI_PDEV_PARAM_MPD_USERPD_SSR, 351 [wmi_pdev_param_low_latency_mode] = 352 WMI_PDEV_PARAM_LOW_LATENCY_SCHED_MODE, 353 [wmi_pdev_param_scan_radio_tx_on_dfs] = 354 WMI_PDEV_PARAM_SCAN_RADIO_TX_ON_DFS, 355 }; 356 357 /** 358 * Populate vdev_param_value_tlv array whose index is host param 359 * and value is target param 360 */ 361 static const uint32_t vdev_param_tlv[] = { 362 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 363 [wmi_vdev_param_fragmentation_threshold] = 364 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 365 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 366 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 367 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 368 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 369 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 370 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 371 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 372 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 373 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 374 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 375 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 376 [wmi_vdev_oc_scheduler_air_time_limit] = 377 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 378 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 379 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 380 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 381 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 382 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 383 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 384 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 385 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 386 [wmi_vdev_param_disable_htprotection] = 387 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 388 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 389 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 390 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 391 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 392 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 393 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 394 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 395 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 396 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 397 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 398 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 399 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 400 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 401 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 402 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 403 [wmi_vdev_param_unknown_dest_indicate] = 404 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 405 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 406 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 407 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 408 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 409 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 410 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 411 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 412 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 413 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 414 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 415 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 416 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 417 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 418 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 419 [wmi_vdev_param_early_rx_adjust_enable] = 420 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 421 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 422 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 423 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 424 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 425 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 426 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 427 [wmi_vdev_param_early_rx_adjust_pause] = 428 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 429 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 430 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 431 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 432 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 433 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 434 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 435 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 436 [wmi_vdev_param_early_rx_drift_sample] = 437 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 438 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 439 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 440 [wmi_vdev_param_ebt_resync_timeout] = 441 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 442 [wmi_vdev_param_aggr_trig_event_enable] = 443 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 444 [wmi_vdev_param_is_ibss_power_save_allowed] = 445 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 446 [wmi_vdev_param_is_power_collapse_allowed] = 447 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 448 [wmi_vdev_param_is_awake_on_txrx_enabled] = 449 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 450 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 451 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 452 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 453 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 454 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 455 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 456 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 457 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 458 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 459 [wmi_vdev_param_stats_avg_factor] = 460 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 461 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 462 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 463 [wmi_vdev_param_mcc_rtscts_protection_enable] = 464 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 465 [wmi_vdev_param_mcc_broadcast_probe_enable] = 466 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 467 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 468 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 469 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 470 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 471 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 472 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 473 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 474 [wmi_vdev_param_set_he_sounding_mode] = 475 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 476 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 477 #ifdef WLAN_FEATURE_11BE 478 [wmi_vdev_param_set_ehtop] = WMI_VDEV_PARAM_EHTOPS_0_31, 479 #endif 480 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 481 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 482 [wmi_vdev_param_atf_ssid_sched_policy] = 483 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 484 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 485 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 486 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 487 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 488 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 489 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 490 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 491 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 492 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 493 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 494 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 495 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 496 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 497 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 498 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 499 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 500 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 501 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 502 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 503 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 504 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 505 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 506 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 507 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 508 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 509 [wmi_vdev_param_mcast_rc_stale_period] = 510 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 511 [wmi_vdev_param_enable_multi_group_key] = 512 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 513 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 514 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 515 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 516 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 517 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 518 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 519 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 520 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 521 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 522 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 523 [wmi_vdev_param_nan_config_features] = 524 WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES, 525 [wmi_vdev_param_enable_disable_rtt_responder_role] = 526 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, 527 [wmi_vdev_param_enable_disable_rtt_initiator_role] = 528 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE, 529 [wmi_vdev_param_mcast_steer] = WMI_VDEV_PARAM_MCAST_STEERING, 530 }; 531 #endif 532 533 #ifndef WMI_PKTLOG_EVENT_CBF 534 #define WMI_PKTLOG_EVENT_CBF 0x100 535 #endif 536 537 /** 538 * Populate the pktlog event tlv array, where 539 * the values are the FW WMI events, which host 540 * uses to communicate with FW for pktlog 541 */ 542 543 static const uint32_t pktlog_event_tlv[] = { 544 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 545 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 546 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 547 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 548 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 549 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 550 WMI_PKTLOG_EVENT_SMART_ANTENNA, 551 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 552 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 553 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 554 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 555 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 556 }; 557 558 /** 559 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 560 * host to target defines. 561 * @wmi_handle: pointer to wmi_handle 562 * @param pdev_id: host pdev_id to be converted. 563 * Return: target pdev_id after conversion. 564 */ 565 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 566 uint32_t pdev_id) 567 { 568 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 569 if (!wmi_handle->soc->is_pdev_is_map_enable) { 570 switch (pdev_id) { 571 case WMI_HOST_PDEV_ID_0: 572 return WMI_PDEV_ID_1ST; 573 case WMI_HOST_PDEV_ID_1: 574 return WMI_PDEV_ID_2ND; 575 case WMI_HOST_PDEV_ID_2: 576 return WMI_PDEV_ID_3RD; 577 } 578 } else { 579 return wmi_handle->cmd_pdev_id_map[pdev_id]; 580 } 581 } else { 582 return WMI_PDEV_ID_SOC; 583 } 584 585 QDF_ASSERT(0); 586 587 return WMI_PDEV_ID_SOC; 588 } 589 590 /** 591 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 592 * target to host defines. 593 * @wmi_handle: pointer to wmi_handle 594 * @param pdev_id: target pdev_id to be converted. 595 * Return: host pdev_id after conversion. 596 */ 597 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 598 uint32_t pdev_id) 599 { 600 601 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 602 if (!wmi_handle->soc->is_pdev_is_map_enable) { 603 switch (pdev_id) { 604 case WMI_PDEV_ID_1ST: 605 return WMI_HOST_PDEV_ID_0; 606 case WMI_PDEV_ID_2ND: 607 return WMI_HOST_PDEV_ID_1; 608 case WMI_PDEV_ID_3RD: 609 return WMI_HOST_PDEV_ID_2; 610 } 611 } else { 612 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 613 } 614 } else if (pdev_id == WMI_PDEV_ID_SOC) { 615 return WMI_HOST_PDEV_ID_SOC; 616 } else { 617 wmi_err("Invalid pdev_id"); 618 } 619 620 return WMI_HOST_PDEV_ID_INVALID; 621 } 622 623 /** 624 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 625 * host to target defines. 626 * @wmi_handle: pointer to wmi_handle 627 * @param phy_id: host pdev_id to be converted. 628 * Return: target phy_id after conversion. 629 */ 630 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 631 uint32_t phy_id) 632 { 633 if (!wmi_handle->soc->is_phy_id_map_enable || 634 phy_id >= WMI_MAX_RADIOS) { 635 return phy_id; 636 } 637 638 return wmi_handle->cmd_phy_id_map[phy_id]; 639 } 640 641 /** 642 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 643 * target to host defines. 644 * @wmi_handle: pointer to wmi_handle 645 * @param phy_id: target phy_id to be converted. 646 * Return: host phy_id after conversion. 647 */ 648 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 649 uint32_t phy_id) 650 { 651 if (!wmi_handle->soc->is_phy_id_map_enable || 652 phy_id >= WMI_MAX_RADIOS) { 653 return phy_id; 654 } 655 656 return wmi_handle->evt_phy_id_map[phy_id]; 657 } 658 659 /** 660 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 661 * 662 * Return None. 663 */ 664 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 665 uint32_t *pdev_id_map, 666 uint8_t size) 667 { 668 int i = 0; 669 670 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 671 for (i = 0; i < size; i++) { 672 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 673 wmi_handle->evt_pdev_id_map[i] = 674 WMI_HOST_PDEV_ID_INVALID; 675 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 676 wmi_handle->evt_phy_id_map[i] = 677 WMI_HOST_PDEV_ID_INVALID; 678 } 679 680 for (i = 0; i < size; i++) { 681 if (wmi_handle->cmd_pdev_id_map[i] != 682 WMI_HOST_PDEV_ID_INVALID) { 683 wmi_handle->evt_pdev_id_map 684 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 685 } 686 if (wmi_handle->cmd_phy_id_map[i] != 687 WMI_HOST_PDEV_ID_INVALID) { 688 wmi_handle->evt_phy_id_map 689 [wmi_handle->cmd_phy_id_map[i]] = i; 690 } 691 } 692 wmi_handle->soc->is_pdev_is_map_enable = true; 693 wmi_handle->soc->is_phy_id_map_enable = true; 694 } else { 695 wmi_handle->soc->is_pdev_is_map_enable = false; 696 wmi_handle->soc->is_phy_id_map_enable = false; 697 } 698 699 wmi_handle->ops->convert_pdev_id_host_to_target = 700 convert_host_pdev_id_to_target_pdev_id; 701 wmi_handle->ops->convert_pdev_id_target_to_host = 702 convert_target_pdev_id_to_host_pdev_id; 703 704 /* phy_id convert function assignments */ 705 wmi_handle->ops->convert_phy_id_host_to_target = 706 convert_host_phy_id_to_target_phy_id; 707 wmi_handle->ops->convert_phy_id_target_to_host = 708 convert_target_phy_id_to_host_phy_id; 709 } 710 711 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 712 * buffer. 713 * @wmi_handle: pointer to wmi_handle 714 * @cmd: pointer target vdev create command buffer 715 * @param: pointer host params for vdev create 716 * 717 * Return: None 718 */ 719 static inline void copy_vdev_create_pdev_id( 720 struct wmi_unified *wmi_handle, 721 wmi_vdev_create_cmd_fixed_param * cmd, 722 struct vdev_create_params *param) 723 { 724 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 725 wmi_handle, 726 param->pdev_id); 727 } 728 729 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 730 { 731 uint16_t mtrace_message_id; 732 733 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 734 (QDF_WMI_MTRACE_GRP_ID(message_id) << 735 QDF_WMI_MTRACE_CMD_NUM_BITS); 736 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 737 mtrace_message_id, vdev_id, data); 738 } 739 qdf_export_symbol(wmi_mtrace); 740 741 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 742 wmi_buf_t buf, 743 uint32_t buflen, uint32_t cmd_id) 744 { 745 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 746 goto send_over_wmi; 747 748 if (wmi_is_target_suspend_acked(wmi_handle)) { 749 if (QDF_IS_STATUS_SUCCESS( 750 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 751 buflen, cmd_id))) 752 return QDF_STATUS_SUCCESS; 753 } 754 755 send_over_wmi: 756 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 757 758 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 759 } 760 761 /** 762 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 763 * @wmi_handle: wmi handle 764 * @param: pointer to hold vdev create parameter 765 * @macaddr: vdev mac address 766 * 767 * Return: QDF_STATUS_SUCCESS for success or error code 768 */ 769 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 770 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 771 struct vdev_create_params *param) 772 { 773 wmi_vdev_create_cmd_fixed_param *cmd; 774 wmi_buf_t buf; 775 int32_t len = sizeof(*cmd); 776 QDF_STATUS ret; 777 int num_bands = 2; 778 uint8_t *buf_ptr; 779 wmi_vdev_txrx_streams *txrx_streams; 780 781 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 782 len += vdev_create_mlo_params_size(); 783 784 buf = wmi_buf_alloc(wmi_handle, len); 785 if (!buf) 786 return QDF_STATUS_E_NOMEM; 787 788 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 789 WMITLV_SET_HDR(&cmd->tlv_header, 790 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 791 WMITLV_GET_STRUCT_TLVLEN 792 (wmi_vdev_create_cmd_fixed_param)); 793 cmd->vdev_id = param->vdev_id; 794 cmd->vdev_type = param->type; 795 cmd->vdev_subtype = param->subtype; 796 cmd->flags = param->mbssid_flags; 797 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 798 cmd->vdevid_trans = param->vdevid_trans; 799 cmd->num_cfg_txrx_streams = num_bands; 800 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 801 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 802 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 803 param->vdev_id, cmd->pdev_id, 804 QDF_MAC_ADDR_REF(macaddr)); 805 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 806 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 807 (num_bands * sizeof(wmi_vdev_txrx_streams))); 808 buf_ptr += WMI_TLV_HDR_SIZE; 809 810 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 811 param->type, param->subtype, 812 param->nss_2g, param->nss_5g); 813 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 814 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 815 txrx_streams->supported_tx_streams = param->nss_2g; 816 txrx_streams->supported_rx_streams = param->nss_2g; 817 WMITLV_SET_HDR(&txrx_streams->tlv_header, 818 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 819 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 820 821 txrx_streams++; 822 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 823 txrx_streams->supported_tx_streams = param->nss_5g; 824 txrx_streams->supported_rx_streams = param->nss_5g; 825 WMITLV_SET_HDR(&txrx_streams->tlv_header, 826 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 827 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 828 829 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 830 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 831 832 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 833 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 834 if (QDF_IS_STATUS_ERROR(ret)) { 835 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 836 wmi_buf_free(buf); 837 } 838 839 return ret; 840 } 841 842 /** 843 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 844 * @wmi_handle: wmi handle 845 * @if_id: vdev id 846 * 847 * Return: QDF_STATUS_SUCCESS for success or error code 848 */ 849 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 850 uint8_t if_id) 851 { 852 wmi_vdev_delete_cmd_fixed_param *cmd; 853 wmi_buf_t buf; 854 QDF_STATUS ret; 855 856 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 857 if (!buf) 858 return QDF_STATUS_E_NOMEM; 859 860 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 861 WMITLV_SET_HDR(&cmd->tlv_header, 862 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 863 WMITLV_GET_STRUCT_TLVLEN 864 (wmi_vdev_delete_cmd_fixed_param)); 865 cmd->vdev_id = if_id; 866 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 867 ret = wmi_unified_cmd_send(wmi_handle, buf, 868 sizeof(wmi_vdev_delete_cmd_fixed_param), 869 WMI_VDEV_DELETE_CMDID); 870 if (QDF_IS_STATUS_ERROR(ret)) { 871 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 872 wmi_buf_free(buf); 873 } 874 wmi_debug("vdev id = %d", if_id); 875 876 return ret; 877 } 878 879 /** 880 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 881 * @wmi_handle: wmi handle 882 * @vdev_id: vdev id 883 * @nss_chains_user_cfg: user configured nss chain params 884 * 885 * Return: QDF_STATUS_SUCCESS for success or error code 886 */ 887 static QDF_STATUS 888 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 889 uint8_t vdev_id, 890 struct vdev_nss_chains *user_cfg) 891 { 892 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 893 wmi_buf_t buf; 894 QDF_STATUS ret; 895 896 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 897 if (!buf) 898 return QDF_STATUS_E_NOMEM; 899 900 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 901 WMITLV_SET_HDR(&cmd->tlv_header, 902 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 903 WMITLV_GET_STRUCT_TLVLEN 904 (wmi_vdev_chainmask_config_cmd_fixed_param)); 905 cmd->vdev_id = vdev_id; 906 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 907 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 908 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 909 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 910 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 911 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 912 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 913 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 914 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 915 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 916 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 917 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 918 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 919 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 920 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 921 922 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 923 ret = wmi_unified_cmd_send(wmi_handle, buf, 924 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 925 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 926 if (QDF_IS_STATUS_ERROR(ret)) { 927 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 928 wmi_buf_free(buf); 929 } 930 wmi_debug("vdev_id %d", vdev_id); 931 932 return ret; 933 } 934 935 /** 936 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 937 * @wmi: wmi handle 938 * @vdev_id: vdev id 939 * 940 * Return: QDF_STATUS_SUCCESS for success or erro code 941 */ 942 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 943 uint8_t vdev_id) 944 { 945 wmi_vdev_stop_cmd_fixed_param *cmd; 946 wmi_buf_t buf; 947 int32_t len = sizeof(*cmd); 948 949 buf = wmi_buf_alloc(wmi, len); 950 if (!buf) 951 return QDF_STATUS_E_NOMEM; 952 953 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 954 WMITLV_SET_HDR(&cmd->tlv_header, 955 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 956 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 957 cmd->vdev_id = vdev_id; 958 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 959 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 960 wmi_err("Failed to send vdev stop command"); 961 wmi_buf_free(buf); 962 return QDF_STATUS_E_FAILURE; 963 } 964 wmi_debug("vdev id = %d", vdev_id); 965 966 return 0; 967 } 968 969 /** 970 * send_vdev_down_cmd_tlv() - send vdev down command to fw 971 * @wmi: wmi handle 972 * @vdev_id: vdev id 973 * 974 * Return: QDF_STATUS_SUCCESS for success or error code 975 */ 976 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 977 { 978 wmi_vdev_down_cmd_fixed_param *cmd; 979 wmi_buf_t buf; 980 int32_t len = sizeof(*cmd); 981 982 buf = wmi_buf_alloc(wmi, len); 983 if (!buf) 984 return QDF_STATUS_E_NOMEM; 985 986 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 987 WMITLV_SET_HDR(&cmd->tlv_header, 988 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 989 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 990 cmd->vdev_id = vdev_id; 991 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 992 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 993 wmi_err("Failed to send vdev down"); 994 wmi_buf_free(buf); 995 return QDF_STATUS_E_FAILURE; 996 } 997 wmi_debug("vdev_id %d", vdev_id); 998 999 return 0; 1000 } 1001 1002 static inline void copy_channel_info( 1003 wmi_vdev_start_request_cmd_fixed_param * cmd, 1004 wmi_channel *chan, 1005 struct vdev_start_params *req) 1006 { 1007 chan->mhz = req->channel.mhz; 1008 1009 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1010 1011 chan->band_center_freq1 = req->channel.cfreq1; 1012 chan->band_center_freq2 = req->channel.cfreq2; 1013 1014 if (req->channel.half_rate) 1015 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1016 else if (req->channel.quarter_rate) 1017 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1018 1019 if (req->channel.dfs_set) { 1020 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1021 cmd->disable_hw_ack = req->disable_hw_ack; 1022 } 1023 1024 if (req->channel.dfs_set_cfreq2) 1025 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1026 1027 if (req->channel.is_stadfs_en) 1028 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1029 1030 /* According to firmware both reg power and max tx power 1031 * on set channel power is used and set it to max reg 1032 * power from regulatory. 1033 */ 1034 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1035 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1036 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1037 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1038 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1039 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1040 1041 } 1042 1043 /** 1044 * vdev_start_cmd_fill_11be() - 11be information fiiling in vdev_ststart 1045 * @cmd: wmi cmd 1046 * @req: vdev start params 1047 * 1048 * Return: QDF status 1049 */ 1050 #ifdef WLAN_FEATURE_11BE 1051 static void 1052 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1053 struct vdev_start_params *req) 1054 { 1055 cmd->eht_ops = req->eht_ops; 1056 cmd->puncture_20mhz_bitmap = req->channel.puncture_pattern; 1057 wmi_info("EHT ops: %x puncture_pattern %x", 1058 req->eht_ops, req->channel.puncture_pattern); 1059 } 1060 #else 1061 static void 1062 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1063 struct vdev_start_params *req) 1064 { 1065 } 1066 #endif 1067 1068 /** 1069 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1070 * @wmi_handle: wmi handle 1071 * @req: vdev start params 1072 * 1073 * Return: QDF status 1074 */ 1075 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1076 struct vdev_start_params *req) 1077 { 1078 wmi_vdev_start_request_cmd_fixed_param *cmd; 1079 wmi_buf_t buf; 1080 wmi_channel *chan; 1081 int32_t len, ret; 1082 uint8_t *buf_ptr; 1083 1084 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1085 if (!req->is_restart) 1086 len += vdev_start_mlo_params_size(req); 1087 buf = wmi_buf_alloc(wmi_handle, len); 1088 if (!buf) 1089 return QDF_STATUS_E_NOMEM; 1090 1091 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1092 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1093 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1094 WMITLV_SET_HDR(&cmd->tlv_header, 1095 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1096 WMITLV_GET_STRUCT_TLVLEN 1097 (wmi_vdev_start_request_cmd_fixed_param)); 1098 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1099 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1100 cmd->vdev_id = req->vdev_id; 1101 1102 /* Fill channel info */ 1103 copy_channel_info(cmd, chan, req); 1104 cmd->beacon_interval = req->beacon_interval; 1105 cmd->dtim_period = req->dtim_period; 1106 1107 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1108 if (req->bcn_tx_rate_code) 1109 wmi_enable_bcn_ratecode(&cmd->flags); 1110 1111 if (!req->is_restart) { 1112 if (req->pmf_enabled) 1113 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1114 1115 cmd->mbss_capability_flags = req->mbssid_flags; 1116 cmd->vdevid_trans = req->vdevid_trans; 1117 } 1118 1119 /* Copy the SSID */ 1120 if (req->ssid.length) { 1121 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1122 cmd->ssid.ssid_len = req->ssid.length; 1123 else 1124 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1125 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1126 cmd->ssid.ssid_len); 1127 } 1128 1129 if (req->hidden_ssid) 1130 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1131 1132 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1133 cmd->num_noa_descriptors = req->num_noa_descriptors; 1134 cmd->preferred_rx_streams = req->preferred_rx_streams; 1135 cmd->preferred_tx_streams = req->preferred_tx_streams; 1136 cmd->cac_duration_ms = req->cac_duration_ms; 1137 cmd->regdomain = req->regdomain; 1138 cmd->he_ops = req->he_ops; 1139 1140 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1141 sizeof(wmi_channel)); 1142 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1143 cmd->num_noa_descriptors * 1144 sizeof(wmi_p2p_noa_descriptor)); 1145 if (!req->is_restart) { 1146 buf_ptr += WMI_TLV_HDR_SIZE + 1147 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1148 1149 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1150 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1151 } 1152 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1153 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1154 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1155 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1156 "req->dis_hw_ack: %d ", req->vdev_id, 1157 chan->mhz, req->channel.phy_mode, chan->info, 1158 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1159 chan->band_center_freq1, chan->band_center_freq2, 1160 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1161 req->preferred_tx_streams, req->preferred_rx_streams, 1162 req->ldpc_rx_enabled, req->cac_duration_ms, 1163 req->regdomain, req->he_ops, 1164 req->disable_hw_ack); 1165 1166 vdev_start_cmd_fill_11be(cmd, req); 1167 1168 if (req->is_restart) { 1169 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1170 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1171 WMI_VDEV_RESTART_REQUEST_CMDID); 1172 } else { 1173 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1174 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1175 WMI_VDEV_START_REQUEST_CMDID); 1176 } 1177 if (ret) { 1178 wmi_err("Failed to send vdev start command"); 1179 wmi_buf_free(buf); 1180 return QDF_STATUS_E_FAILURE; 1181 } 1182 1183 return QDF_STATUS_SUCCESS; 1184 } 1185 1186 /** 1187 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1188 * @wmi: wmi handle 1189 * @peer_addr: peer mac address 1190 * @param: pointer to hold peer flush tid parameter 1191 * 1192 * Return: 0 for success or error code 1193 */ 1194 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1195 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1196 struct peer_flush_params *param) 1197 { 1198 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1199 wmi_buf_t buf; 1200 int32_t len = sizeof(*cmd); 1201 1202 buf = wmi_buf_alloc(wmi, len); 1203 if (!buf) 1204 return QDF_STATUS_E_NOMEM; 1205 1206 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1207 WMITLV_SET_HDR(&cmd->tlv_header, 1208 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1209 WMITLV_GET_STRUCT_TLVLEN 1210 (wmi_peer_flush_tids_cmd_fixed_param)); 1211 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1212 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1213 cmd->vdev_id = param->vdev_id; 1214 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1215 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1216 param->peer_tid_bitmap); 1217 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1218 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1219 wmi_err("Failed to send flush tid command"); 1220 wmi_buf_free(buf); 1221 return QDF_STATUS_E_FAILURE; 1222 } 1223 1224 return 0; 1225 } 1226 1227 /** 1228 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1229 * @wmi: wmi handle 1230 * @peer_addr: peer mac addr 1231 * @vdev_id: vdev id 1232 * 1233 * Return: QDF_STATUS_SUCCESS for success or error code 1234 */ 1235 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1236 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1237 uint8_t vdev_id) 1238 { 1239 wmi_peer_delete_cmd_fixed_param *cmd; 1240 wmi_buf_t buf; 1241 int32_t len = sizeof(*cmd); 1242 buf = wmi_buf_alloc(wmi, len); 1243 if (!buf) 1244 return QDF_STATUS_E_NOMEM; 1245 1246 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 1247 WMITLV_SET_HDR(&cmd->tlv_header, 1248 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1249 WMITLV_GET_STRUCT_TLVLEN 1250 (wmi_peer_delete_cmd_fixed_param)); 1251 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1252 cmd->vdev_id = vdev_id; 1253 1254 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1255 QDF_MAC_ADDR_REF(peer_addr), vdev_id); 1256 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1257 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1258 wmi_err("Failed to send peer delete command"); 1259 wmi_buf_free(buf); 1260 return QDF_STATUS_E_FAILURE; 1261 } 1262 1263 return 0; 1264 } 1265 1266 /** 1267 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1268 * @wmi: wmi handle 1269 * @param: pointer to hold peer delete all parameter 1270 * 1271 * Return: QDF_STATUS_SUCCESS for success or error code 1272 */ 1273 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1274 wmi_unified_t wmi, 1275 struct peer_delete_all_params *param) 1276 { 1277 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1278 wmi_buf_t buf; 1279 int32_t len = sizeof(*cmd); 1280 1281 buf = wmi_buf_alloc(wmi, len); 1282 if (!buf) 1283 return QDF_STATUS_E_NOMEM; 1284 1285 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1286 WMITLV_SET_HDR( 1287 &cmd->tlv_header, 1288 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1289 WMITLV_GET_STRUCT_TLVLEN 1290 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1291 cmd->vdev_id = param->vdev_id; 1292 1293 wmi_debug("vdev_id %d", cmd->vdev_id); 1294 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1295 if (wmi_unified_cmd_send(wmi, buf, len, 1296 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1297 wmi_err("Failed to send peer del all command"); 1298 wmi_buf_free(buf); 1299 return QDF_STATUS_E_FAILURE; 1300 } 1301 1302 return QDF_STATUS_SUCCESS; 1303 } 1304 1305 /** 1306 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1307 * to target id. 1308 * @peer_param_id: host param id. 1309 * 1310 * Return: Target param id. 1311 */ 1312 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1313 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1314 uint32_t peer_param_id) 1315 { 1316 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1317 return peer_param_tlv[peer_param_id]; 1318 return WMI_UNAVAILABLE_PARAM; 1319 } 1320 #else 1321 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1322 uint32_t peer_param_id) 1323 { 1324 return peer_param_id; 1325 } 1326 #endif 1327 1328 /** 1329 * send_peer_param_cmd_tlv() - set peer parameter in fw 1330 * @wmi: wmi handle 1331 * @peer_addr: peer mac address 1332 * @param : pointer to hold peer set parameter 1333 * 1334 * Return: QDF_STATUS_SUCCESS for success or error code 1335 */ 1336 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1337 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1338 struct peer_set_params *param) 1339 { 1340 wmi_peer_set_param_cmd_fixed_param *cmd; 1341 wmi_buf_t buf; 1342 int32_t err; 1343 uint32_t param_id; 1344 1345 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1346 if (param_id == WMI_UNAVAILABLE_PARAM) { 1347 wmi_err("Unavailable param %d", param->param_id); 1348 return QDF_STATUS_E_NOSUPPORT; 1349 } 1350 1351 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1352 if (!buf) 1353 return QDF_STATUS_E_NOMEM; 1354 1355 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1356 WMITLV_SET_HDR(&cmd->tlv_header, 1357 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1358 WMITLV_GET_STRUCT_TLVLEN 1359 (wmi_peer_set_param_cmd_fixed_param)); 1360 cmd->vdev_id = param->vdev_id; 1361 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1362 cmd->param_id = param_id; 1363 cmd->param_value = param->param_value; 1364 1365 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1366 cmd->vdev_id, 1367 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1368 cmd->param_value); 1369 1370 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1371 err = wmi_unified_cmd_send(wmi, buf, 1372 sizeof(wmi_peer_set_param_cmd_fixed_param), 1373 WMI_PEER_SET_PARAM_CMDID); 1374 if (err) { 1375 wmi_err("Failed to send set_param cmd"); 1376 wmi_buf_free(buf); 1377 return QDF_STATUS_E_FAILURE; 1378 } 1379 1380 return 0; 1381 } 1382 1383 /** 1384 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1385 * @wmi: wmi handle 1386 * @bssid: bssid 1387 * @vdev_up_params: pointer to hold vdev up parameter 1388 * 1389 * Return: QDF_STATUS_SUCCESS for success or error code 1390 */ 1391 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1392 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1393 struct vdev_up_params *params) 1394 { 1395 wmi_vdev_up_cmd_fixed_param *cmd; 1396 wmi_buf_t buf; 1397 int32_t len = sizeof(*cmd); 1398 1399 wmi_debug("VDEV_UP"); 1400 wmi_debug("vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT, 1401 params->vdev_id, params->assoc_id, QDF_MAC_ADDR_REF(bssid)); 1402 buf = wmi_buf_alloc(wmi, len); 1403 if (!buf) 1404 return QDF_STATUS_E_NOMEM; 1405 1406 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1407 WMITLV_SET_HDR(&cmd->tlv_header, 1408 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1409 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1410 cmd->vdev_id = params->vdev_id; 1411 cmd->vdev_assoc_id = params->assoc_id; 1412 cmd->profile_idx = params->profile_idx; 1413 cmd->profile_num = params->profile_num; 1414 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1415 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1416 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1417 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1418 wmi_err("Failed to send vdev up command"); 1419 wmi_buf_free(buf); 1420 return QDF_STATUS_E_FAILURE; 1421 } 1422 1423 return 0; 1424 } 1425 1426 /** 1427 * send_peer_create_cmd_tlv() - send peer create command to fw 1428 * @wmi: wmi handle 1429 * @peer_addr: peer mac address 1430 * @peer_type: peer type 1431 * @vdev_id: vdev id 1432 * 1433 * Return: QDF_STATUS_SUCCESS for success or error code 1434 */ 1435 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1436 struct peer_create_params *param) 1437 { 1438 wmi_peer_create_cmd_fixed_param *cmd; 1439 wmi_buf_t buf; 1440 uint8_t *buf_ptr; 1441 int32_t len = sizeof(*cmd); 1442 1443 len += peer_create_mlo_params_size(param); 1444 buf = wmi_buf_alloc(wmi, len); 1445 if (!buf) 1446 return QDF_STATUS_E_NOMEM; 1447 1448 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1449 WMITLV_SET_HDR(&cmd->tlv_header, 1450 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1451 WMITLV_GET_STRUCT_TLVLEN 1452 (wmi_peer_create_cmd_fixed_param)); 1453 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1454 cmd->peer_type = param->peer_type; 1455 cmd->vdev_id = param->vdev_id; 1456 1457 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1458 buf_ptr += sizeof(*cmd); 1459 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1460 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1461 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1462 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1463 wmi_buf_free(buf); 1464 return QDF_STATUS_E_FAILURE; 1465 } 1466 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1467 QDF_MAC_ADDR_REF(param->peer_addr), 1468 param->vdev_id); 1469 1470 return 0; 1471 } 1472 1473 /** 1474 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1475 * command to fw 1476 * @wmi: wmi handle 1477 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1478 * 1479 * Return: 0 for success or error code 1480 */ 1481 static 1482 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1483 struct rx_reorder_queue_setup_params *param) 1484 { 1485 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1486 wmi_buf_t buf; 1487 int32_t len = sizeof(*cmd); 1488 1489 buf = wmi_buf_alloc(wmi, len); 1490 if (!buf) 1491 return QDF_STATUS_E_NOMEM; 1492 1493 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1494 WMITLV_SET_HDR(&cmd->tlv_header, 1495 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1496 WMITLV_GET_STRUCT_TLVLEN 1497 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1498 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1499 cmd->vdev_id = param->vdev_id; 1500 cmd->tid = param->tid; 1501 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1502 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1503 cmd->queue_no = param->queue_no; 1504 cmd->ba_window_size_valid = param->ba_window_size_valid; 1505 cmd->ba_window_size = param->ba_window_size; 1506 1507 1508 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1509 if (wmi_unified_cmd_send(wmi, buf, len, 1510 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1511 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 1512 wmi_buf_free(buf); 1513 return QDF_STATUS_E_FAILURE; 1514 } 1515 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 1516 QDF_MAC_ADDR_REF(param->peer_macaddr), 1517 param->vdev_id, param->tid); 1518 1519 return QDF_STATUS_SUCCESS; 1520 } 1521 1522 /** 1523 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1524 * command to fw 1525 * @wmi: wmi handle 1526 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1527 * 1528 * Return: 0 for success or error code 1529 */ 1530 static 1531 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1532 struct rx_reorder_queue_remove_params *param) 1533 { 1534 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1535 wmi_buf_t buf; 1536 int32_t len = sizeof(*cmd); 1537 1538 buf = wmi_buf_alloc(wmi, len); 1539 if (!buf) 1540 return QDF_STATUS_E_NOMEM; 1541 1542 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1543 wmi_buf_data(buf); 1544 WMITLV_SET_HDR(&cmd->tlv_header, 1545 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1546 WMITLV_GET_STRUCT_TLVLEN 1547 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1548 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1549 cmd->vdev_id = param->vdev_id; 1550 cmd->tid_mask = param->peer_tid_bitmap; 1551 1552 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1553 if (wmi_unified_cmd_send(wmi, buf, len, 1554 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1555 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 1556 wmi_buf_free(buf); 1557 return QDF_STATUS_E_FAILURE; 1558 } 1559 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 1560 QDF_MAC_ADDR_REF(param->peer_macaddr), 1561 param->vdev_id, param->peer_tid_bitmap); 1562 1563 return QDF_STATUS_SUCCESS; 1564 } 1565 1566 #ifdef WLAN_SUPPORT_GREEN_AP 1567 /** 1568 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1569 * @wmi_handle: wmi handle 1570 * @value: value 1571 * @pdev_id: pdev id to have radio context 1572 * 1573 * Return: QDF_STATUS_SUCCESS for success or error code 1574 */ 1575 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1576 uint32_t value, uint8_t pdev_id) 1577 { 1578 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1579 wmi_buf_t buf; 1580 int32_t len = sizeof(*cmd); 1581 1582 wmi_debug("Set Green AP PS val %d", value); 1583 1584 buf = wmi_buf_alloc(wmi_handle, len); 1585 if (!buf) 1586 return QDF_STATUS_E_NOMEM; 1587 1588 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1589 WMITLV_SET_HDR(&cmd->tlv_header, 1590 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1591 WMITLV_GET_STRUCT_TLVLEN 1592 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1593 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1594 wmi_handle, 1595 pdev_id); 1596 cmd->enable = value; 1597 1598 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1599 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1600 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1601 wmi_err("Set Green AP PS param Failed val %d", value); 1602 wmi_buf_free(buf); 1603 return QDF_STATUS_E_FAILURE; 1604 } 1605 1606 return 0; 1607 } 1608 #endif 1609 1610 /** 1611 * send_pdev_utf_cmd_tlv() - send utf command to fw 1612 * @wmi_handle: wmi handle 1613 * @param: pointer to pdev_utf_params 1614 * @mac_id: mac id to have radio context 1615 * 1616 * Return: QDF_STATUS_SUCCESS for success or error code 1617 */ 1618 static QDF_STATUS 1619 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1620 struct pdev_utf_params *param, 1621 uint8_t mac_id) 1622 { 1623 wmi_buf_t buf; 1624 uint8_t *cmd; 1625 /* if param->len is 0 no data is sent, return error */ 1626 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1627 static uint8_t msgref = 1; 1628 uint8_t segNumber = 0, segInfo, numSegments; 1629 uint16_t chunk_len, total_bytes; 1630 uint8_t *bufpos; 1631 struct seg_hdr_info segHdrInfo; 1632 1633 bufpos = param->utf_payload; 1634 total_bytes = param->len; 1635 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1636 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1637 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1638 1639 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1640 numSegments++; 1641 1642 while (param->len) { 1643 if (param->len > MAX_WMI_UTF_LEN) 1644 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1645 else 1646 chunk_len = param->len; 1647 1648 buf = wmi_buf_alloc(wmi_handle, 1649 (chunk_len + sizeof(segHdrInfo) + 1650 WMI_TLV_HDR_SIZE)); 1651 if (!buf) 1652 return QDF_STATUS_E_NOMEM; 1653 1654 cmd = (uint8_t *) wmi_buf_data(buf); 1655 1656 segHdrInfo.len = total_bytes; 1657 segHdrInfo.msgref = msgref; 1658 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1659 segHdrInfo.segmentInfo = segInfo; 1660 segHdrInfo.pad = 0; 1661 1662 wmi_debug("segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1663 " segHdrInfo.segmentInfo = %d", 1664 segHdrInfo.len, segHdrInfo.msgref, 1665 segHdrInfo.segmentInfo); 1666 1667 wmi_debug("total_bytes %d segNumber %d totalSegments %d" 1668 " chunk len %d", total_bytes, segNumber, 1669 numSegments, chunk_len); 1670 1671 segNumber++; 1672 1673 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1674 (chunk_len + sizeof(segHdrInfo))); 1675 cmd += WMI_TLV_HDR_SIZE; 1676 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1677 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(&cmd[sizeof(segHdrInfo)], 1678 bufpos, chunk_len); 1679 1680 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1681 ret = wmi_unified_cmd_send(wmi_handle, buf, 1682 (chunk_len + sizeof(segHdrInfo) + 1683 WMI_TLV_HDR_SIZE), 1684 WMI_PDEV_UTF_CMDID); 1685 1686 if (QDF_IS_STATUS_ERROR(ret)) { 1687 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 1688 wmi_buf_free(buf); 1689 break; 1690 } 1691 1692 param->len -= chunk_len; 1693 bufpos += chunk_len; 1694 } 1695 1696 msgref++; 1697 1698 return ret; 1699 } 1700 1701 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1702 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1703 { 1704 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1705 return pdev_param_tlv[host_param]; 1706 return WMI_UNAVAILABLE_PARAM; 1707 } 1708 #else 1709 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1710 { 1711 return host_param; 1712 } 1713 #endif 1714 1715 /** 1716 * send_pdev_param_cmd_tlv() - set pdev parameters 1717 * @wmi_handle: wmi handle 1718 * @param: pointer to pdev parameter 1719 * @mac_id: radio context 1720 * 1721 * Return: 0 on success, errno on failure 1722 */ 1723 static QDF_STATUS 1724 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1725 struct pdev_params *param, 1726 uint8_t mac_id) 1727 { 1728 QDF_STATUS ret; 1729 wmi_pdev_set_param_cmd_fixed_param *cmd; 1730 wmi_buf_t buf; 1731 uint16_t len = sizeof(*cmd); 1732 uint32_t pdev_param; 1733 1734 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1735 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1736 wmi_err("Unavailable param %d", param->param_id); 1737 return QDF_STATUS_E_INVAL; 1738 } 1739 1740 buf = wmi_buf_alloc(wmi_handle, len); 1741 if (!buf) 1742 return QDF_STATUS_E_NOMEM; 1743 1744 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1745 WMITLV_SET_HDR(&cmd->tlv_header, 1746 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1747 WMITLV_GET_STRUCT_TLVLEN 1748 (wmi_pdev_set_param_cmd_fixed_param)); 1749 if (param->is_host_pdev_id) 1750 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 1751 wmi_handle, 1752 mac_id); 1753 else 1754 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1755 wmi_handle, 1756 mac_id); 1757 cmd->param_id = pdev_param; 1758 cmd->param_value = param->param_value; 1759 wmi_debug("Setting pdev param = %x, value = %u", param->param_id, 1760 param->param_value); 1761 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1762 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1763 WMI_PDEV_SET_PARAM_CMDID); 1764 if (QDF_IS_STATUS_ERROR(ret)) { 1765 wmi_err("Failed to send set param command ret = %d", ret); 1766 wmi_buf_free(buf); 1767 } 1768 return ret; 1769 } 1770 1771 /** 1772 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1773 * @wmi_handle: wmi handle 1774 * @msg: Structure containing the following parameters 1775 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1776 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 1777 * 1778 * Provides notification to the WLAN firmware that host driver is requesting a 1779 * HardWare (HW) Mode change. This command is needed to support iHelium in the 1780 * configurations that include the Dual Band Simultaneous (DBS) feature. 1781 * 1782 * Return: Success if the cmd is sent successfully to the firmware 1783 */ 1784 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 1785 uint32_t hw_mode_index) 1786 { 1787 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 1788 wmi_buf_t buf; 1789 uint32_t len; 1790 1791 len = sizeof(*cmd); 1792 1793 buf = wmi_buf_alloc(wmi_handle, len); 1794 if (!buf) 1795 return QDF_STATUS_E_NOMEM; 1796 1797 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 1798 WMITLV_SET_HDR(&cmd->tlv_header, 1799 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 1800 WMITLV_GET_STRUCT_TLVLEN( 1801 wmi_pdev_set_hw_mode_cmd_fixed_param)); 1802 1803 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1804 wmi_handle, 1805 WMI_HOST_PDEV_ID_SOC); 1806 cmd->hw_mode_index = hw_mode_index; 1807 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 1808 1809 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 1810 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1811 WMI_PDEV_SET_HW_MODE_CMDID)) { 1812 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 1813 wmi_buf_free(buf); 1814 return QDF_STATUS_E_FAILURE; 1815 } 1816 1817 return QDF_STATUS_SUCCESS; 1818 } 1819 1820 /** 1821 * send_suspend_cmd_tlv() - WMI suspend function 1822 * @param wmi_handle : handle to WMI. 1823 * @param param : pointer to hold suspend parameter 1824 * @mac_id: radio context 1825 * 1826 * Return 0 on success and -ve on failure. 1827 */ 1828 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1829 struct suspend_params *param, 1830 uint8_t mac_id) 1831 { 1832 wmi_pdev_suspend_cmd_fixed_param *cmd; 1833 wmi_buf_t wmibuf; 1834 uint32_t len = sizeof(*cmd); 1835 int32_t ret; 1836 1837 /* 1838 * send the command to Target to ignore the 1839 * PCIE reset so as to ensure that Host and target 1840 * states are in sync 1841 */ 1842 wmibuf = wmi_buf_alloc(wmi_handle, len); 1843 if (!wmibuf) 1844 return QDF_STATUS_E_NOMEM; 1845 1846 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1847 WMITLV_SET_HDR(&cmd->tlv_header, 1848 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1849 WMITLV_GET_STRUCT_TLVLEN 1850 (wmi_pdev_suspend_cmd_fixed_param)); 1851 if (param->disable_target_intr) 1852 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1853 else 1854 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1855 1856 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1857 wmi_handle, 1858 mac_id); 1859 1860 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1861 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1862 WMI_PDEV_SUSPEND_CMDID); 1863 if (ret) { 1864 wmi_buf_free(wmibuf); 1865 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1866 } 1867 1868 return ret; 1869 } 1870 1871 /** 1872 * send_resume_cmd_tlv() - WMI resume function 1873 * @param wmi_handle : handle to WMI. 1874 * @mac_id: radio context 1875 * 1876 * Return: 0 on success and -ve on failure. 1877 */ 1878 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1879 uint8_t mac_id) 1880 { 1881 wmi_buf_t wmibuf; 1882 wmi_pdev_resume_cmd_fixed_param *cmd; 1883 QDF_STATUS ret; 1884 1885 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1886 if (!wmibuf) 1887 return QDF_STATUS_E_NOMEM; 1888 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1889 WMITLV_SET_HDR(&cmd->tlv_header, 1890 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1891 WMITLV_GET_STRUCT_TLVLEN 1892 (wmi_pdev_resume_cmd_fixed_param)); 1893 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1894 wmi_handle, 1895 mac_id); 1896 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1897 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1898 WMI_PDEV_RESUME_CMDID); 1899 if (QDF_IS_STATUS_ERROR(ret)) { 1900 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 1901 wmi_buf_free(wmibuf); 1902 } 1903 1904 return ret; 1905 } 1906 1907 /** 1908 * send_wow_enable_cmd_tlv() - WMI wow enable function 1909 * @param wmi_handle : handle to WMI. 1910 * @param param : pointer to hold wow enable parameter 1911 * @mac_id: radio context 1912 * 1913 * Return: 0 on success and -ve on failure. 1914 */ 1915 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1916 struct wow_cmd_params *param, 1917 uint8_t mac_id) 1918 { 1919 wmi_wow_enable_cmd_fixed_param *cmd; 1920 wmi_buf_t buf; 1921 int32_t len; 1922 int32_t ret; 1923 1924 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1925 1926 buf = wmi_buf_alloc(wmi_handle, len); 1927 if (!buf) 1928 return QDF_STATUS_E_NOMEM; 1929 1930 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1931 WMITLV_SET_HDR(&cmd->tlv_header, 1932 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1933 WMITLV_GET_STRUCT_TLVLEN 1934 (wmi_wow_enable_cmd_fixed_param)); 1935 cmd->enable = param->enable; 1936 if (param->can_suspend_link) 1937 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1938 else 1939 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1940 cmd->flags = param->flags; 1941 1942 wmi_info("suspend type: %s flag is 0x%x", 1943 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1944 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 1945 cmd->flags); 1946 1947 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1948 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1949 WMI_WOW_ENABLE_CMDID); 1950 if (ret) 1951 wmi_buf_free(buf); 1952 1953 return ret; 1954 } 1955 1956 /** 1957 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1958 * @wmi_handle: wmi handle 1959 * @peer_addr: peer mac address 1960 * @param: pointer to ap_ps parameter structure 1961 * 1962 * Return: QDF_STATUS_SUCCESS for success or error code 1963 */ 1964 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1965 uint8_t *peer_addr, 1966 struct ap_ps_params *param) 1967 { 1968 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1969 wmi_buf_t buf; 1970 int32_t err; 1971 1972 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1973 if (!buf) 1974 return QDF_STATUS_E_NOMEM; 1975 1976 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1977 WMITLV_SET_HDR(&cmd->tlv_header, 1978 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1979 WMITLV_GET_STRUCT_TLVLEN 1980 (wmi_ap_ps_peer_cmd_fixed_param)); 1981 cmd->vdev_id = param->vdev_id; 1982 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1983 cmd->param = param->param; 1984 cmd->value = param->value; 1985 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 1986 err = wmi_unified_cmd_send(wmi_handle, buf, 1987 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1988 if (err) { 1989 wmi_err("Failed to send set_ap_ps_param cmd"); 1990 wmi_buf_free(buf); 1991 return QDF_STATUS_E_FAILURE; 1992 } 1993 1994 return 0; 1995 } 1996 1997 /** 1998 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1999 * @wmi_handle: wmi handle 2000 * @peer_addr: peer mac address 2001 * @param: pointer to sta_ps parameter structure 2002 * 2003 * Return: QDF_STATUS_SUCCESS for success or error code 2004 */ 2005 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2006 struct sta_ps_params *param) 2007 { 2008 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2009 wmi_buf_t buf; 2010 int32_t len = sizeof(*cmd); 2011 2012 buf = wmi_buf_alloc(wmi_handle, len); 2013 if (!buf) 2014 return QDF_STATUS_E_NOMEM; 2015 2016 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2017 WMITLV_SET_HDR(&cmd->tlv_header, 2018 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2019 WMITLV_GET_STRUCT_TLVLEN 2020 (wmi_sta_powersave_param_cmd_fixed_param)); 2021 cmd->vdev_id = param->vdev_id; 2022 cmd->param = param->param_id; 2023 cmd->value = param->value; 2024 2025 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2026 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2027 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2028 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2029 param->vdev_id, param->param_id, param->value); 2030 wmi_buf_free(buf); 2031 return QDF_STATUS_E_FAILURE; 2032 } 2033 2034 return 0; 2035 } 2036 2037 /** 2038 * send_crash_inject_cmd_tlv() - inject fw crash 2039 * @wmi_handle: wmi handle 2040 * @param: ponirt to crash inject parameter structure 2041 * 2042 * Return: QDF_STATUS_SUCCESS for success or return error 2043 */ 2044 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2045 struct crash_inject *param) 2046 { 2047 int32_t ret = 0; 2048 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2049 uint16_t len = sizeof(*cmd); 2050 wmi_buf_t buf; 2051 2052 buf = wmi_buf_alloc(wmi_handle, len); 2053 if (!buf) 2054 return QDF_STATUS_E_NOMEM; 2055 2056 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2057 WMITLV_SET_HDR(&cmd->tlv_header, 2058 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2059 WMITLV_GET_STRUCT_TLVLEN 2060 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2061 cmd->type = param->type; 2062 cmd->delay_time_ms = param->delay_time_ms; 2063 2064 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2065 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2066 WMI_FORCE_FW_HANG_CMDID); 2067 if (ret) { 2068 wmi_err("Failed to send set param command, ret = %d", ret); 2069 wmi_buf_free(buf); 2070 } 2071 2072 return ret; 2073 } 2074 2075 /** 2076 * send_dbglog_cmd_tlv() - set debug log level 2077 * @param wmi_handle : handle to WMI. 2078 * @param param : pointer to hold dbglog level parameter 2079 * 2080 * Return: 0 on success and -ve on failure. 2081 */ 2082 static QDF_STATUS 2083 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2084 struct dbglog_params *dbglog_param) 2085 { 2086 wmi_buf_t buf; 2087 wmi_debug_log_config_cmd_fixed_param *configmsg; 2088 QDF_STATUS status; 2089 int32_t i; 2090 int32_t len; 2091 int8_t *buf_ptr; 2092 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2093 2094 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2095 2096 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2097 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2098 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2099 buf = wmi_buf_alloc(wmi_handle, len); 2100 if (!buf) 2101 return QDF_STATUS_E_NOMEM; 2102 2103 configmsg = 2104 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2105 buf_ptr = (int8_t *) configmsg; 2106 WMITLV_SET_HDR(&configmsg->tlv_header, 2107 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2108 WMITLV_GET_STRUCT_TLVLEN 2109 (wmi_debug_log_config_cmd_fixed_param)); 2110 configmsg->dbg_log_param = dbglog_param->param; 2111 configmsg->value = dbglog_param->val; 2112 /* Filling in the data part of second tlv -- should 2113 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2114 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2115 sizeof 2116 (wmi_debug_log_config_cmd_fixed_param) 2117 + WMI_TLV_HDR_SIZE); 2118 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2119 WMITLV_TAG_ARRAY_UINT32, 2120 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2121 if (dbglog_param->module_id_bitmap) { 2122 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2123 module_id_bitmap_array[i] = 2124 dbglog_param->module_id_bitmap[i]; 2125 } 2126 } 2127 2128 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2129 status = wmi_unified_cmd_send(wmi_handle, buf, 2130 len, WMI_DBGLOG_CFG_CMDID); 2131 2132 if (status != QDF_STATUS_SUCCESS) 2133 wmi_buf_free(buf); 2134 2135 return status; 2136 } 2137 2138 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2139 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2140 { 2141 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2142 return vdev_param_tlv[host_param]; 2143 return WMI_UNAVAILABLE_PARAM; 2144 } 2145 #else 2146 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2147 { 2148 return host_param; 2149 } 2150 #endif 2151 2152 /** 2153 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2154 * @param wmi_handle : handle to WMI. 2155 * @param macaddr : MAC address 2156 * @param param : pointer to hold vdev set parameter 2157 * 2158 * Return: 0 on success and -ve on failure. 2159 */ 2160 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2161 struct vdev_set_params *param) 2162 { 2163 QDF_STATUS ret; 2164 wmi_vdev_set_param_cmd_fixed_param *cmd; 2165 wmi_buf_t buf; 2166 uint16_t len = sizeof(*cmd); 2167 uint32_t vdev_param; 2168 2169 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2170 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2171 wmi_err("Vdev param %d not available", param->param_id); 2172 return QDF_STATUS_E_INVAL; 2173 2174 } 2175 2176 buf = wmi_buf_alloc(wmi_handle, len); 2177 if (!buf) 2178 return QDF_STATUS_E_NOMEM; 2179 2180 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2181 WMITLV_SET_HDR(&cmd->tlv_header, 2182 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2183 WMITLV_GET_STRUCT_TLVLEN 2184 (wmi_vdev_set_param_cmd_fixed_param)); 2185 cmd->vdev_id = param->vdev_id; 2186 cmd->param_id = vdev_param; 2187 cmd->param_value = param->param_value; 2188 wmi_debug("Setting vdev %d param = %x, value = %u", 2189 cmd->vdev_id, cmd->param_id, cmd->param_value); 2190 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2191 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2192 WMI_VDEV_SET_PARAM_CMDID); 2193 if (QDF_IS_STATUS_ERROR(ret)) { 2194 wmi_err("Failed to send set param command ret = %d", ret); 2195 wmi_buf_free(buf); 2196 } 2197 2198 return ret; 2199 } 2200 2201 /** 2202 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2203 * @wmi_handle: handle to WMI. 2204 * @macaddr: Peer mac address to be filter 2205 * @mac_id: mac id to have radio context 2206 * @enb_dsb: Enable MAC based filtering or Disable 2207 * 2208 * Return: QDF_STATUS 2209 */ 2210 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2211 uint8_t *macaddr, 2212 uint8_t mac_id, 2213 uint8_t enb_dsb) 2214 { 2215 int32_t ret; 2216 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2217 wmi_pdev_pktlog_filter_info *mac_info; 2218 wmi_buf_t buf; 2219 uint8_t *buf_ptr; 2220 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2221 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2222 2223 buf = wmi_buf_alloc(wmi_handle, len); 2224 if (!buf) 2225 return QDF_STATUS_E_NOMEM; 2226 2227 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2228 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2229 WMITLV_SET_HDR(&cmd->tlv_header, 2230 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2231 WMITLV_GET_STRUCT_TLVLEN 2232 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2233 cmd->pdev_id = mac_id; 2234 cmd->enable = enb_dsb; 2235 cmd->num_of_mac_addresses = 1; 2236 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2237 2238 buf_ptr += sizeof(*cmd); 2239 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2240 sizeof(wmi_pdev_pktlog_filter_info)); 2241 buf_ptr += WMI_TLV_HDR_SIZE; 2242 2243 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2244 2245 WMITLV_SET_HDR(&mac_info->tlv_header, 2246 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2247 WMITLV_GET_STRUCT_TLVLEN 2248 (wmi_pdev_pktlog_filter_info)); 2249 2250 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2251 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2252 WMI_PDEV_PKTLOG_FILTER_CMDID); 2253 if (ret) { 2254 wmi_err("Failed to send peer based pktlog command to FW =%d" 2255 , ret); 2256 wmi_buf_free(buf); 2257 } 2258 2259 return ret; 2260 } 2261 2262 /** 2263 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2264 * @param wmi_handle : handle to WMI. 2265 * @param PKTLOG_EVENT : packet log event 2266 * @mac_id: mac id to have radio context 2267 * 2268 * Return: 0 on success and -ve on failure. 2269 */ 2270 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2271 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2272 { 2273 int32_t ret, idx, max_idx; 2274 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2275 wmi_buf_t buf; 2276 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2277 2278 buf = wmi_buf_alloc(wmi_handle, len); 2279 if (!buf) 2280 return -QDF_STATUS_E_NOMEM; 2281 2282 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2283 WMITLV_SET_HDR(&cmd->tlv_header, 2284 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2285 WMITLV_GET_STRUCT_TLVLEN 2286 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2287 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2288 cmd->evlist = 0; 2289 for (idx = 0; idx < max_idx; idx++) { 2290 if (PKTLOG_EVENT & (1 << idx)) 2291 cmd->evlist |= pktlog_event_tlv[idx]; 2292 } 2293 cmd->pdev_id = mac_id; 2294 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2295 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2296 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2297 if (ret) { 2298 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 2299 wmi_buf_free(buf); 2300 } 2301 2302 return ret; 2303 } 2304 2305 /** 2306 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2307 * @param wmi_handle : handle to WMI. 2308 * @mac_id: mac id to have radio context 2309 * 2310 * Return: 0 on success and -ve on failure. 2311 */ 2312 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 2313 uint8_t mac_id) 2314 { 2315 int32_t ret; 2316 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2317 wmi_buf_t buf; 2318 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 2319 2320 buf = wmi_buf_alloc(wmi_handle, len); 2321 if (!buf) 2322 return -QDF_STATUS_E_NOMEM; 2323 2324 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 2325 WMITLV_SET_HDR(&cmd->tlv_header, 2326 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2327 WMITLV_GET_STRUCT_TLVLEN 2328 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2329 cmd->pdev_id = mac_id; 2330 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2331 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2332 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2333 if (ret) { 2334 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 2335 wmi_buf_free(buf); 2336 } 2337 2338 return ret; 2339 } 2340 2341 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2342 /** 2343 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2344 * sync time between bwtween host and firmware 2345 * @param wmi_handle : handle to WMI. 2346 * 2347 * Return: None 2348 */ 2349 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2350 { 2351 wmi_buf_t buf; 2352 QDF_STATUS status = QDF_STATUS_SUCCESS; 2353 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2354 int32_t len; 2355 qdf_time_t time_ms; 2356 2357 len = sizeof(*time_stamp); 2358 buf = wmi_buf_alloc(wmi_handle, len); 2359 2360 if (!buf) 2361 return; 2362 2363 time_stamp = 2364 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2365 (wmi_buf_data(buf)); 2366 WMITLV_SET_HDR(&time_stamp->tlv_header, 2367 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2368 WMITLV_GET_STRUCT_TLVLEN( 2369 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2370 2371 time_ms = qdf_get_time_of_the_day_ms(); 2372 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2373 time_stamp->time_stamp_low = time_ms & 2374 WMI_FW_TIME_STAMP_LOW_MASK; 2375 /* 2376 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2377 * wont exceed 27 bit 2378 */ 2379 time_stamp->time_stamp_high = 0; 2380 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 2381 time_stamp->mode, time_stamp->time_stamp_low, 2382 time_stamp->time_stamp_high); 2383 2384 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2385 status = wmi_unified_cmd_send(wmi_handle, buf, 2386 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2387 if (status) { 2388 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2389 wmi_buf_free(buf); 2390 } 2391 2392 } 2393 2394 /** 2395 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2396 * @param wmi_handle : handle to WMI. 2397 * @param param : pointer to hold FILS Discovery send cmd parameter 2398 * 2399 * Return: 0 on success and -ve on failure. 2400 */ 2401 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2402 struct fils_discovery_tmpl_params *param) 2403 { 2404 int32_t ret; 2405 wmi_fd_tmpl_cmd_fixed_param *cmd; 2406 wmi_buf_t wmi_buf; 2407 uint8_t *buf_ptr; 2408 uint32_t wmi_buf_len; 2409 2410 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2411 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2412 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2413 if (!wmi_buf) 2414 return QDF_STATUS_E_NOMEM; 2415 2416 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2417 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2418 WMITLV_SET_HDR(&cmd->tlv_header, 2419 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2420 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2421 cmd->vdev_id = param->vdev_id; 2422 cmd->buf_len = param->tmpl_len; 2423 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2424 2425 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2426 buf_ptr += WMI_TLV_HDR_SIZE; 2427 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2428 2429 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2430 ret = wmi_unified_cmd_send(wmi_handle, 2431 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2432 2433 if (ret) { 2434 wmi_err("Failed to send fd tmpl: %d", ret); 2435 wmi_buf_free(wmi_buf); 2436 return ret; 2437 } 2438 2439 return 0; 2440 } 2441 2442 /** 2443 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2444 * @param wmi_handle : handle to WMI. 2445 * @param param : pointer to hold beacon send cmd parameter 2446 * 2447 * Return: 0 on success and -ve on failure. 2448 */ 2449 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2450 struct beacon_tmpl_params *param) 2451 { 2452 int32_t ret; 2453 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2454 wmi_bcn_prb_info *bcn_prb_info; 2455 wmi_buf_t wmi_buf; 2456 uint8_t *buf_ptr; 2457 uint32_t wmi_buf_len; 2458 2459 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2460 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2461 param->tmpl_len_aligned; 2462 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2463 if (!wmi_buf) 2464 return QDF_STATUS_E_NOMEM; 2465 2466 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2467 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2468 WMITLV_SET_HDR(&cmd->tlv_header, 2469 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2470 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2471 cmd->vdev_id = param->vdev_id; 2472 cmd->tim_ie_offset = param->tim_ie_offset; 2473 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2474 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2475 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2476 cmd->esp_ie_offset = param->esp_ie_offset; 2477 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2478 cmd->ema_params = param->ema_params; 2479 cmd->buf_len = param->tmpl_len; 2480 cmd->csa_event_bitmap = param->csa_event_bitmap; 2481 2482 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 2483 param->enable_bigtk); 2484 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2485 2486 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2487 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2488 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2489 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2490 bcn_prb_info->caps = 0; 2491 bcn_prb_info->erp = 0; 2492 buf_ptr += sizeof(wmi_bcn_prb_info); 2493 2494 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2495 buf_ptr += WMI_TLV_HDR_SIZE; 2496 2497 /* for big endian host, copy engine byte_swap is enabled 2498 * But the frame content is in network byte order 2499 * Need to byte swap the frame content - so when copy engine 2500 * does byte_swap - target gets frame content in the correct order 2501 */ 2502 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 2503 param->tmpl_len); 2504 2505 buf_ptr += param->tmpl_len; 2506 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 2507 2508 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2509 ret = wmi_unified_cmd_send(wmi_handle, 2510 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2511 if (ret) { 2512 wmi_err("Failed to send bcn tmpl: %d", ret); 2513 wmi_buf_free(wmi_buf); 2514 } 2515 2516 return 0; 2517 } 2518 2519 #ifdef WLAN_FEATURE_11BE 2520 static inline void copy_peer_flags_tlv_11be( 2521 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2522 struct peer_assoc_params *param) 2523 { 2524 if (param->bw_320) 2525 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 2526 if (param->eht_flag) 2527 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 2528 2529 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 2530 } 2531 #else 2532 static inline void copy_peer_flags_tlv_11be( 2533 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2534 struct peer_assoc_params *param) 2535 { 2536 } 2537 #endif 2538 2539 static inline void copy_peer_flags_tlv( 2540 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2541 struct peer_assoc_params *param) 2542 { 2543 /* 2544 * The target only needs a subset of the flags maintained in the host. 2545 * Just populate those flags and send it down 2546 */ 2547 cmd->peer_flags = 0; 2548 2549 /* 2550 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2551 */ 2552 if (param->is_wme_set) { 2553 2554 if (param->qos_flag) 2555 cmd->peer_flags |= WMI_PEER_QOS; 2556 if (param->apsd_flag) 2557 cmd->peer_flags |= WMI_PEER_APSD; 2558 if (param->ht_flag) 2559 cmd->peer_flags |= WMI_PEER_HT; 2560 if (param->bw_40) 2561 cmd->peer_flags |= WMI_PEER_40MHZ; 2562 if (param->bw_80) 2563 cmd->peer_flags |= WMI_PEER_80MHZ; 2564 if (param->bw_160) 2565 cmd->peer_flags |= WMI_PEER_160MHZ; 2566 2567 copy_peer_flags_tlv_11be(cmd, param); 2568 2569 /* Typically if STBC is enabled for VHT it should be enabled 2570 * for HT as well 2571 **/ 2572 if (param->stbc_flag) 2573 cmd->peer_flags |= WMI_PEER_STBC; 2574 2575 /* Typically if LDPC is enabled for VHT it should be enabled 2576 * for HT as well 2577 **/ 2578 if (param->ldpc_flag) 2579 cmd->peer_flags |= WMI_PEER_LDPC; 2580 2581 if (param->static_mimops_flag) 2582 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2583 if (param->dynamic_mimops_flag) 2584 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2585 if (param->spatial_mux_flag) 2586 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2587 if (param->vht_flag) 2588 cmd->peer_flags |= WMI_PEER_VHT; 2589 if (param->he_flag) 2590 cmd->peer_flags |= WMI_PEER_HE; 2591 if (param->p2p_capable_sta) 2592 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2593 } 2594 2595 if (param->is_pmf_enabled) 2596 cmd->peer_flags |= WMI_PEER_PMF; 2597 /* 2598 * Suppress authorization for all AUTH modes that need 4-way handshake 2599 * (during re-association). 2600 * Authorization will be done for these modes on key installation. 2601 */ 2602 if (param->auth_flag) 2603 cmd->peer_flags |= WMI_PEER_AUTH; 2604 if (param->need_ptk_4_way) 2605 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2606 else 2607 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2608 if (param->need_gtk_2_way) 2609 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2610 /* safe mode bypass the 4-way handshake */ 2611 if (param->safe_mode_enabled) 2612 cmd->peer_flags &= 2613 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2614 /* inter BSS peer */ 2615 if (param->inter_bss_peer) 2616 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2617 /* Disable AMSDU for station transmit, if user configures it */ 2618 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2619 * it 2620 * if (param->amsdu_disable) Add after FW support 2621 **/ 2622 2623 /* Target asserts if node is marked HT and all MCS is set to 0. 2624 * Mark the node as non-HT if all the mcs rates are disabled through 2625 * iwpriv 2626 **/ 2627 if (param->peer_ht_rates.num_rates == 0) 2628 cmd->peer_flags &= ~WMI_PEER_HT; 2629 2630 if (param->twt_requester) 2631 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2632 2633 if (param->twt_responder) 2634 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2635 } 2636 2637 static inline void copy_peer_mac_addr_tlv( 2638 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2639 struct peer_assoc_params *param) 2640 { 2641 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2642 } 2643 2644 #ifdef WLAN_FEATURE_11BE 2645 static uint8_t *update_peer_flags_tlv_ehtinfo( 2646 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2647 struct peer_assoc_params *param, uint8_t *buf_ptr) 2648 { 2649 wmi_eht_rate_set *eht_mcs; 2650 int i; 2651 2652 cmd->peer_eht_ops = param->peer_eht_ops; 2653 cmd->puncture_20mhz_bitmap = param->puncture_pattern; 2654 2655 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 2656 sizeof(param->peer_eht_cap_macinfo)); 2657 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 2658 sizeof(param->peer_eht_cap_phyinfo)); 2659 2660 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2661 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 2662 buf_ptr += WMI_TLV_HDR_SIZE; 2663 2664 /* Loop through the EHT rate set */ 2665 for (i = 0; i < param->peer_eht_mcs_count; i++) { 2666 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 2667 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 2668 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 2669 2670 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 2671 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 2672 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 2673 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 2674 buf_ptr += sizeof(wmi_eht_rate_set); 2675 } 2676 2677 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 2678 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2679 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 2680 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 2681 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2682 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 2683 param->peer_eht_tx_mcs_set 2684 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2685 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 2686 param->peer_eht_rx_mcs_set 2687 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2688 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2689 QDF_MAC_ADDR_REF(param->peer_mac)); 2690 } 2691 2692 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 2693 cmd->peer_eht_cap_mac[0], 2694 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 2695 cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], 2696 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 2697 2698 return buf_ptr; 2699 } 2700 #else 2701 static uint8_t *update_peer_flags_tlv_ehtinfo( 2702 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2703 struct peer_assoc_params *param, uint8_t *buf_ptr) 2704 { 2705 return buf_ptr; 2706 } 2707 #endif 2708 2709 #ifdef WLAN_FEATURE_11BE 2710 static 2711 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 2712 { 2713 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 2714 + WMI_TLV_HDR_SIZE); 2715 } 2716 2717 static void wmi_populate_service_11be(uint32_t *wmi_service) 2718 { 2719 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 2720 } 2721 2722 #else 2723 static 2724 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 2725 { 2726 return 0; 2727 } 2728 2729 static void wmi_populate_service_11be(uint32_t *wmi_service) 2730 { 2731 } 2732 2733 #endif 2734 2735 /** 2736 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2737 * @param wmi_handle : handle to WMI. 2738 * @param param : pointer to peer assoc parameter 2739 * 2740 * Return: 0 on success and -ve on failure. 2741 */ 2742 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2743 struct peer_assoc_params *param) 2744 { 2745 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2746 wmi_vht_rate_set *mcs; 2747 wmi_he_rate_set *he_mcs; 2748 wmi_buf_t buf; 2749 int32_t len; 2750 uint8_t *buf_ptr; 2751 QDF_STATUS ret; 2752 uint32_t peer_legacy_rates_align; 2753 uint32_t peer_ht_rates_align; 2754 int32_t i; 2755 2756 2757 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2758 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2759 2760 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2761 (peer_legacy_rates_align * sizeof(uint8_t)) + 2762 WMI_TLV_HDR_SIZE + 2763 (peer_ht_rates_align * sizeof(uint8_t)) + 2764 sizeof(wmi_vht_rate_set) + 2765 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2766 + WMI_TLV_HDR_SIZE) 2767 + wmi_eht_peer_assoc_params_len(param) + 2768 peer_assoc_mlo_params_size(param); 2769 2770 buf = wmi_buf_alloc(wmi_handle, len); 2771 if (!buf) 2772 return QDF_STATUS_E_NOMEM; 2773 2774 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2775 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2776 WMITLV_SET_HDR(&cmd->tlv_header, 2777 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2778 WMITLV_GET_STRUCT_TLVLEN 2779 (wmi_peer_assoc_complete_cmd_fixed_param)); 2780 2781 cmd->vdev_id = param->vdev_id; 2782 2783 cmd->peer_new_assoc = param->peer_new_assoc; 2784 cmd->peer_associd = param->peer_associd; 2785 2786 copy_peer_flags_tlv(cmd, param); 2787 copy_peer_mac_addr_tlv(cmd, param); 2788 2789 cmd->peer_rate_caps = param->peer_rate_caps; 2790 cmd->peer_caps = param->peer_caps; 2791 cmd->peer_listen_intval = param->peer_listen_intval; 2792 cmd->peer_ht_caps = param->peer_ht_caps; 2793 cmd->peer_max_mpdu = param->peer_max_mpdu; 2794 cmd->peer_mpdu_density = param->peer_mpdu_density; 2795 cmd->peer_vht_caps = param->peer_vht_caps; 2796 cmd->peer_phymode = param->peer_phymode; 2797 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 2798 2799 /* Update 11ax capabilities */ 2800 cmd->peer_he_cap_info = 2801 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2802 cmd->peer_he_cap_info_ext = 2803 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2804 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 2805 cmd->peer_he_ops = param->peer_he_ops; 2806 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2807 sizeof(param->peer_he_cap_phyinfo)); 2808 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2809 sizeof(param->peer_ppet)); 2810 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 2811 2812 /* Update peer legacy rate information */ 2813 buf_ptr += sizeof(*cmd); 2814 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2815 peer_legacy_rates_align); 2816 buf_ptr += WMI_TLV_HDR_SIZE; 2817 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2818 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2819 param->peer_legacy_rates.num_rates); 2820 2821 /* Update peer HT rate information */ 2822 buf_ptr += peer_legacy_rates_align; 2823 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2824 peer_ht_rates_align); 2825 buf_ptr += WMI_TLV_HDR_SIZE; 2826 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2827 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2828 param->peer_ht_rates.num_rates); 2829 2830 /* VHT Rates */ 2831 buf_ptr += peer_ht_rates_align; 2832 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2833 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2834 2835 cmd->auth_mode = param->akm; 2836 cmd->peer_nss = param->peer_nss; 2837 2838 /* Update bandwidth-NSS mapping */ 2839 cmd->peer_bw_rxnss_override = 0; 2840 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2841 2842 mcs = (wmi_vht_rate_set *) buf_ptr; 2843 if (param->vht_capable) { 2844 mcs->rx_max_rate = param->rx_max_rate; 2845 mcs->rx_mcs_set = param->rx_mcs_set; 2846 mcs->tx_max_rate = param->tx_max_rate; 2847 mcs->tx_mcs_set = param->tx_mcs_set; 2848 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 2849 } 2850 2851 /* HE Rates */ 2852 cmd->min_data_rate = param->min_data_rate; 2853 cmd->peer_he_mcs = param->peer_he_mcs_count; 2854 buf_ptr += sizeof(wmi_vht_rate_set); 2855 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2856 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2857 buf_ptr += WMI_TLV_HDR_SIZE; 2858 2859 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 2860 /* Loop through the HE rate set */ 2861 for (i = 0; i < param->peer_he_mcs_count; i++) { 2862 he_mcs = (wmi_he_rate_set *) buf_ptr; 2863 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2864 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2865 2866 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2867 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2868 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 2869 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2870 buf_ptr += sizeof(wmi_he_rate_set); 2871 } 2872 2873 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 2874 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2875 == WMI_HOST_HE_INVALID_MCSNSSMAP || 2876 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2877 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2878 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 2879 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2880 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 2881 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2882 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 2883 QDF_MAC_ADDR_REF(param->peer_mac)); 2884 } 2885 2886 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 2887 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2888 "nss %d phymode %d peer_mpdu_density %d " 2889 "cmd->peer_vht_caps %x " 2890 "HE cap_info %x ops %x " 2891 "HE cap_info_ext %x " 2892 "HE phy %x %x %x " 2893 "peer_bw_rxnss_override %x", 2894 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2895 cmd->peer_rate_caps, cmd->peer_caps, 2896 cmd->peer_listen_intval, cmd->peer_ht_caps, 2897 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2898 cmd->peer_mpdu_density, 2899 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2900 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2901 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2902 cmd->peer_he_cap_phy[2], 2903 cmd->peer_bw_rxnss_override); 2904 2905 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 2906 2907 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 2908 2909 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 2910 2911 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2912 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2913 WMI_PEER_ASSOC_CMDID); 2914 if (QDF_IS_STATUS_ERROR(ret)) { 2915 wmi_err("Failed to send peer assoc command ret = %d", ret); 2916 wmi_buf_free(buf); 2917 } 2918 2919 return ret; 2920 } 2921 2922 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2923 */ 2924 static inline void copy_scan_event_cntrl_flags( 2925 wmi_start_scan_cmd_fixed_param * cmd, 2926 struct scan_req_params *param) 2927 { 2928 2929 /* Scan events subscription */ 2930 if (param->scan_ev_started) 2931 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2932 if (param->scan_ev_completed) 2933 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2934 if (param->scan_ev_bss_chan) 2935 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2936 if (param->scan_ev_foreign_chan) 2937 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2938 if (param->scan_ev_dequeued) 2939 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2940 if (param->scan_ev_preempted) 2941 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2942 if (param->scan_ev_start_failed) 2943 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2944 if (param->scan_ev_restarted) 2945 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2946 if (param->scan_ev_foreign_chn_exit) 2947 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2948 if (param->scan_ev_suspended) 2949 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2950 if (param->scan_ev_resumed) 2951 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2952 2953 /** Set scan control flags */ 2954 cmd->scan_ctrl_flags = 0; 2955 if (param->scan_f_passive) 2956 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2957 if (param->scan_f_strict_passive_pch) 2958 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2959 if (param->scan_f_promisc_mode) 2960 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2961 if (param->scan_f_capture_phy_err) 2962 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2963 if (param->scan_f_half_rate) 2964 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2965 if (param->scan_f_quarter_rate) 2966 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2967 if (param->scan_f_cck_rates) 2968 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2969 if (param->scan_f_ofdm_rates) 2970 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2971 if (param->scan_f_chan_stat_evnt) 2972 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2973 if (param->scan_f_filter_prb_req) 2974 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2975 if (param->scan_f_bcast_probe) 2976 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2977 if (param->scan_f_offchan_mgmt_tx) 2978 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2979 if (param->scan_f_offchan_data_tx) 2980 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2981 if (param->scan_f_force_active_dfs_chn) 2982 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2983 if (param->scan_f_add_tpc_ie_in_probe) 2984 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2985 if (param->scan_f_add_ds_ie_in_probe) 2986 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2987 if (param->scan_f_add_spoofed_mac_in_probe) 2988 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2989 if (param->scan_f_add_rand_seq_in_probe) 2990 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2991 if (param->scan_f_en_ie_whitelist_in_probe) 2992 cmd->scan_ctrl_flags |= 2993 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2994 2995 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2996 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2997 param->adaptive_dwell_time_mode); 2998 } 2999 3000 /* scan_copy_ie_buffer() - Copy scan ie_data */ 3001 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 3002 struct scan_req_params *params) 3003 { 3004 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 3005 } 3006 3007 /** 3008 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 3009 * @mac: random mac addr 3010 * @mask: random mac mask 3011 * @mac_addr: wmi random mac 3012 * @mac_mask: wmi random mac mask 3013 * 3014 * Return None. 3015 */ 3016 static inline 3017 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 3018 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 3019 { 3020 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 3021 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 3022 } 3023 3024 /* 3025 * wmi_fill_vendor_oui() - fill vendor OUIs 3026 * @buf_ptr: pointer to wmi tlv buffer 3027 * @num_vendor_oui: number of vendor OUIs to be filled 3028 * @param_voui: pointer to OUI buffer 3029 * 3030 * This function populates the wmi tlv buffer when vendor specific OUIs are 3031 * present. 3032 * 3033 * Return: None 3034 */ 3035 static inline 3036 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 3037 uint32_t *pvoui) 3038 { 3039 wmi_vendor_oui *voui = NULL; 3040 uint32_t i; 3041 3042 voui = (wmi_vendor_oui *)buf_ptr; 3043 3044 for (i = 0; i < num_vendor_oui; i++) { 3045 WMITLV_SET_HDR(&voui[i].tlv_header, 3046 WMITLV_TAG_STRUC_wmi_vendor_oui, 3047 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 3048 voui[i].oui_type_subtype = pvoui[i]; 3049 } 3050 } 3051 3052 /* 3053 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 3054 * @ie_bitmap: output pointer to ie bit map in cmd 3055 * @num_vendor_oui: output pointer to num vendor OUIs 3056 * @ie_whitelist: input parameter 3057 * 3058 * This function populates the IE whitelist attrs of scan, pno and 3059 * scan oui commands for ie_whitelist parameter. 3060 * 3061 * Return: None 3062 */ 3063 static inline 3064 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 3065 uint32_t *num_vendor_oui, 3066 struct probe_req_whitelist_attr *ie_whitelist) 3067 { 3068 uint32_t i = 0; 3069 3070 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 3071 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 3072 3073 *num_vendor_oui = ie_whitelist->num_vendor_oui; 3074 } 3075 3076 /** 3077 * send_scan_start_cmd_tlv() - WMI scan start function 3078 * @param wmi_handle : handle to WMI. 3079 * @param param : pointer to hold scan start cmd parameter 3080 * 3081 * Return: 0 on success and -ve on failure. 3082 */ 3083 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 3084 struct scan_req_params *params) 3085 { 3086 int32_t ret = 0; 3087 int32_t i; 3088 wmi_buf_t wmi_buf; 3089 wmi_start_scan_cmd_fixed_param *cmd; 3090 uint8_t *buf_ptr; 3091 uint32_t *tmp_ptr; 3092 wmi_ssid *ssid = NULL; 3093 wmi_mac_addr *bssid; 3094 size_t len = sizeof(*cmd); 3095 uint16_t extraie_len_with_pad = 0; 3096 uint8_t phymode_roundup = 0; 3097 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 3098 wmi_hint_freq_short_ssid *s_ssid = NULL; 3099 wmi_hint_freq_bssid *hint_bssid = NULL; 3100 3101 /* Length TLV placeholder for array of uint32_t */ 3102 len += WMI_TLV_HDR_SIZE; 3103 /* calculate the length of buffer required */ 3104 if (params->chan_list.num_chan) 3105 len += params->chan_list.num_chan * sizeof(uint32_t); 3106 3107 /* Length TLV placeholder for array of wmi_ssid structures */ 3108 len += WMI_TLV_HDR_SIZE; 3109 if (params->num_ssids) 3110 len += params->num_ssids * sizeof(wmi_ssid); 3111 3112 /* Length TLV placeholder for array of wmi_mac_addr structures */ 3113 len += WMI_TLV_HDR_SIZE; 3114 if (params->num_bssid) 3115 len += sizeof(wmi_mac_addr) * params->num_bssid; 3116 3117 /* Length TLV placeholder for array of bytes */ 3118 len += WMI_TLV_HDR_SIZE; 3119 if (params->extraie.len) 3120 extraie_len_with_pad = 3121 roundup(params->extraie.len, sizeof(uint32_t)); 3122 len += extraie_len_with_pad; 3123 3124 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 3125 if (ie_whitelist->num_vendor_oui) 3126 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 3127 3128 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 3129 if (params->scan_f_wide_band) 3130 phymode_roundup = 3131 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 3132 sizeof(uint32_t)); 3133 len += phymode_roundup; 3134 3135 len += WMI_TLV_HDR_SIZE; 3136 if (params->num_hint_bssid) 3137 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 3138 3139 len += WMI_TLV_HDR_SIZE; 3140 if (params->num_hint_s_ssid) 3141 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 3142 3143 /* Allocate the memory */ 3144 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3145 if (!wmi_buf) 3146 return QDF_STATUS_E_FAILURE; 3147 3148 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3149 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 3150 WMITLV_SET_HDR(&cmd->tlv_header, 3151 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 3152 WMITLV_GET_STRUCT_TLVLEN 3153 (wmi_start_scan_cmd_fixed_param)); 3154 3155 cmd->scan_id = params->scan_id; 3156 cmd->scan_req_id = params->scan_req_id; 3157 cmd->vdev_id = params->vdev_id; 3158 cmd->scan_priority = params->scan_priority; 3159 3160 copy_scan_event_cntrl_flags(cmd, params); 3161 3162 cmd->dwell_time_active = params->dwell_time_active; 3163 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 3164 cmd->dwell_time_passive = params->dwell_time_passive; 3165 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 3166 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 3167 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 3168 cmd->scan_start_offset = params->scan_offset_time; 3169 cmd->min_rest_time = params->min_rest_time; 3170 cmd->max_rest_time = params->max_rest_time; 3171 cmd->repeat_probe_time = params->repeat_probe_time; 3172 cmd->probe_spacing_time = params->probe_spacing_time; 3173 cmd->idle_time = params->idle_time; 3174 cmd->max_scan_time = params->max_scan_time; 3175 cmd->probe_delay = params->probe_delay; 3176 cmd->burst_duration = params->burst_duration; 3177 cmd->num_chan = params->chan_list.num_chan; 3178 cmd->num_bssid = params->num_bssid; 3179 cmd->num_ssids = params->num_ssids; 3180 cmd->ie_len = params->extraie.len; 3181 cmd->n_probes = params->n_probes; 3182 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3183 3184 if (params->scan_random.randomize) 3185 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3186 params->scan_random.mac_mask, 3187 &cmd->mac_addr, 3188 &cmd->mac_mask); 3189 3190 if (ie_whitelist->white_list) 3191 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 3192 &cmd->num_vendor_oui, 3193 ie_whitelist); 3194 3195 buf_ptr += sizeof(*cmd); 3196 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3197 for (i = 0; i < params->chan_list.num_chan; ++i) { 3198 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 3199 params->chan_list.chan[i].freq); 3200 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 3201 params->chan_list.chan[i].flags); 3202 } 3203 3204 WMITLV_SET_HDR(buf_ptr, 3205 WMITLV_TAG_ARRAY_UINT32, 3206 (params->chan_list.num_chan * sizeof(uint32_t))); 3207 buf_ptr += WMI_TLV_HDR_SIZE + 3208 (params->chan_list.num_chan * sizeof(uint32_t)); 3209 3210 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3211 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 3212 goto error; 3213 } 3214 3215 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3216 (params->num_ssids * sizeof(wmi_ssid))); 3217 3218 if (params->num_ssids) { 3219 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3220 for (i = 0; i < params->num_ssids; ++i) { 3221 ssid->ssid_len = params->ssid[i].length; 3222 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3223 params->ssid[i].length); 3224 ssid++; 3225 } 3226 } 3227 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3228 3229 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3230 (params->num_bssid * sizeof(wmi_mac_addr))); 3231 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3232 3233 if (params->num_bssid) { 3234 for (i = 0; i < params->num_bssid; ++i) { 3235 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3236 ¶ms->bssid_list[i].bytes[0], bssid); 3237 bssid++; 3238 } 3239 } 3240 3241 buf_ptr += WMI_TLV_HDR_SIZE + 3242 (params->num_bssid * sizeof(wmi_mac_addr)); 3243 3244 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3245 if (params->extraie.len) 3246 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3247 params); 3248 3249 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3250 3251 /* probe req ie whitelisting */ 3252 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3253 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3254 3255 buf_ptr += WMI_TLV_HDR_SIZE; 3256 3257 if (cmd->num_vendor_oui) { 3258 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3259 ie_whitelist->voui); 3260 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3261 } 3262 3263 /* Add phy mode TLV if it's a wide band scan */ 3264 if (params->scan_f_wide_band) { 3265 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3266 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3267 for (i = 0; i < params->chan_list.num_chan; ++i) 3268 buf_ptr[i] = 3269 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3270 buf_ptr += phymode_roundup; 3271 } else { 3272 /* Add ZERO legth phy mode TLV */ 3273 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3274 buf_ptr += WMI_TLV_HDR_SIZE; 3275 } 3276 3277 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3278 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3279 if (params->num_hint_s_ssid) { 3280 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3281 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3282 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3283 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3284 s_ssid++; 3285 } 3286 } 3287 buf_ptr += WMI_TLV_HDR_SIZE + 3288 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3289 3290 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3291 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3292 if (params->num_hint_bssid) { 3293 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3294 for (i = 0; i < params->num_hint_bssid; ++i) { 3295 hint_bssid->freq_flags = 3296 params->hint_bssid[i].freq_flags; 3297 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3298 &hint_bssid->bssid); 3299 hint_bssid++; 3300 } 3301 } 3302 3303 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3304 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3305 len, WMI_START_SCAN_CMDID); 3306 if (ret) { 3307 wmi_err("Failed to start scan: %d", ret); 3308 wmi_buf_free(wmi_buf); 3309 } 3310 return ret; 3311 error: 3312 wmi_buf_free(wmi_buf); 3313 return QDF_STATUS_E_FAILURE; 3314 } 3315 3316 /** 3317 * send_scan_stop_cmd_tlv() - WMI scan start function 3318 * @param wmi_handle : handle to WMI. 3319 * @param param : pointer to hold scan cancel cmd parameter 3320 * 3321 * Return: 0 on success and -ve on failure. 3322 */ 3323 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3324 struct scan_cancel_param *param) 3325 { 3326 wmi_stop_scan_cmd_fixed_param *cmd; 3327 int ret; 3328 int len = sizeof(*cmd); 3329 wmi_buf_t wmi_buf; 3330 3331 /* Allocate the memory */ 3332 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3333 if (!wmi_buf) { 3334 ret = QDF_STATUS_E_NOMEM; 3335 goto error; 3336 } 3337 3338 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3339 WMITLV_SET_HDR(&cmd->tlv_header, 3340 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3341 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3342 cmd->vdev_id = param->vdev_id; 3343 cmd->requestor = param->requester; 3344 cmd->scan_id = param->scan_id; 3345 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3346 wmi_handle, 3347 param->pdev_id); 3348 /* stop the scan with the corresponding scan_id */ 3349 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3350 /* Cancelling all scans */ 3351 cmd->req_type = WMI_SCAN_STOP_ALL; 3352 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3353 /* Cancelling VAP scans */ 3354 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3355 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3356 /* Cancelling specific scan */ 3357 cmd->req_type = WMI_SCAN_STOP_ONE; 3358 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 3359 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 3360 } else { 3361 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 3362 wmi_buf_free(wmi_buf); 3363 return QDF_STATUS_E_INVAL; 3364 } 3365 3366 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3367 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3368 len, WMI_STOP_SCAN_CMDID); 3369 if (ret) { 3370 wmi_err("Failed to send stop scan: %d", ret); 3371 wmi_buf_free(wmi_buf); 3372 } 3373 3374 error: 3375 return ret; 3376 } 3377 3378 #define WMI_MAX_CHAN_INFO_LOG 192 3379 3380 /** 3381 * wmi_scan_chanlist_dump() - Dump scan channel list info 3382 * @scan_chan_list: scan channel list 3383 * 3384 * Return: void 3385 */ 3386 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3387 { 3388 uint32_t i; 3389 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3390 uint32_t len = 0; 3391 struct channel_param *chan; 3392 int ret; 3393 3394 wmi_debug("Total chan %d", scan_chan_list->nallchans); 3395 for (i = 0; i < scan_chan_list->nallchans; i++) { 3396 chan = &scan_chan_list->ch_param[i]; 3397 ret = qdf_scnprintf(info + len, sizeof(info) - len, 3398 " %d[%d][%d]", chan->mhz, chan->maxregpower, 3399 chan->dfs_set); 3400 if (ret <= 0) 3401 break; 3402 len += ret; 3403 if (len >= (sizeof(info) - 20)) { 3404 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3405 len = 0; 3406 } 3407 } 3408 if (len) 3409 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3410 } 3411 3412 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3413 struct scan_chan_list_params *chan_list) 3414 { 3415 wmi_buf_t buf; 3416 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3417 wmi_scan_chan_list_cmd_fixed_param *cmd; 3418 int i; 3419 uint8_t *buf_ptr; 3420 wmi_channel *chan_info; 3421 struct channel_param *tchan_info; 3422 uint16_t len; 3423 uint16_t num_send_chans, num_sends = 0; 3424 3425 wmi_scan_chanlist_dump(chan_list); 3426 tchan_info = &chan_list->ch_param[0]; 3427 while (chan_list->nallchans) { 3428 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3429 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3430 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3431 else 3432 num_send_chans = chan_list->nallchans; 3433 3434 chan_list->nallchans -= num_send_chans; 3435 len += sizeof(wmi_channel) * num_send_chans; 3436 buf = wmi_buf_alloc(wmi_handle, len); 3437 if (!buf) { 3438 qdf_status = QDF_STATUS_E_NOMEM; 3439 goto end; 3440 } 3441 3442 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3443 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3444 WMITLV_SET_HDR(&cmd->tlv_header, 3445 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3446 WMITLV_GET_STRUCT_TLVLEN 3447 (wmi_scan_chan_list_cmd_fixed_param)); 3448 3449 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 3450 3451 if (num_sends) 3452 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3453 3454 if (chan_list->max_bw_support_present) 3455 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3456 3457 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3458 wmi_handle, 3459 chan_list->pdev_id); 3460 3461 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3462 3463 cmd->num_scan_chans = num_send_chans; 3464 WMITLV_SET_HDR((buf_ptr + 3465 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3466 WMITLV_TAG_ARRAY_STRUC, 3467 sizeof(wmi_channel) * num_send_chans); 3468 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3469 WMI_TLV_HDR_SIZE); 3470 3471 for (i = 0; i < num_send_chans; ++i) { 3472 WMITLV_SET_HDR(&chan_info->tlv_header, 3473 WMITLV_TAG_STRUC_wmi_channel, 3474 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3475 chan_info->mhz = tchan_info->mhz; 3476 chan_info->band_center_freq1 = 3477 tchan_info->cfreq1; 3478 chan_info->band_center_freq2 = 3479 tchan_info->cfreq2; 3480 3481 if (tchan_info->is_chan_passive) 3482 WMI_SET_CHANNEL_FLAG(chan_info, 3483 WMI_CHAN_FLAG_PASSIVE); 3484 if (tchan_info->dfs_set) 3485 WMI_SET_CHANNEL_FLAG(chan_info, 3486 WMI_CHAN_FLAG_DFS); 3487 3488 if (tchan_info->dfs_set_cfreq2) 3489 WMI_SET_CHANNEL_FLAG(chan_info, 3490 WMI_CHAN_FLAG_DFS_CFREQ2); 3491 3492 if (tchan_info->allow_he) 3493 WMI_SET_CHANNEL_FLAG(chan_info, 3494 WMI_CHAN_FLAG_ALLOW_HE); 3495 3496 if (tchan_info->allow_vht) 3497 WMI_SET_CHANNEL_FLAG(chan_info, 3498 WMI_CHAN_FLAG_ALLOW_VHT); 3499 3500 if (tchan_info->allow_ht) 3501 WMI_SET_CHANNEL_FLAG(chan_info, 3502 WMI_CHAN_FLAG_ALLOW_HT); 3503 WMI_SET_CHANNEL_MODE(chan_info, 3504 tchan_info->phy_mode); 3505 3506 if (tchan_info->half_rate) 3507 WMI_SET_CHANNEL_FLAG(chan_info, 3508 WMI_CHAN_FLAG_HALF_RATE); 3509 3510 if (tchan_info->quarter_rate) 3511 WMI_SET_CHANNEL_FLAG(chan_info, 3512 WMI_CHAN_FLAG_QUARTER_RATE); 3513 3514 if (tchan_info->psc_channel) 3515 WMI_SET_CHANNEL_FLAG(chan_info, 3516 WMI_CHAN_FLAG_PSC); 3517 3518 if (tchan_info->nan_disabled) 3519 WMI_SET_CHANNEL_FLAG(chan_info, 3520 WMI_CHAN_FLAG_NAN_DISABLED); 3521 3522 /* also fill in power information */ 3523 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3524 tchan_info->minpower); 3525 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3526 tchan_info->maxpower); 3527 WMI_SET_CHANNEL_REG_POWER(chan_info, 3528 tchan_info->maxregpower); 3529 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3530 tchan_info->antennamax); 3531 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3532 tchan_info->reg_class_id); 3533 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3534 tchan_info->maxregpower); 3535 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3536 tchan_info->max_bw_supported); 3537 3538 tchan_info++; 3539 chan_info++; 3540 } 3541 3542 qdf_status = wmi_unified_cmd_send( 3543 wmi_handle, 3544 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3545 3546 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3547 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3548 wmi_buf_free(buf); 3549 goto end; 3550 } 3551 num_sends++; 3552 } 3553 3554 end: 3555 return qdf_status; 3556 } 3557 3558 /** 3559 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3560 * 3561 * @bufp: Pointer to buffer 3562 * @param: Pointer to tx param 3563 * 3564 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3565 */ 3566 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3567 struct tx_send_params param) 3568 { 3569 wmi_tx_send_params *tx_param; 3570 QDF_STATUS status = QDF_STATUS_SUCCESS; 3571 3572 if (!bufp) { 3573 status = QDF_STATUS_E_FAILURE; 3574 return status; 3575 } 3576 tx_param = (wmi_tx_send_params *)bufp; 3577 WMITLV_SET_HDR(&tx_param->tlv_header, 3578 WMITLV_TAG_STRUC_wmi_tx_send_params, 3579 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3580 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3581 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3582 param.mcs_mask); 3583 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3584 param.nss_mask); 3585 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3586 param.retry_limit); 3587 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3588 param.chain_mask); 3589 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3590 param.bw_mask); 3591 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3592 param.preamble_type); 3593 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3594 param.frame_type); 3595 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3596 param.cfr_enable); 3597 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 3598 param.en_beamforming); 3599 3600 return status; 3601 } 3602 3603 #ifdef CONFIG_HL_SUPPORT 3604 /** 3605 * send_mgmt_cmd_tlv() - WMI scan start function 3606 * @wmi_handle : handle to WMI. 3607 * @param : pointer to hold mgmt cmd parameter 3608 * 3609 * Return: 0 on success and -ve on failure. 3610 */ 3611 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3612 struct wmi_mgmt_params *param) 3613 { 3614 wmi_buf_t buf; 3615 uint8_t *bufp; 3616 int32_t cmd_len; 3617 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3618 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3619 mgmt_tx_dl_frm_len; 3620 3621 if (param->frm_len > mgmt_tx_dl_frm_len) { 3622 wmi_err("mgmt frame len %u exceeds %u", 3623 param->frm_len, mgmt_tx_dl_frm_len); 3624 return QDF_STATUS_E_INVAL; 3625 } 3626 3627 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3628 WMI_TLV_HDR_SIZE + 3629 roundup(bufp_len, sizeof(uint32_t)); 3630 3631 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3632 if (!buf) 3633 return QDF_STATUS_E_NOMEM; 3634 3635 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3636 bufp = (uint8_t *) cmd; 3637 WMITLV_SET_HDR(&cmd->tlv_header, 3638 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3639 WMITLV_GET_STRUCT_TLVLEN 3640 (wmi_mgmt_tx_send_cmd_fixed_param)); 3641 3642 cmd->vdev_id = param->vdev_id; 3643 3644 cmd->desc_id = param->desc_id; 3645 cmd->chanfreq = param->chanfreq; 3646 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3647 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3648 sizeof(uint32_t))); 3649 bufp += WMI_TLV_HDR_SIZE; 3650 qdf_mem_copy(bufp, param->pdata, bufp_len); 3651 3652 cmd->frame_len = param->frm_len; 3653 cmd->buf_len = bufp_len; 3654 cmd->tx_params_valid = param->tx_params_valid; 3655 cmd->tx_flags = param->tx_flags; 3656 cmd->peer_rssi = param->peer_rssi; 3657 3658 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3659 bufp, cmd->vdev_id, cmd->chanfreq); 3660 3661 bufp += roundup(bufp_len, sizeof(uint32_t)); 3662 if (param->tx_params_valid) { 3663 if (populate_tx_send_params(bufp, param->tx_param) != 3664 QDF_STATUS_SUCCESS) { 3665 wmi_err("Populate TX send params failed"); 3666 goto free_buf; 3667 } 3668 cmd_len += sizeof(wmi_tx_send_params); 3669 } 3670 3671 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3672 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3673 WMI_MGMT_TX_SEND_CMDID)) { 3674 wmi_err("Failed to send mgmt Tx"); 3675 goto free_buf; 3676 } 3677 return QDF_STATUS_SUCCESS; 3678 3679 free_buf: 3680 wmi_buf_free(buf); 3681 return QDF_STATUS_E_FAILURE; 3682 } 3683 #else 3684 /** 3685 * send_mgmt_cmd_tlv() - WMI scan start function 3686 * @wmi_handle : handle to WMI. 3687 * @param : pointer to hold mgmt cmd parameter 3688 * 3689 * Return: 0 on success and -ve on failure. 3690 */ 3691 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3692 struct wmi_mgmt_params *param) 3693 { 3694 wmi_buf_t buf; 3695 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3696 int32_t cmd_len; 3697 uint64_t dma_addr; 3698 void *qdf_ctx = param->qdf_ctx; 3699 uint8_t *bufp; 3700 QDF_STATUS status = QDF_STATUS_SUCCESS; 3701 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3702 mgmt_tx_dl_frm_len; 3703 3704 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3705 WMI_TLV_HDR_SIZE + 3706 roundup(bufp_len, sizeof(uint32_t)); 3707 3708 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3709 if (!buf) 3710 return QDF_STATUS_E_NOMEM; 3711 3712 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3713 bufp = (uint8_t *) cmd; 3714 WMITLV_SET_HDR(&cmd->tlv_header, 3715 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3716 WMITLV_GET_STRUCT_TLVLEN 3717 (wmi_mgmt_tx_send_cmd_fixed_param)); 3718 3719 cmd->vdev_id = param->vdev_id; 3720 3721 cmd->desc_id = param->desc_id; 3722 cmd->chanfreq = param->chanfreq; 3723 cmd->peer_rssi = param->peer_rssi; 3724 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3725 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3726 sizeof(uint32_t))); 3727 bufp += WMI_TLV_HDR_SIZE; 3728 3729 /* for big endian host, copy engine byte_swap is enabled 3730 * But the frame content is in network byte order 3731 * Need to byte swap the frame content - so when copy engine 3732 * does byte_swap - target gets frame content in the correct order 3733 */ 3734 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 3735 3736 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3737 QDF_DMA_TO_DEVICE); 3738 if (status != QDF_STATUS_SUCCESS) { 3739 wmi_err("wmi buf map failed"); 3740 goto free_buf; 3741 } 3742 3743 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3744 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3745 #if defined(HTT_PADDR64) 3746 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3747 #endif 3748 cmd->frame_len = param->frm_len; 3749 cmd->buf_len = bufp_len; 3750 cmd->tx_params_valid = param->tx_params_valid; 3751 cmd->tx_flags = param->tx_flags; 3752 3753 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3754 bufp, cmd->vdev_id, cmd->chanfreq); 3755 3756 bufp += roundup(bufp_len, sizeof(uint32_t)); 3757 if (param->tx_params_valid) { 3758 status = populate_tx_send_params(bufp, param->tx_param); 3759 if (status != QDF_STATUS_SUCCESS) { 3760 wmi_err("Populate TX send params failed"); 3761 goto unmap_tx_frame; 3762 } 3763 cmd_len += sizeof(wmi_tx_send_params); 3764 } 3765 3766 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3767 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3768 WMI_MGMT_TX_SEND_CMDID)) { 3769 wmi_err("Failed to send mgmt Tx"); 3770 goto unmap_tx_frame; 3771 } 3772 return QDF_STATUS_SUCCESS; 3773 3774 unmap_tx_frame: 3775 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3776 QDF_DMA_TO_DEVICE); 3777 free_buf: 3778 wmi_buf_free(buf); 3779 return QDF_STATUS_E_FAILURE; 3780 } 3781 #endif /* CONFIG_HL_SUPPORT */ 3782 3783 /** 3784 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3785 * @wmi_handle : handle to WMI. 3786 * @param : pointer to offchan data tx cmd parameter 3787 * 3788 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3789 */ 3790 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3791 struct wmi_offchan_data_tx_params *param) 3792 { 3793 wmi_buf_t buf; 3794 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3795 int32_t cmd_len; 3796 uint64_t dma_addr; 3797 void *qdf_ctx = param->qdf_ctx; 3798 uint8_t *bufp; 3799 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3800 param->frm_len : mgmt_tx_dl_frm_len; 3801 QDF_STATUS status = QDF_STATUS_SUCCESS; 3802 3803 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3804 WMI_TLV_HDR_SIZE + 3805 roundup(bufp_len, sizeof(uint32_t)); 3806 3807 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3808 if (!buf) 3809 return QDF_STATUS_E_NOMEM; 3810 3811 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3812 bufp = (uint8_t *) cmd; 3813 WMITLV_SET_HDR(&cmd->tlv_header, 3814 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3815 WMITLV_GET_STRUCT_TLVLEN 3816 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3817 3818 cmd->vdev_id = param->vdev_id; 3819 3820 cmd->desc_id = param->desc_id; 3821 cmd->chanfreq = param->chanfreq; 3822 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3823 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3824 sizeof(uint32_t))); 3825 bufp += WMI_TLV_HDR_SIZE; 3826 qdf_mem_copy(bufp, param->pdata, bufp_len); 3827 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3828 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3829 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3830 #if defined(HTT_PADDR64) 3831 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3832 #endif 3833 cmd->frame_len = param->frm_len; 3834 cmd->buf_len = bufp_len; 3835 cmd->tx_params_valid = param->tx_params_valid; 3836 3837 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3838 bufp, cmd->vdev_id, cmd->chanfreq); 3839 3840 bufp += roundup(bufp_len, sizeof(uint32_t)); 3841 if (param->tx_params_valid) { 3842 status = populate_tx_send_params(bufp, param->tx_param); 3843 if (status != QDF_STATUS_SUCCESS) { 3844 wmi_err("Populate TX send params failed"); 3845 goto err1; 3846 } 3847 cmd_len += sizeof(wmi_tx_send_params); 3848 } 3849 3850 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3851 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3852 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3853 wmi_err("Failed to offchan data Tx"); 3854 goto err1; 3855 } 3856 3857 return QDF_STATUS_SUCCESS; 3858 3859 err1: 3860 wmi_buf_free(buf); 3861 return QDF_STATUS_E_FAILURE; 3862 } 3863 3864 /** 3865 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3866 * @wmi_handle: wmi handle 3867 * @param_value: parameter value 3868 * 3869 * Return: QDF_STATUS_SUCCESS for success or error code 3870 */ 3871 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3872 uint32_t param_value) 3873 { 3874 QDF_STATUS ret; 3875 wmi_modem_power_state_cmd_param *cmd; 3876 wmi_buf_t buf; 3877 uint16_t len = sizeof(*cmd); 3878 3879 buf = wmi_buf_alloc(wmi_handle, len); 3880 if (!buf) 3881 return QDF_STATUS_E_NOMEM; 3882 3883 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3884 WMITLV_SET_HDR(&cmd->tlv_header, 3885 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3886 WMITLV_GET_STRUCT_TLVLEN 3887 (wmi_modem_power_state_cmd_param)); 3888 cmd->modem_power_state = param_value; 3889 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 3890 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3891 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3892 WMI_MODEM_POWER_STATE_CMDID); 3893 if (QDF_IS_STATUS_ERROR(ret)) { 3894 wmi_err("Failed to send notify cmd ret = %d", ret); 3895 wmi_buf_free(buf); 3896 } 3897 3898 return ret; 3899 } 3900 3901 /** 3902 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3903 * @wmi_handle: wmi handle 3904 * @vdev_id: vdev id 3905 * @val: value 3906 * 3907 * Return: QDF_STATUS_SUCCESS for success or error code. 3908 */ 3909 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3910 uint32_t vdev_id, uint8_t val) 3911 { 3912 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3913 wmi_buf_t buf; 3914 int32_t len = sizeof(*cmd); 3915 3916 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3917 3918 buf = wmi_buf_alloc(wmi_handle, len); 3919 if (!buf) 3920 return QDF_STATUS_E_NOMEM; 3921 3922 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3923 WMITLV_SET_HDR(&cmd->tlv_header, 3924 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3925 WMITLV_GET_STRUCT_TLVLEN 3926 (wmi_sta_powersave_mode_cmd_fixed_param)); 3927 cmd->vdev_id = vdev_id; 3928 if (val) 3929 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3930 else 3931 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3932 3933 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 3934 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3935 WMI_STA_POWERSAVE_MODE_CMDID)) { 3936 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 3937 vdev_id, val); 3938 wmi_buf_free(buf); 3939 return QDF_STATUS_E_FAILURE; 3940 } 3941 return QDF_STATUS_SUCCESS; 3942 } 3943 3944 /** 3945 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 3946 * @wmi_handle: wmi handle 3947 * @vdev_id: vdev id 3948 * 3949 * Return: QDF_STATUS_SUCCESS for success or error code. 3950 */ 3951 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 3952 uint8_t val) 3953 { 3954 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 3955 wmi_buf_t buf; 3956 size_t len = sizeof(*cmd); 3957 3958 buf = wmi_buf_alloc(wmi_handle, len); 3959 if (!buf) 3960 return QDF_STATUS_E_NOMEM; 3961 3962 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 3963 WMITLV_SET_HDR(&cmd->tlv_header, 3964 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 3965 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 3966 3967 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 3968 WMI_IDLE_TRIGGER_MONITOR_OFF); 3969 3970 wmi_debug("val: %d", cmd->idle_trigger_monitor); 3971 3972 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3973 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 3974 wmi_buf_free(buf); 3975 return QDF_STATUS_E_FAILURE; 3976 } 3977 return QDF_STATUS_SUCCESS; 3978 } 3979 3980 /** 3981 * send_set_mimops_cmd_tlv() - set MIMO powersave 3982 * @wmi_handle: wmi handle 3983 * @vdev_id: vdev id 3984 * @value: value 3985 * 3986 * Return: QDF_STATUS_SUCCESS for success or error code. 3987 */ 3988 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3989 uint8_t vdev_id, int value) 3990 { 3991 QDF_STATUS ret; 3992 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3993 wmi_buf_t buf; 3994 uint16_t len = sizeof(*cmd); 3995 3996 buf = wmi_buf_alloc(wmi_handle, len); 3997 if (!buf) 3998 return QDF_STATUS_E_NOMEM; 3999 4000 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 4001 WMITLV_SET_HDR(&cmd->tlv_header, 4002 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 4003 WMITLV_GET_STRUCT_TLVLEN 4004 (wmi_sta_smps_force_mode_cmd_fixed_param)); 4005 4006 cmd->vdev_id = vdev_id; 4007 4008 /* WMI_SMPS_FORCED_MODE values do not directly map 4009 * to SM power save values defined in the specification. 4010 * Make sure to send the right mapping. 4011 */ 4012 switch (value) { 4013 case 0: 4014 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 4015 break; 4016 case 1: 4017 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 4018 break; 4019 case 2: 4020 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 4021 break; 4022 case 3: 4023 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 4024 break; 4025 default: 4026 wmi_err("INVALID MIMO PS CONFIG: %d", value); 4027 wmi_buf_free(buf); 4028 return QDF_STATUS_E_FAILURE; 4029 } 4030 4031 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 4032 4033 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 4034 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4035 WMI_STA_SMPS_FORCE_MODE_CMDID); 4036 if (QDF_IS_STATUS_ERROR(ret)) { 4037 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4038 wmi_buf_free(buf); 4039 } 4040 4041 return ret; 4042 } 4043 4044 /** 4045 * send_set_smps_params_cmd_tlv() - set smps params 4046 * @wmi_handle: wmi handle 4047 * @vdev_id: vdev id 4048 * @value: value 4049 * 4050 * Return: QDF_STATUS_SUCCESS for success or error code. 4051 */ 4052 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 4053 int value) 4054 { 4055 QDF_STATUS ret; 4056 wmi_sta_smps_param_cmd_fixed_param *cmd; 4057 wmi_buf_t buf; 4058 uint16_t len = sizeof(*cmd); 4059 4060 buf = wmi_buf_alloc(wmi_handle, len); 4061 if (!buf) 4062 return QDF_STATUS_E_NOMEM; 4063 4064 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 4065 WMITLV_SET_HDR(&cmd->tlv_header, 4066 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 4067 WMITLV_GET_STRUCT_TLVLEN 4068 (wmi_sta_smps_param_cmd_fixed_param)); 4069 4070 cmd->vdev_id = vdev_id; 4071 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 4072 cmd->param = 4073 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 4074 4075 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 4076 cmd->param); 4077 4078 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 4079 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4080 WMI_STA_SMPS_PARAM_CMDID); 4081 if (QDF_IS_STATUS_ERROR(ret)) { 4082 wmi_err("Failed to send set Mimo PS ret = %d", ret); 4083 wmi_buf_free(buf); 4084 } 4085 4086 return ret; 4087 } 4088 4089 /** 4090 * send_get_temperature_cmd_tlv() - get pdev temperature req 4091 * @wmi_handle: wmi handle 4092 * 4093 * Return: QDF_STATUS_SUCCESS for success or error code. 4094 */ 4095 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 4096 { 4097 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 4098 wmi_buf_t wmi_buf; 4099 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 4100 uint8_t *buf_ptr; 4101 4102 if (!wmi_handle) { 4103 wmi_err("WMI is closed, can not issue cmd"); 4104 return QDF_STATUS_E_INVAL; 4105 } 4106 4107 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4108 if (!wmi_buf) 4109 return QDF_STATUS_E_NOMEM; 4110 4111 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4112 4113 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 4114 WMITLV_SET_HDR(&cmd->tlv_header, 4115 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 4116 WMITLV_GET_STRUCT_TLVLEN 4117 (wmi_pdev_get_temperature_cmd_fixed_param)); 4118 4119 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 4120 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4121 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 4122 wmi_err("Failed to send get temperature command"); 4123 wmi_buf_free(wmi_buf); 4124 return QDF_STATUS_E_FAILURE; 4125 } 4126 4127 return QDF_STATUS_SUCCESS; 4128 } 4129 4130 /** 4131 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 4132 * @wmi_handle: wmi handle 4133 * @vdevid: vdev id 4134 * @peer_addr: peer mac address 4135 * @auto_triggerparam: auto trigger parameters 4136 * @num_ac: number of access category 4137 * 4138 * This function sets the trigger 4139 * uapsd params such as service interval, delay interval 4140 * and suspend interval which will be used by the firmware 4141 * to send trigger frames periodically when there is no 4142 * traffic on the transmit side. 4143 * 4144 * Return: QDF_STATUS_SUCCESS for success or error code. 4145 */ 4146 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 4147 struct sta_uapsd_trig_params *param) 4148 { 4149 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 4150 QDF_STATUS ret; 4151 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 4152 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 4153 uint32_t i; 4154 wmi_buf_t buf; 4155 uint8_t *buf_ptr; 4156 struct sta_uapsd_params *uapsd_param; 4157 wmi_sta_uapsd_auto_trig_param *trig_param; 4158 4159 buf = wmi_buf_alloc(wmi_handle, cmd_len); 4160 if (!buf) 4161 return QDF_STATUS_E_NOMEM; 4162 4163 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4164 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 4165 WMITLV_SET_HDR(&cmd->tlv_header, 4166 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 4167 WMITLV_GET_STRUCT_TLVLEN 4168 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 4169 cmd->vdev_id = param->vdevid; 4170 cmd->num_ac = param->num_ac; 4171 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 4172 4173 /* TLV indicating array of structures to follow */ 4174 buf_ptr += sizeof(*cmd); 4175 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 4176 4177 buf_ptr += WMI_TLV_HDR_SIZE; 4178 4179 /* 4180 * Update tag and length for uapsd auto trigger params (this will take 4181 * care of updating tag and length if it is not pre-filled by caller). 4182 */ 4183 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 4184 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 4185 for (i = 0; i < param->num_ac; i++) { 4186 WMITLV_SET_HDR((buf_ptr + 4187 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 4188 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 4189 WMITLV_GET_STRUCT_TLVLEN 4190 (wmi_sta_uapsd_auto_trig_param)); 4191 trig_param->wmm_ac = uapsd_param->wmm_ac; 4192 trig_param->user_priority = uapsd_param->user_priority; 4193 trig_param->service_interval = uapsd_param->service_interval; 4194 trig_param->suspend_interval = uapsd_param->suspend_interval; 4195 trig_param->delay_interval = uapsd_param->delay_interval; 4196 trig_param++; 4197 uapsd_param++; 4198 } 4199 4200 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4201 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4202 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4203 if (QDF_IS_STATUS_ERROR(ret)) { 4204 wmi_err("Failed to send set uapsd param ret = %d", ret); 4205 wmi_buf_free(buf); 4206 } 4207 4208 return ret; 4209 } 4210 4211 /** 4212 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4213 * @wmi_handle: Pointer to wmi handle 4214 * @thermal_info: Thermal command information 4215 * 4216 * This function sends the thermal management command 4217 * to the firmware 4218 * 4219 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4220 */ 4221 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4222 struct thermal_cmd_params *thermal_info) 4223 { 4224 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4225 wmi_buf_t buf = NULL; 4226 QDF_STATUS status; 4227 uint32_t len = 0; 4228 uint8_t action; 4229 4230 switch (thermal_info->thermal_action) { 4231 case THERMAL_MGMT_ACTION_DEFAULT: 4232 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 4233 break; 4234 4235 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 4236 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 4237 break; 4238 4239 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 4240 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 4241 break; 4242 4243 case THERMAL_MGMT_ACTION_CHAINSCALING: 4244 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 4245 break; 4246 4247 default: 4248 wmi_err("Invalid thermal_action code %d", 4249 thermal_info->thermal_action); 4250 return QDF_STATUS_E_FAILURE; 4251 } 4252 4253 len = sizeof(*cmd); 4254 4255 buf = wmi_buf_alloc(wmi_handle, len); 4256 if (!buf) 4257 return QDF_STATUS_E_FAILURE; 4258 4259 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4260 4261 WMITLV_SET_HDR(&cmd->tlv_header, 4262 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4263 WMITLV_GET_STRUCT_TLVLEN 4264 (wmi_thermal_mgmt_cmd_fixed_param)); 4265 4266 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4267 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4268 cmd->enable = thermal_info->thermal_enable; 4269 cmd->action = action; 4270 4271 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 4272 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 4273 cmd->enable, cmd->action); 4274 4275 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4276 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4277 WMI_THERMAL_MGMT_CMDID); 4278 if (QDF_IS_STATUS_ERROR(status)) { 4279 wmi_buf_free(buf); 4280 wmi_err("Failed to send thermal mgmt command"); 4281 } 4282 4283 return status; 4284 } 4285 4286 /** 4287 * send_lro_config_cmd_tlv() - process the LRO config command 4288 * @wmi_handle: Pointer to WMI handle 4289 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4290 * 4291 * This function sends down the LRO configuration parameters to 4292 * the firmware to enable LRO, sets the TCP flags and sets the 4293 * seed values for the toeplitz hash generation 4294 * 4295 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4296 */ 4297 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4298 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4299 { 4300 wmi_lro_info_cmd_fixed_param *cmd; 4301 wmi_buf_t buf; 4302 QDF_STATUS status; 4303 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4304 4305 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4306 if (!buf) 4307 return QDF_STATUS_E_FAILURE; 4308 4309 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4310 4311 WMITLV_SET_HDR(&cmd->tlv_header, 4312 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4313 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4314 4315 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4316 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4317 wmi_lro_cmd->tcp_flag); 4318 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4319 wmi_lro_cmd->tcp_flag_mask); 4320 cmd->toeplitz_hash_ipv4_0_3 = 4321 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4322 cmd->toeplitz_hash_ipv4_4_7 = 4323 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4324 cmd->toeplitz_hash_ipv4_8_11 = 4325 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4326 cmd->toeplitz_hash_ipv4_12_15 = 4327 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4328 cmd->toeplitz_hash_ipv4_16 = 4329 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4330 4331 cmd->toeplitz_hash_ipv6_0_3 = 4332 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4333 cmd->toeplitz_hash_ipv6_4_7 = 4334 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4335 cmd->toeplitz_hash_ipv6_8_11 = 4336 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4337 cmd->toeplitz_hash_ipv6_12_15 = 4338 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4339 cmd->toeplitz_hash_ipv6_16_19 = 4340 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4341 cmd->toeplitz_hash_ipv6_20_23 = 4342 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4343 cmd->toeplitz_hash_ipv6_24_27 = 4344 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4345 cmd->toeplitz_hash_ipv6_28_31 = 4346 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4347 cmd->toeplitz_hash_ipv6_32_35 = 4348 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4349 cmd->toeplitz_hash_ipv6_36_39 = 4350 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4351 cmd->toeplitz_hash_ipv6_40 = 4352 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4353 4354 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4355 wmi_handle, 4356 pdev_id); 4357 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4358 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4359 4360 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4361 status = wmi_unified_cmd_send(wmi_handle, buf, 4362 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4363 if (QDF_IS_STATUS_ERROR(status)) { 4364 wmi_buf_free(buf); 4365 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 4366 } 4367 4368 return status; 4369 } 4370 4371 /** 4372 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4373 * @wmi_handle: Pointer to wmi handle 4374 * @rate_report_params: Pointer to peer rate report parameters 4375 * 4376 * 4377 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4378 */ 4379 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4380 struct wmi_peer_rate_report_params *rate_report_params) 4381 { 4382 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4383 wmi_buf_t buf = NULL; 4384 QDF_STATUS status = 0; 4385 uint32_t len = 0; 4386 uint32_t i, j; 4387 4388 len = sizeof(*cmd); 4389 4390 buf = wmi_buf_alloc(wmi_handle, len); 4391 if (!buf) 4392 return QDF_STATUS_E_FAILURE; 4393 4394 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4395 wmi_buf_data(buf); 4396 4397 WMITLV_SET_HDR( 4398 &cmd->tlv_header, 4399 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4400 WMITLV_GET_STRUCT_TLVLEN( 4401 wmi_peer_set_rate_report_condition_fixed_param)); 4402 4403 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4404 cmd->report_backoff_time = rate_report_params->backoff_time; 4405 cmd->report_timer_period = rate_report_params->timer_period; 4406 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4407 cmd->cond_per_phy[i].val_cond_flags = 4408 rate_report_params->report_per_phy[i].cond_flags; 4409 cmd->cond_per_phy[i].rate_delta.min_delta = 4410 rate_report_params->report_per_phy[i].delta.delta_min; 4411 cmd->cond_per_phy[i].rate_delta.percentage = 4412 rate_report_params->report_per_phy[i].delta.percent; 4413 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4414 cmd->cond_per_phy[i].rate_threshold[j] = 4415 rate_report_params->report_per_phy[i]. 4416 report_rate_threshold[j]; 4417 } 4418 } 4419 4420 wmi_debug("enable %d backoff_time %d period %d", 4421 cmd->enable_rate_report, 4422 cmd->report_backoff_time, cmd->report_timer_period); 4423 4424 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4425 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4426 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4427 if (QDF_IS_STATUS_ERROR(status)) { 4428 wmi_buf_free(buf); 4429 wmi_err("Failed to send peer_set_report_cond command"); 4430 } 4431 return status; 4432 } 4433 4434 /** 4435 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4436 * @wmi_handle: wmi handle 4437 * @vdev_id: vdev id. 4438 * @wmm_vparams: edca parameters 4439 * 4440 * This function updates EDCA parameters to the target 4441 * 4442 * Return: CDF Status 4443 */ 4444 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4445 uint8_t vdev_id, bool mu_edca_param, 4446 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4447 { 4448 uint8_t *buf_ptr; 4449 wmi_buf_t buf; 4450 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4451 wmi_wmm_vparams *wmm_param; 4452 struct wmi_host_wme_vparams *twmm_param; 4453 int len = sizeof(*cmd); 4454 int ac; 4455 4456 buf = wmi_buf_alloc(wmi_handle, len); 4457 4458 if (!buf) 4459 return QDF_STATUS_E_NOMEM; 4460 4461 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4462 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4463 WMITLV_SET_HDR(&cmd->tlv_header, 4464 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4465 WMITLV_GET_STRUCT_TLVLEN 4466 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4467 cmd->vdev_id = vdev_id; 4468 cmd->wmm_param_type = mu_edca_param; 4469 4470 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4471 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4472 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4473 WMITLV_SET_HDR(&wmm_param->tlv_header, 4474 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4475 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4476 wmm_param->cwmin = twmm_param->cwmin; 4477 wmm_param->cwmax = twmm_param->cwmax; 4478 wmm_param->aifs = twmm_param->aifs; 4479 if (mu_edca_param) 4480 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4481 else 4482 wmm_param->txoplimit = twmm_param->txoplimit; 4483 wmm_param->acm = twmm_param->acm; 4484 wmm_param->no_ack = twmm_param->noackpolicy; 4485 } 4486 4487 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4488 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4489 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4490 goto fail; 4491 4492 return QDF_STATUS_SUCCESS; 4493 4494 fail: 4495 wmi_buf_free(buf); 4496 wmi_err("Failed to set WMM Parameters"); 4497 return QDF_STATUS_E_FAILURE; 4498 } 4499 4500 /** 4501 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4502 * @wmi_handle: wmi handle 4503 * @vdev_id: vdev id 4504 * @probe_rsp_info: probe response info 4505 * 4506 * Return: QDF_STATUS_SUCCESS for success or error code 4507 */ 4508 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4509 uint8_t vdev_id, 4510 struct wmi_probe_resp_params *probe_rsp_info) 4511 { 4512 wmi_prb_tmpl_cmd_fixed_param *cmd; 4513 wmi_bcn_prb_info *bcn_prb_info; 4514 wmi_buf_t wmi_buf; 4515 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4516 uint8_t *buf_ptr; 4517 QDF_STATUS ret; 4518 4519 wmi_debug("Send probe response template for vdev %d", vdev_id); 4520 4521 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4522 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4523 4524 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4525 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4526 tmpl_len_aligned; 4527 4528 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4529 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 4530 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4531 return QDF_STATUS_E_INVAL; 4532 } 4533 4534 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4535 if (!wmi_buf) 4536 return QDF_STATUS_E_NOMEM; 4537 4538 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4539 4540 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4541 WMITLV_SET_HDR(&cmd->tlv_header, 4542 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4543 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4544 cmd->vdev_id = vdev_id; 4545 cmd->buf_len = tmpl_len; 4546 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4547 4548 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4549 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4550 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4551 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4552 bcn_prb_info->caps = 0; 4553 bcn_prb_info->erp = 0; 4554 buf_ptr += sizeof(wmi_bcn_prb_info); 4555 4556 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4557 buf_ptr += WMI_TLV_HDR_SIZE; 4558 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4559 4560 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4561 ret = wmi_unified_cmd_send(wmi_handle, 4562 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4563 if (QDF_IS_STATUS_ERROR(ret)) { 4564 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 4565 wmi_buf_free(wmi_buf); 4566 } 4567 4568 return ret; 4569 } 4570 4571 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4572 #define WPI_IV_LEN 16 4573 4574 /** 4575 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4576 * 4577 * @dest_tx: destination address of tsc key counter 4578 * @src_tx: source address of tsc key counter 4579 * @dest_rx: destination address of rsc key counter 4580 * @src_rx: source address of rsc key counter 4581 * 4582 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4583 * 4584 * Return: None 4585 * 4586 */ 4587 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4588 uint8_t *dest_rx, uint8_t *src_rx) 4589 { 4590 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4591 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4592 } 4593 #else 4594 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4595 uint8_t *dest_rx, uint8_t *src_rx) 4596 { 4597 return; 4598 } 4599 #endif 4600 4601 /** 4602 * send_setup_install_key_cmd_tlv() - set key parameters 4603 * @wmi_handle: wmi handle 4604 * @key_params: key parameters 4605 * 4606 * This function fills structure from information 4607 * passed in key_params. 4608 * 4609 * Return: QDF_STATUS_SUCCESS - success 4610 * QDF_STATUS_E_FAILURE - failure 4611 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4612 */ 4613 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4614 struct set_key_params *key_params) 4615 { 4616 wmi_vdev_install_key_cmd_fixed_param *cmd; 4617 wmi_buf_t buf; 4618 uint8_t *buf_ptr; 4619 uint32_t len; 4620 uint8_t *key_data; 4621 QDF_STATUS status; 4622 4623 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4624 WMI_TLV_HDR_SIZE; 4625 4626 buf = wmi_buf_alloc(wmi_handle, len); 4627 if (!buf) 4628 return QDF_STATUS_E_NOMEM; 4629 4630 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4631 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4632 WMITLV_SET_HDR(&cmd->tlv_header, 4633 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4634 WMITLV_GET_STRUCT_TLVLEN 4635 (wmi_vdev_install_key_cmd_fixed_param)); 4636 cmd->vdev_id = key_params->vdev_id; 4637 cmd->key_ix = key_params->key_idx; 4638 if (key_params->group_key_idx) { 4639 cmd->is_group_key_ix_valid = 1; 4640 cmd->group_key_ix = key_params->group_key_idx; 4641 } 4642 4643 4644 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4645 cmd->key_flags |= key_params->key_flags; 4646 cmd->key_cipher = key_params->key_cipher; 4647 if ((key_params->key_txmic_len) && 4648 (key_params->key_rxmic_len)) { 4649 cmd->key_txmic_len = key_params->key_txmic_len; 4650 cmd->key_rxmic_len = key_params->key_rxmic_len; 4651 } 4652 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4653 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4654 key_params->tx_iv, 4655 cmd->wpi_key_rsc_counter, 4656 key_params->rx_iv); 4657 #endif 4658 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4659 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4660 roundup(key_params->key_len, sizeof(uint32_t))); 4661 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4662 4663 /* for big endian host, copy engine byte_swap is enabled 4664 * But key_data is in network byte order 4665 * Need to byte swap the key_data - so when copy engine 4666 * does byte_swap - target gets key_data in the correct order 4667 */ 4668 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 4669 (const void *)key_params->key_data, 4670 key_params->key_len); 4671 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4672 sizeof(wmi_key_seq_counter)); 4673 cmd->key_len = key_params->key_len; 4674 4675 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4676 sizeof(wmi_key_seq_counter)); 4677 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4678 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4679 WMI_VDEV_INSTALL_KEY_CMDID); 4680 if (QDF_IS_STATUS_ERROR(status)) { 4681 qdf_mem_zero(wmi_buf_data(buf), len); 4682 wmi_buf_free(buf); 4683 } 4684 return status; 4685 } 4686 4687 /** 4688 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 4689 * @wmi_handle: wmi handle 4690 * @vdev_id: vdev id 4691 * @p2p_ie: p2p IE 4692 * 4693 * Return: QDF_STATUS_SUCCESS for success or error code 4694 */ 4695 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 4696 uint32_t vdev_id, uint8_t *p2p_ie) 4697 { 4698 QDF_STATUS ret; 4699 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 4700 wmi_buf_t wmi_buf; 4701 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 4702 uint8_t *buf_ptr; 4703 4704 ie_len = (uint32_t) (p2p_ie[1] + 2); 4705 4706 /* More than one P2P IE may be included in a single frame. 4707 If multiple P2P IEs are present, the complete P2P attribute 4708 data consists of the concatenation of the P2P Attribute 4709 fields of the P2P IEs. The P2P Attributes field of each 4710 P2P IE may be any length up to the maximum (251 octets). 4711 In this case host sends one P2P IE to firmware so the length 4712 should not exceed more than 251 bytes 4713 */ 4714 if (ie_len > 251) { 4715 wmi_err("Invalid p2p ie length %u", ie_len); 4716 return QDF_STATUS_E_INVAL; 4717 } 4718 4719 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 4720 4721 wmi_buf_len = 4722 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 4723 WMI_TLV_HDR_SIZE; 4724 4725 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4726 if (!wmi_buf) 4727 return QDF_STATUS_E_NOMEM; 4728 4729 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4730 4731 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 4732 WMITLV_SET_HDR(&cmd->tlv_header, 4733 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 4734 WMITLV_GET_STRUCT_TLVLEN 4735 (wmi_p2p_go_set_beacon_ie_fixed_param)); 4736 cmd->vdev_id = vdev_id; 4737 cmd->ie_buf_len = ie_len; 4738 4739 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 4740 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 4741 buf_ptr += WMI_TLV_HDR_SIZE; 4742 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 4743 4744 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 4745 4746 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 4747 ret = wmi_unified_cmd_send(wmi_handle, 4748 wmi_buf, wmi_buf_len, 4749 WMI_P2P_GO_SET_BEACON_IE); 4750 if (QDF_IS_STATUS_ERROR(ret)) { 4751 wmi_err("Failed to send bcn tmpl: %d", ret); 4752 wmi_buf_free(wmi_buf); 4753 } 4754 4755 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 4756 return ret; 4757 } 4758 4759 /** 4760 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 4761 * @wmi_handle: wmi handle 4762 * @psetoui: OUI parameters 4763 * 4764 * set scan probe OUI parameters in firmware 4765 * 4766 * Return: CDF status 4767 */ 4768 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 4769 struct scan_mac_oui *psetoui) 4770 { 4771 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 4772 wmi_buf_t wmi_buf; 4773 uint32_t len; 4774 uint8_t *buf_ptr; 4775 uint32_t *oui_buf; 4776 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 4777 4778 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4779 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 4780 4781 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4782 if (!wmi_buf) 4783 return QDF_STATUS_E_NOMEM; 4784 4785 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4786 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 4787 WMITLV_SET_HDR(&cmd->tlv_header, 4788 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 4789 WMITLV_GET_STRUCT_TLVLEN 4790 (wmi_scan_prob_req_oui_cmd_fixed_param)); 4791 4792 oui_buf = &cmd->prob_req_oui; 4793 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 4794 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 4795 | psetoui->oui[2]; 4796 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 4797 4798 cmd->vdev_id = psetoui->vdev_id; 4799 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 4800 if (psetoui->enb_probe_req_sno_randomization) 4801 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 4802 4803 if (ie_whitelist->white_list) { 4804 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4805 &cmd->num_vendor_oui, 4806 ie_whitelist); 4807 cmd->flags |= 4808 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4809 } 4810 4811 buf_ptr += sizeof(*cmd); 4812 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4813 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4814 buf_ptr += WMI_TLV_HDR_SIZE; 4815 4816 if (cmd->num_vendor_oui != 0) { 4817 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4818 ie_whitelist->voui); 4819 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4820 } 4821 4822 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 4823 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4824 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 4825 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 4826 wmi_buf_free(wmi_buf); 4827 return QDF_STATUS_E_FAILURE; 4828 } 4829 return QDF_STATUS_SUCCESS; 4830 } 4831 4832 #ifdef IPA_OFFLOAD 4833 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 4834 * @wmi_handle: wmi handle 4835 * @ipa_offload: ipa offload control parameter 4836 * 4837 * Returns: 0 on success, error number otherwise 4838 */ 4839 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 4840 struct ipa_uc_offload_control_params *ipa_offload) 4841 { 4842 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 4843 wmi_buf_t wmi_buf; 4844 uint32_t len; 4845 u_int8_t *buf_ptr; 4846 4847 len = sizeof(*cmd); 4848 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4849 if (!wmi_buf) 4850 return QDF_STATUS_E_NOMEM; 4851 4852 wmi_debug("offload_type=%d, enable=%d", 4853 ipa_offload->offload_type, ipa_offload->enable); 4854 4855 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 4856 4857 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 4858 WMITLV_SET_HDR(&cmd->tlv_header, 4859 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 4860 WMITLV_GET_STRUCT_TLVLEN( 4861 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 4862 4863 cmd->offload_type = ipa_offload->offload_type; 4864 cmd->vdev_id = ipa_offload->vdev_id; 4865 cmd->enable = ipa_offload->enable; 4866 4867 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 4868 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4869 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 4870 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 4871 wmi_buf_free(wmi_buf); 4872 return QDF_STATUS_E_FAILURE; 4873 } 4874 4875 return QDF_STATUS_SUCCESS; 4876 } 4877 #endif 4878 4879 /** 4880 * send_pno_stop_cmd_tlv() - PNO stop request 4881 * @wmi_handle: wmi handle 4882 * @vdev_id: vdev id 4883 * 4884 * This function request FW to stop ongoing PNO operation. 4885 * 4886 * Return: CDF status 4887 */ 4888 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4889 { 4890 wmi_nlo_config_cmd_fixed_param *cmd; 4891 int32_t len = sizeof(*cmd); 4892 wmi_buf_t buf; 4893 uint8_t *buf_ptr; 4894 int ret; 4895 4896 /* 4897 * TLV place holder for array of structures nlo_configured_parameters 4898 * TLV place holder for array of uint32_t channel_list 4899 * TLV place holder for chnl prediction cfg 4900 */ 4901 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4902 buf = wmi_buf_alloc(wmi_handle, len); 4903 if (!buf) 4904 return QDF_STATUS_E_NOMEM; 4905 4906 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4907 buf_ptr = (uint8_t *) cmd; 4908 4909 WMITLV_SET_HDR(&cmd->tlv_header, 4910 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4911 WMITLV_GET_STRUCT_TLVLEN 4912 (wmi_nlo_config_cmd_fixed_param)); 4913 4914 cmd->vdev_id = vdev_id; 4915 cmd->flags = WMI_NLO_CONFIG_STOP; 4916 buf_ptr += sizeof(*cmd); 4917 4918 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4919 buf_ptr += WMI_TLV_HDR_SIZE; 4920 4921 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 4922 buf_ptr += WMI_TLV_HDR_SIZE; 4923 4924 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4925 buf_ptr += WMI_TLV_HDR_SIZE; 4926 4927 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4928 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4929 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4930 if (ret) { 4931 wmi_err("Failed to send nlo wmi cmd"); 4932 wmi_buf_free(buf); 4933 return QDF_STATUS_E_FAILURE; 4934 } 4935 4936 return QDF_STATUS_SUCCESS; 4937 } 4938 4939 /** 4940 * send_obss_disable_cmd_tlv() - disable obss scan request 4941 * @wmi_handle: wmi handle 4942 * @vdev_id: vdev id 4943 * 4944 * This function request FW to disable ongoing obss scan operation. 4945 * 4946 * Return: QDF status 4947 */ 4948 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 4949 uint8_t vdev_id) 4950 { 4951 QDF_STATUS status; 4952 wmi_buf_t buf; 4953 wmi_obss_scan_disable_cmd_fixed_param *cmd; 4954 int len = sizeof(*cmd); 4955 4956 buf = wmi_buf_alloc(wmi_handle, len); 4957 if (!buf) 4958 return QDF_STATUS_E_NOMEM; 4959 4960 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 4961 4962 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 4963 WMITLV_SET_HDR(&cmd->tlv_header, 4964 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 4965 WMITLV_GET_STRUCT_TLVLEN( 4966 wmi_obss_scan_disable_cmd_fixed_param)); 4967 4968 cmd->vdev_id = vdev_id; 4969 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4970 WMI_OBSS_SCAN_DISABLE_CMDID); 4971 if (QDF_IS_STATUS_ERROR(status)) 4972 wmi_buf_free(buf); 4973 4974 return status; 4975 } 4976 4977 /** 4978 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 4979 * @buf_ptr: Buffer passed by upper layers 4980 * @pno: Buffer to be sent to the firmware 4981 * 4982 * Copy the PNO Channel prediction configuration parameters 4983 * passed by the upper layers to a WMI format TLV and send it 4984 * down to the firmware. 4985 * 4986 * Return: None 4987 */ 4988 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 4989 struct pno_scan_req_params *pno) 4990 { 4991 nlo_channel_prediction_cfg *channel_prediction_cfg = 4992 (nlo_channel_prediction_cfg *) buf_ptr; 4993 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 4994 WMITLV_TAG_ARRAY_BYTE, 4995 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 4996 #ifdef FEATURE_WLAN_SCAN_PNO 4997 channel_prediction_cfg->enable = pno->pno_channel_prediction; 4998 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 4999 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 5000 channel_prediction_cfg->full_scan_period_ms = 5001 pno->channel_prediction_full_scan; 5002 #endif 5003 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5004 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 5005 channel_prediction_cfg->enable, 5006 channel_prediction_cfg->top_k_num, 5007 channel_prediction_cfg->stationary_threshold, 5008 channel_prediction_cfg->full_scan_period_ms); 5009 } 5010 5011 /** 5012 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 5013 * @wmi_handle: wmi handle 5014 * @buf_ptr: Buffer passed by upper layers 5015 * @buf_len: Length of passed buffer by upper layer 5016 * 5017 * Copy the buffer passed by the upper layers and send it 5018 * down to the firmware. 5019 * 5020 * Return: None 5021 */ 5022 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 5023 void *buf_ptr, uint32_t buf_len) 5024 { 5025 wmi_buf_t buf = NULL; 5026 QDF_STATUS status; 5027 int len; 5028 uint8_t *data_ptr; 5029 5030 len = buf_len; 5031 buf = wmi_buf_alloc(wmi_handle, len); 5032 if (!buf) 5033 return QDF_STATUS_E_NOMEM; 5034 5035 data_ptr = (uint8_t *)wmi_buf_data(buf); 5036 qdf_mem_copy(data_ptr, buf_ptr, len); 5037 5038 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 5039 status = wmi_unified_cmd_send(wmi_handle, buf, 5040 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 5041 5042 if (QDF_IS_STATUS_ERROR(status)) { 5043 wmi_buf_free(buf); 5044 return QDF_STATUS_E_FAILURE; 5045 } 5046 return QDF_STATUS_SUCCESS; 5047 } 5048 5049 /** 5050 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 5051 * @wmi_handle: wmi handle 5052 * @evt_buf: event buffer 5053 * @more_flag: buffer to populate more flag 5054 * 5055 * Return: status of operation 5056 */ 5057 static QDF_STATUS 5058 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi, void *evt_buf, 5059 uint32_t *more_flag) 5060 { 5061 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 5062 wmi_ctrl_path_stats_event_fixed_param *ev; 5063 5064 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 5065 if (!param_buf) { 5066 wmi_err_rl("param_buf is NULL"); 5067 return QDF_STATUS_E_FAILURE; 5068 } 5069 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 5070 5071 *more_flag = ev->more; 5072 return QDF_STATUS_SUCCESS; 5073 } 5074 5075 /** 5076 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 5077 * @wmi_handle: wmi handle 5078 * @params: configuration parameters 5079 * 5080 * Return: QDF_STATUS 5081 */ 5082 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 5083 struct nlo_mawc_params *params) 5084 { 5085 wmi_buf_t buf = NULL; 5086 QDF_STATUS status; 5087 int len; 5088 uint8_t *buf_ptr; 5089 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 5090 5091 len = sizeof(*wmi_nlo_mawc_params); 5092 buf = wmi_buf_alloc(wmi_handle, len); 5093 if (!buf) 5094 return QDF_STATUS_E_NOMEM; 5095 5096 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5097 wmi_nlo_mawc_params = 5098 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 5099 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 5100 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 5101 WMITLV_GET_STRUCT_TLVLEN 5102 (wmi_nlo_configure_mawc_cmd_fixed_param)); 5103 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 5104 if (params->enable) 5105 wmi_nlo_mawc_params->enable = 1; 5106 else 5107 wmi_nlo_mawc_params->enable = 0; 5108 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 5109 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 5110 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 5111 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 5112 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 5113 wmi_nlo_mawc_params->exp_backoff_ratio, 5114 wmi_nlo_mawc_params->init_scan_interval, 5115 wmi_nlo_mawc_params->max_scan_interval); 5116 5117 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 5118 status = wmi_unified_cmd_send(wmi_handle, buf, 5119 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 5120 if (QDF_IS_STATUS_ERROR(status)) { 5121 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 5122 status); 5123 wmi_buf_free(buf); 5124 return QDF_STATUS_E_FAILURE; 5125 } 5126 5127 return QDF_STATUS_SUCCESS; 5128 } 5129 5130 /** 5131 * send_pno_start_cmd_tlv() - PNO start request 5132 * @wmi_handle: wmi handle 5133 * @pno: PNO request 5134 * 5135 * This function request FW to start PNO request. 5136 * Request: CDF status 5137 */ 5138 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 5139 struct pno_scan_req_params *pno) 5140 { 5141 wmi_nlo_config_cmd_fixed_param *cmd; 5142 nlo_configured_parameters *nlo_list; 5143 uint32_t *channel_list; 5144 int32_t len; 5145 wmi_buf_t buf; 5146 uint8_t *buf_ptr; 5147 uint8_t i; 5148 int ret; 5149 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 5150 connected_nlo_rssi_params *nlo_relative_rssi; 5151 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 5152 5153 /* 5154 * TLV place holder for array nlo_configured_parameters(nlo_list) 5155 * TLV place holder for array of uint32_t channel_list 5156 * TLV place holder for chnnl prediction cfg 5157 * TLV place holder for array of wmi_vendor_oui 5158 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 5159 */ 5160 len = sizeof(*cmd) + 5161 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 5162 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 5163 5164 len += sizeof(uint32_t) * pno->networks_list[0].channel_cnt; 5165 len += sizeof(nlo_configured_parameters) * 5166 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5167 len += sizeof(nlo_channel_prediction_cfg); 5168 len += sizeof(enlo_candidate_score_params); 5169 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 5170 len += sizeof(connected_nlo_rssi_params); 5171 len += sizeof(connected_nlo_bss_band_rssi_pref); 5172 5173 buf = wmi_buf_alloc(wmi_handle, len); 5174 if (!buf) 5175 return QDF_STATUS_E_NOMEM; 5176 5177 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 5178 5179 buf_ptr = (uint8_t *) cmd; 5180 WMITLV_SET_HDR(&cmd->tlv_header, 5181 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 5182 WMITLV_GET_STRUCT_TLVLEN 5183 (wmi_nlo_config_cmd_fixed_param)); 5184 cmd->vdev_id = pno->vdev_id; 5185 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 5186 5187 #ifdef FEATURE_WLAN_SCAN_PNO 5188 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 5189 pno->adaptive_dwell_mode); 5190 #endif 5191 /* Current FW does not support min-max range for dwell time */ 5192 cmd->active_dwell_time = pno->active_dwell_time; 5193 cmd->passive_dwell_time = pno->passive_dwell_time; 5194 5195 if (pno->do_passive_scan) 5196 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 5197 /* Copy scan interval */ 5198 cmd->fast_scan_period = pno->fast_scan_period; 5199 cmd->slow_scan_period = pno->slow_scan_period; 5200 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 5201 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 5202 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 5203 5204 /* mac randomization attributes */ 5205 if (pno->scan_random.randomize) { 5206 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 5207 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 5208 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 5209 pno->scan_random.mac_mask, 5210 &cmd->mac_addr, 5211 &cmd->mac_mask); 5212 } 5213 5214 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 5215 5216 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 5217 5218 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5219 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 5220 buf_ptr += WMI_TLV_HDR_SIZE; 5221 5222 nlo_list = (nlo_configured_parameters *) buf_ptr; 5223 for (i = 0; i < cmd->no_of_ssids; i++) { 5224 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 5225 WMITLV_TAG_ARRAY_BYTE, 5226 WMITLV_GET_STRUCT_TLVLEN 5227 (nlo_configured_parameters)); 5228 /* Copy ssid and it's length */ 5229 nlo_list[i].ssid.valid = true; 5230 nlo_list[i].ssid.ssid.ssid_len = 5231 pno->networks_list[i].ssid.length; 5232 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 5233 pno->networks_list[i].ssid.ssid, 5234 nlo_list[i].ssid.ssid.ssid_len); 5235 5236 /* Copy rssi threshold */ 5237 if (pno->networks_list[i].rssi_thresh && 5238 pno->networks_list[i].rssi_thresh > 5239 WMI_RSSI_THOLD_DEFAULT) { 5240 nlo_list[i].rssi_cond.valid = true; 5241 nlo_list[i].rssi_cond.rssi = 5242 pno->networks_list[i].rssi_thresh; 5243 } 5244 nlo_list[i].bcast_nw_type.valid = true; 5245 nlo_list[i].bcast_nw_type.bcast_nw_type = 5246 pno->networks_list[i].bc_new_type; 5247 } 5248 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 5249 5250 /* Copy channel info */ 5251 cmd->num_of_channels = pno->networks_list[0].channel_cnt; 5252 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 5253 (cmd->num_of_channels * sizeof(uint32_t))); 5254 buf_ptr += WMI_TLV_HDR_SIZE; 5255 5256 channel_list = (uint32_t *) buf_ptr; 5257 for (i = 0; i < cmd->num_of_channels; i++) { 5258 channel_list[i] = pno->networks_list[0].channels[i]; 5259 5260 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 5261 channel_list[i] = 5262 wlan_chan_to_freq(pno-> 5263 networks_list[0].channels[i]); 5264 } 5265 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 5266 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5267 sizeof(nlo_channel_prediction_cfg)); 5268 buf_ptr += WMI_TLV_HDR_SIZE; 5269 wmi_set_pno_channel_prediction(buf_ptr, pno); 5270 buf_ptr += sizeof(nlo_channel_prediction_cfg); 5271 /** TODO: Discrete firmware doesn't have command/option to configure 5272 * App IE which comes from wpa_supplicant as of part PNO start request. 5273 */ 5274 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 5275 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 5276 buf_ptr += sizeof(enlo_candidate_score_params); 5277 5278 if (ie_whitelist->white_list) { 5279 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 5280 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 5281 &cmd->num_vendor_oui, 5282 ie_whitelist); 5283 } 5284 5285 /* ie white list */ 5286 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5287 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 5288 buf_ptr += WMI_TLV_HDR_SIZE; 5289 if (cmd->num_vendor_oui != 0) { 5290 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 5291 ie_whitelist->voui); 5292 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 5293 } 5294 5295 if (pno->relative_rssi_set) 5296 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 5297 5298 /* 5299 * Firmware calculation using connected PNO params: 5300 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 5301 * deduction of rssi_pref for chosen band_pref and 5302 * addition of rssi_pref for remaining bands (other than chosen band). 5303 */ 5304 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 5305 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 5306 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 5307 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 5308 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 5309 buf_ptr += sizeof(*nlo_relative_rssi); 5310 5311 /* 5312 * As of now Kernel and Host supports one band and rssi preference. 5313 * Firmware supports array of band and rssi preferences 5314 */ 5315 cmd->num_cnlo_band_pref = 1; 5316 WMITLV_SET_HDR(buf_ptr, 5317 WMITLV_TAG_ARRAY_STRUC, 5318 cmd->num_cnlo_band_pref * 5319 sizeof(connected_nlo_bss_band_rssi_pref)); 5320 buf_ptr += WMI_TLV_HDR_SIZE; 5321 5322 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 5323 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 5324 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 5325 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 5326 WMITLV_GET_STRUCT_TLVLEN( 5327 connected_nlo_bss_band_rssi_pref)); 5328 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 5329 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 5330 } 5331 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 5332 5333 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5334 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5335 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5336 if (ret) { 5337 wmi_err("Failed to send nlo wmi cmd"); 5338 wmi_buf_free(buf); 5339 return QDF_STATUS_E_FAILURE; 5340 } 5341 5342 return QDF_STATUS_SUCCESS; 5343 } 5344 5345 /** 5346 * is_service_enabled_tlv() - Check if service enabled 5347 * @param wmi_handle: wmi handle 5348 * @param service_id: service identifier 5349 * 5350 * Return: 1 enabled, 0 disabled 5351 */ 5352 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 5353 uint32_t service_id) 5354 { 5355 struct wmi_soc *soc = wmi_handle->soc; 5356 5357 if (!soc->wmi_service_bitmap) { 5358 wmi_err("WMI service bit map is not saved yet"); 5359 return false; 5360 } 5361 5362 /* if wmi_service_enabled was received with extended2 bitmap, 5363 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 5364 */ 5365 if (soc->wmi_ext2_service_bitmap) { 5366 if (!soc->wmi_ext_service_bitmap) { 5367 wmi_err("WMI service ext bit map is not saved yet"); 5368 return false; 5369 } 5370 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 5371 soc->wmi_ext_service_bitmap, 5372 soc->wmi_ext2_service_bitmap, 5373 service_id); 5374 } 5375 5376 if (service_id >= WMI_MAX_EXT_SERVICE) { 5377 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 5378 service_id); 5379 return false; 5380 } 5381 /* if wmi_service_enabled was received with extended bitmap, 5382 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 5383 */ 5384 if (soc->wmi_ext_service_bitmap) 5385 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 5386 soc->wmi_ext_service_bitmap, 5387 service_id); 5388 5389 if (service_id >= WMI_MAX_SERVICE) { 5390 wmi_err("Service id %d but WMI ext service bitmap is NULL", 5391 service_id); 5392 return false; 5393 } 5394 5395 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 5396 service_id); 5397 } 5398 5399 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5400 /** 5401 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5402 * @wmi_handle: wmi handle 5403 * @clear_req: ll stats clear request command params 5404 * 5405 * Return: QDF_STATUS_SUCCESS for success or error code 5406 */ 5407 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5408 const struct ll_stats_clear_params *clear_req) 5409 { 5410 wmi_clear_link_stats_cmd_fixed_param *cmd; 5411 int32_t len; 5412 wmi_buf_t buf; 5413 uint8_t *buf_ptr; 5414 int ret; 5415 5416 len = sizeof(*cmd); 5417 buf = wmi_buf_alloc(wmi_handle, len); 5418 5419 if (!buf) 5420 return QDF_STATUS_E_NOMEM; 5421 5422 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5423 qdf_mem_zero(buf_ptr, len); 5424 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5425 5426 WMITLV_SET_HDR(&cmd->tlv_header, 5427 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5428 WMITLV_GET_STRUCT_TLVLEN 5429 (wmi_clear_link_stats_cmd_fixed_param)); 5430 5431 cmd->stop_stats_collection_req = clear_req->stop_req; 5432 cmd->vdev_id = clear_req->vdev_id; 5433 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5434 5435 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5436 &cmd->peer_macaddr); 5437 5438 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 5439 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 5440 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5441 cmd->stop_stats_collection_req, 5442 cmd->vdev_id, cmd->stats_clear_req_mask, 5443 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 5444 5445 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5446 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5447 WMI_CLEAR_LINK_STATS_CMDID); 5448 if (ret) { 5449 wmi_err("Failed to send clear link stats req"); 5450 wmi_buf_free(buf); 5451 return QDF_STATUS_E_FAILURE; 5452 } 5453 5454 wmi_debug("Clear Link Layer Stats request sent successfully"); 5455 return QDF_STATUS_SUCCESS; 5456 } 5457 5458 /** 5459 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5460 * @wmi_handle: wmi handle 5461 * @set_req: ll stats set request command params 5462 * 5463 * Return: QDF_STATUS_SUCCESS for success or error code 5464 */ 5465 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5466 const struct ll_stats_set_params *set_req) 5467 { 5468 wmi_start_link_stats_cmd_fixed_param *cmd; 5469 int32_t len; 5470 wmi_buf_t buf; 5471 uint8_t *buf_ptr; 5472 int ret; 5473 5474 len = sizeof(*cmd); 5475 buf = wmi_buf_alloc(wmi_handle, len); 5476 5477 if (!buf) 5478 return QDF_STATUS_E_NOMEM; 5479 5480 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5481 qdf_mem_zero(buf_ptr, len); 5482 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5483 5484 WMITLV_SET_HDR(&cmd->tlv_header, 5485 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5486 WMITLV_GET_STRUCT_TLVLEN 5487 (wmi_start_link_stats_cmd_fixed_param)); 5488 5489 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5490 cmd->aggressive_statistics_gathering = 5491 set_req->aggressive_statistics_gathering; 5492 5493 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 5494 cmd->mpdu_size_threshold, 5495 cmd->aggressive_statistics_gathering); 5496 5497 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5498 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5499 WMI_START_LINK_STATS_CMDID); 5500 if (ret) { 5501 wmi_err("Failed to send set link stats request"); 5502 wmi_buf_free(buf); 5503 return QDF_STATUS_E_FAILURE; 5504 } 5505 5506 return QDF_STATUS_SUCCESS; 5507 } 5508 5509 /** 5510 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5511 * @wmi_handle: wmi handle 5512 * @get_req: ll stats get request command params 5513 * 5514 * Return: QDF_STATUS_SUCCESS for success or error code 5515 */ 5516 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5517 const struct ll_stats_get_params *get_req) 5518 { 5519 wmi_request_link_stats_cmd_fixed_param *cmd; 5520 int32_t len; 5521 wmi_buf_t buf; 5522 uint8_t *buf_ptr; 5523 int ret; 5524 5525 len = sizeof(*cmd); 5526 buf = wmi_buf_alloc(wmi_handle, len); 5527 5528 if (!buf) 5529 return QDF_STATUS_E_NOMEM; 5530 5531 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5532 qdf_mem_zero(buf_ptr, len); 5533 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5534 5535 WMITLV_SET_HDR(&cmd->tlv_header, 5536 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5537 WMITLV_GET_STRUCT_TLVLEN 5538 (wmi_request_link_stats_cmd_fixed_param)); 5539 5540 cmd->request_id = get_req->req_id; 5541 cmd->stats_type = get_req->param_id_mask; 5542 cmd->vdev_id = get_req->vdev_id; 5543 5544 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5545 &cmd->peer_macaddr); 5546 5547 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 5548 cmd->request_id, cmd->stats_type, cmd->vdev_id, 5549 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5550 5551 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 5552 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 5553 WMI_REQUEST_LINK_STATS_CMDID); 5554 if (ret) { 5555 wmi_buf_free(buf); 5556 return QDF_STATUS_E_FAILURE; 5557 } 5558 5559 return QDF_STATUS_SUCCESS; 5560 } 5561 5562 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 5563 /** 5564 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 5565 * station request 5566 * @wmi_handle: wmi handle 5567 * @get_req: ll stats get request command params 5568 * 5569 * Return: QDF_STATUS_SUCCESS for success or error code 5570 */ 5571 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 5572 wmi_unified_t wmi_handle, 5573 const struct ll_stats_get_params *get_req) 5574 { 5575 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 5576 int32_t len; 5577 wmi_buf_t buf; 5578 void *buf_ptr; 5579 QDF_STATUS ret; 5580 bool is_ll_get_sta_stats_over_qmi; 5581 5582 len = sizeof(*unified_cmd); 5583 buf = wmi_buf_alloc(wmi_handle, len); 5584 5585 if (!buf) 5586 return QDF_STATUS_E_NOMEM; 5587 5588 buf_ptr = wmi_buf_data(buf); 5589 5590 unified_cmd = buf_ptr; 5591 WMITLV_SET_HDR( 5592 &unified_cmd->tlv_header, 5593 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 5594 WMITLV_GET_STRUCT_TLVLEN 5595 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 5596 5597 unified_cmd->link_stats_type = get_req->param_id_mask; 5598 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 5599 WMI_REQUEST_PEER_STAT | 5600 WMI_REQUEST_VDEV_STAT | 5601 WMI_REQUEST_PDEV_STAT | 5602 WMI_REQUEST_PEER_EXTD2_STAT | 5603 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 5604 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5605 wmi_handle, 5606 WMI_HOST_PDEV_ID_SOC); 5607 5608 unified_cmd->vdev_id = get_req->vdev_id; 5609 unified_cmd->request_id = get_req->req_id; 5610 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5611 &unified_cmd->peer_macaddr); 5612 5613 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 5614 QDF_MAC_ADDR_FMT, 5615 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 5616 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 5617 5618 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 5619 5620 /** 5621 * FW support for LL_get_sta command. True represents the unified 5622 * ll_get_sta command should be sent over QMI always irrespective of 5623 * WOW state. 5624 */ 5625 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 5626 wmi_handle, 5627 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 5628 5629 if (is_ll_get_sta_stats_over_qmi) { 5630 ret = wmi_unified_cmd_send_over_qmi( 5631 wmi_handle, buf, len, 5632 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 5633 } else { 5634 ret = wmi_unified_cmd_send_pm_chk( 5635 wmi_handle, buf, len, 5636 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 5637 } 5638 5639 if (QDF_IS_STATUS_ERROR(ret)) { 5640 wmi_buf_free(buf); 5641 return QDF_STATUS_E_FAILURE; 5642 } 5643 5644 return ret; 5645 } 5646 #endif 5647 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 5648 5649 /** 5650 * send_congestion_cmd_tlv() - send request to fw to get CCA 5651 * @wmi_handle: wmi handle 5652 * @vdev_id: vdev id 5653 * 5654 * Return: CDF status 5655 */ 5656 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 5657 uint8_t vdev_id) 5658 { 5659 wmi_buf_t buf; 5660 wmi_request_stats_cmd_fixed_param *cmd; 5661 uint8_t len; 5662 uint8_t *buf_ptr; 5663 5664 len = sizeof(*cmd); 5665 buf = wmi_buf_alloc(wmi_handle, len); 5666 if (!buf) 5667 return QDF_STATUS_E_FAILURE; 5668 5669 buf_ptr = wmi_buf_data(buf); 5670 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 5671 WMITLV_SET_HDR(&cmd->tlv_header, 5672 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5673 WMITLV_GET_STRUCT_TLVLEN 5674 (wmi_request_stats_cmd_fixed_param)); 5675 5676 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 5677 cmd->vdev_id = vdev_id; 5678 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 5679 cmd->vdev_id, cmd->stats_id); 5680 5681 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5682 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5683 WMI_REQUEST_STATS_CMDID)) { 5684 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 5685 wmi_buf_free(buf); 5686 return QDF_STATUS_E_FAILURE; 5687 } 5688 5689 return QDF_STATUS_SUCCESS; 5690 } 5691 5692 /** 5693 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 5694 * @wmi_handle: wmi handle 5695 * @rssi_req: get RSSI request 5696 * 5697 * Return: CDF status 5698 */ 5699 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 5700 { 5701 wmi_buf_t buf; 5702 wmi_request_stats_cmd_fixed_param *cmd; 5703 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5704 5705 buf = wmi_buf_alloc(wmi_handle, len); 5706 if (!buf) 5707 return QDF_STATUS_E_FAILURE; 5708 5709 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5710 WMITLV_SET_HDR(&cmd->tlv_header, 5711 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5712 WMITLV_GET_STRUCT_TLVLEN 5713 (wmi_request_stats_cmd_fixed_param)); 5714 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5715 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5716 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5717 WMI_REQUEST_STATS_CMDID)) { 5718 wmi_err("Failed to send host stats request to fw"); 5719 wmi_buf_free(buf); 5720 return QDF_STATUS_E_FAILURE; 5721 } 5722 5723 return QDF_STATUS_SUCCESS; 5724 } 5725 5726 /** 5727 * send_snr_cmd_tlv() - get RSSI from fw 5728 * @wmi_handle: wmi handle 5729 * @vdev_id: vdev id 5730 * 5731 * Return: CDF status 5732 */ 5733 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5734 { 5735 wmi_buf_t buf; 5736 wmi_request_stats_cmd_fixed_param *cmd; 5737 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5738 5739 buf = wmi_buf_alloc(wmi_handle, len); 5740 if (!buf) 5741 return QDF_STATUS_E_FAILURE; 5742 5743 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5744 cmd->vdev_id = vdev_id; 5745 5746 WMITLV_SET_HDR(&cmd->tlv_header, 5747 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5748 WMITLV_GET_STRUCT_TLVLEN 5749 (wmi_request_stats_cmd_fixed_param)); 5750 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5751 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5752 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5753 WMI_REQUEST_STATS_CMDID)) { 5754 wmi_err("Failed to send host stats request to fw"); 5755 wmi_buf_free(buf); 5756 return QDF_STATUS_E_FAILURE; 5757 } 5758 5759 return QDF_STATUS_SUCCESS; 5760 } 5761 5762 /** 5763 * send_link_status_req_cmd_tlv() - process link status request from UMAC 5764 * @wmi_handle: wmi handle 5765 * @link_status: get link params 5766 * 5767 * Return: CDF status 5768 */ 5769 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 5770 struct link_status_params *link_status) 5771 { 5772 wmi_buf_t buf; 5773 wmi_request_stats_cmd_fixed_param *cmd; 5774 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5775 5776 buf = wmi_buf_alloc(wmi_handle, len); 5777 if (!buf) 5778 return QDF_STATUS_E_FAILURE; 5779 5780 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5781 WMITLV_SET_HDR(&cmd->tlv_header, 5782 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5783 WMITLV_GET_STRUCT_TLVLEN 5784 (wmi_request_stats_cmd_fixed_param)); 5785 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 5786 cmd->vdev_id = link_status->vdev_id; 5787 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5788 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5789 WMI_REQUEST_STATS_CMDID)) { 5790 wmi_err("Failed to send WMI link status request to fw"); 5791 wmi_buf_free(buf); 5792 return QDF_STATUS_E_FAILURE; 5793 } 5794 5795 return QDF_STATUS_SUCCESS; 5796 } 5797 5798 #ifdef WLAN_SUPPORT_GREEN_AP 5799 /** 5800 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 5801 * @wmi_handle: wmi handler 5802 * @egap_params: pointer to egap_params 5803 * 5804 * Return: 0 for success, otherwise appropriate error code 5805 */ 5806 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 5807 struct wlan_green_ap_egap_params *egap_params) 5808 { 5809 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 5810 wmi_buf_t buf; 5811 int32_t err; 5812 5813 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5814 if (!buf) 5815 return QDF_STATUS_E_NOMEM; 5816 5817 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 5818 WMITLV_SET_HDR(&cmd->tlv_header, 5819 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 5820 WMITLV_GET_STRUCT_TLVLEN( 5821 wmi_ap_ps_egap_param_cmd_fixed_param)); 5822 5823 cmd->enable = egap_params->host_enable_egap; 5824 cmd->inactivity_time = egap_params->egap_inactivity_time; 5825 cmd->wait_time = egap_params->egap_wait_time; 5826 cmd->flags = egap_params->egap_feature_flags; 5827 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 5828 err = wmi_unified_cmd_send(wmi_handle, buf, 5829 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 5830 if (err) { 5831 wmi_err("Failed to send ap_ps_egap cmd"); 5832 wmi_buf_free(buf); 5833 return QDF_STATUS_E_FAILURE; 5834 } 5835 5836 return QDF_STATUS_SUCCESS; 5837 } 5838 #endif 5839 5840 /** 5841 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 5842 * @wmi_handle: wmi handle 5843 * @vdev_id: vdev id 5844 * 5845 * Return: QDF_STATUS_SUCCESS for success or error code 5846 */ 5847 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 5848 uint8_t vdev_id) 5849 { 5850 wmi_csa_offload_enable_cmd_fixed_param *cmd; 5851 wmi_buf_t buf; 5852 int32_t len = sizeof(*cmd); 5853 5854 wmi_debug("vdev_id %d", vdev_id); 5855 buf = wmi_buf_alloc(wmi_handle, len); 5856 if (!buf) 5857 return QDF_STATUS_E_NOMEM; 5858 5859 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 5860 WMITLV_SET_HDR(&cmd->tlv_header, 5861 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 5862 WMITLV_GET_STRUCT_TLVLEN 5863 (wmi_csa_offload_enable_cmd_fixed_param)); 5864 cmd->vdev_id = vdev_id; 5865 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 5866 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 5867 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5868 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 5869 wmi_err("Failed to send CSA offload enable command"); 5870 wmi_buf_free(buf); 5871 return QDF_STATUS_E_FAILURE; 5872 } 5873 5874 return 0; 5875 } 5876 5877 #ifdef WLAN_FEATURE_CIF_CFR 5878 /** 5879 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 5880 * @wmi_handle: wmi handle 5881 * @data_len: len of dma cfg req 5882 * @data: dma cfg req 5883 * 5884 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 5885 */ 5886 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 5887 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 5888 { 5889 wmi_buf_t buf; 5890 uint8_t *cmd; 5891 QDF_STATUS ret; 5892 5893 WMITLV_SET_HDR(cfg, 5894 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 5895 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 5896 5897 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 5898 if (!buf) 5899 return QDF_STATUS_E_FAILURE; 5900 5901 cmd = (uint8_t *) wmi_buf_data(buf); 5902 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 5903 wmi_debug("Sending OEM Data Request to target, data len %lu", 5904 sizeof(*cfg)); 5905 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 5906 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 5907 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 5908 if (QDF_IS_STATUS_ERROR(ret)) { 5909 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 5910 wmi_buf_free(buf); 5911 } 5912 5913 return ret; 5914 } 5915 #endif 5916 5917 /** 5918 * send_start_11d_scan_cmd_tlv() - start 11d scan request 5919 * @wmi_handle: wmi handle 5920 * @start_11d_scan: 11d scan start request parameters 5921 * 5922 * This function request FW to start 11d scan. 5923 * 5924 * Return: QDF status 5925 */ 5926 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5927 struct reg_start_11d_scan_req *start_11d_scan) 5928 { 5929 wmi_11d_scan_start_cmd_fixed_param *cmd; 5930 int32_t len; 5931 wmi_buf_t buf; 5932 int ret; 5933 5934 len = sizeof(*cmd); 5935 buf = wmi_buf_alloc(wmi_handle, len); 5936 if (!buf) 5937 return QDF_STATUS_E_NOMEM; 5938 5939 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 5940 5941 WMITLV_SET_HDR(&cmd->tlv_header, 5942 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 5943 WMITLV_GET_STRUCT_TLVLEN 5944 (wmi_11d_scan_start_cmd_fixed_param)); 5945 5946 cmd->vdev_id = start_11d_scan->vdev_id; 5947 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 5948 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 5949 5950 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 5951 5952 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 5953 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5954 WMI_11D_SCAN_START_CMDID); 5955 if (ret) { 5956 wmi_err("Failed to send start 11d scan wmi cmd"); 5957 wmi_buf_free(buf); 5958 return QDF_STATUS_E_FAILURE; 5959 } 5960 5961 return QDF_STATUS_SUCCESS; 5962 } 5963 5964 /** 5965 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 5966 * @wmi_handle: wmi handle 5967 * @start_11d_scan: 11d scan stop request parameters 5968 * 5969 * This function request FW to stop 11d scan. 5970 * 5971 * Return: QDF status 5972 */ 5973 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5974 struct reg_stop_11d_scan_req *stop_11d_scan) 5975 { 5976 wmi_11d_scan_stop_cmd_fixed_param *cmd; 5977 int32_t len; 5978 wmi_buf_t buf; 5979 int ret; 5980 5981 len = sizeof(*cmd); 5982 buf = wmi_buf_alloc(wmi_handle, len); 5983 if (!buf) 5984 return QDF_STATUS_E_NOMEM; 5985 5986 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 5987 5988 WMITLV_SET_HDR(&cmd->tlv_header, 5989 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 5990 WMITLV_GET_STRUCT_TLVLEN 5991 (wmi_11d_scan_stop_cmd_fixed_param)); 5992 5993 cmd->vdev_id = stop_11d_scan->vdev_id; 5994 5995 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 5996 5997 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 5998 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5999 WMI_11D_SCAN_STOP_CMDID); 6000 if (ret) { 6001 wmi_err("Failed to send stop 11d scan wmi cmd"); 6002 wmi_buf_free(buf); 6003 return QDF_STATUS_E_FAILURE; 6004 } 6005 6006 return QDF_STATUS_SUCCESS; 6007 } 6008 6009 /** 6010 * send_start_oem_data_cmd_tlv() - start OEM data request to target 6011 * @wmi_handle: wmi handle 6012 * @data_len: the length of @data 6013 * @data: the pointer to data buf 6014 * 6015 * Return: CDF status 6016 */ 6017 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 6018 uint32_t data_len, 6019 uint8_t *data) 6020 { 6021 wmi_buf_t buf; 6022 uint8_t *cmd; 6023 QDF_STATUS ret; 6024 6025 buf = wmi_buf_alloc(wmi_handle, 6026 (data_len + WMI_TLV_HDR_SIZE)); 6027 if (!buf) 6028 return QDF_STATUS_E_FAILURE; 6029 6030 cmd = (uint8_t *) wmi_buf_data(buf); 6031 6032 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 6033 cmd += WMI_TLV_HDR_SIZE; 6034 qdf_mem_copy(cmd, data, 6035 data_len); 6036 6037 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 6038 6039 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 6040 ret = wmi_unified_cmd_send(wmi_handle, buf, 6041 (data_len + 6042 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 6043 6044 if (QDF_IS_STATUS_ERROR(ret)) { 6045 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 6046 wmi_buf_free(buf); 6047 } 6048 6049 return ret; 6050 } 6051 6052 #ifdef FEATURE_OEM_DATA 6053 /** 6054 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 6055 * @wmi_handle: wmi handle 6056 * @oem_data: the pointer to oem data 6057 * 6058 * Return: QDF status 6059 */ 6060 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 6061 struct oem_data *oem_data) 6062 { 6063 QDF_STATUS ret; 6064 wmi_oem_data_cmd_fixed_param *cmd; 6065 struct wmi_ops *ops; 6066 wmi_buf_t buf; 6067 uint16_t len = sizeof(*cmd); 6068 uint16_t oem_data_len_aligned; 6069 uint8_t *buf_ptr; 6070 uint32_t pdev_id; 6071 6072 if (!oem_data || !oem_data->data) { 6073 wmi_err_rl("oem data is not valid"); 6074 return QDF_STATUS_E_FAILURE; 6075 } 6076 6077 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 6078 if (oem_data_len_aligned < oem_data->data_len) { 6079 wmi_err_rl("integer overflow while rounding up data_len"); 6080 return QDF_STATUS_E_FAILURE; 6081 } 6082 6083 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 6084 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 6085 return QDF_STATUS_E_FAILURE; 6086 } 6087 6088 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 6089 buf = wmi_buf_alloc(wmi_handle, len); 6090 if (!buf) 6091 return QDF_STATUS_E_NOMEM; 6092 6093 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6094 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 6095 WMITLV_SET_HDR(&cmd->tlv_header, 6096 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 6097 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 6098 6099 pdev_id = oem_data->pdev_id; 6100 if (oem_data->pdev_vdev_flag) { 6101 ops = wmi_handle->ops; 6102 if (oem_data->is_host_pdev_id) 6103 pdev_id = 6104 ops->convert_host_pdev_id_to_target(wmi_handle, 6105 pdev_id); 6106 else 6107 pdev_id = 6108 ops->convert_pdev_id_host_to_target(wmi_handle, 6109 pdev_id); 6110 } 6111 6112 cmd->vdev_id = oem_data->vdev_id; 6113 cmd->data_len = oem_data->data_len; 6114 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 6115 cmd->pdev_id = pdev_id; 6116 6117 buf_ptr += sizeof(*cmd); 6118 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 6119 buf_ptr += WMI_TLV_HDR_SIZE; 6120 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 6121 6122 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 6123 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 6124 if (QDF_IS_STATUS_ERROR(ret)) { 6125 wmi_err_rl("Failed with ret = %d", ret); 6126 wmi_buf_free(buf); 6127 } 6128 6129 return ret; 6130 } 6131 #endif 6132 6133 /** 6134 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 6135 * @wmi_handle: wmi handle 6136 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 6137 * 6138 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 6139 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 6140 * to firmware based on phyerr filtering 6141 * offload status. 6142 * 6143 * Return: 1 success, 0 failure 6144 */ 6145 static QDF_STATUS 6146 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 6147 bool dfs_phyerr_filter_offload) 6148 { 6149 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 6150 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 6151 wmi_buf_t buf; 6152 uint16_t len; 6153 QDF_STATUS ret; 6154 6155 6156 if (false == dfs_phyerr_filter_offload) { 6157 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 6158 len = sizeof(*disable_phyerr_offload_cmd); 6159 buf = wmi_buf_alloc(wmi_handle, len); 6160 if (!buf) 6161 return 0; 6162 6163 disable_phyerr_offload_cmd = 6164 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 6165 wmi_buf_data(buf); 6166 6167 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 6168 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 6169 WMITLV_GET_STRUCT_TLVLEN 6170 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 6171 6172 /* 6173 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 6174 * to the firmware to disable the phyerror 6175 * filtering offload. 6176 */ 6177 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 6178 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6179 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 6180 if (QDF_IS_STATUS_ERROR(ret)) { 6181 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 6182 ret); 6183 wmi_buf_free(buf); 6184 return QDF_STATUS_E_FAILURE; 6185 } 6186 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 6187 } else { 6188 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 6189 6190 len = sizeof(*enable_phyerr_offload_cmd); 6191 buf = wmi_buf_alloc(wmi_handle, len); 6192 if (!buf) 6193 return QDF_STATUS_E_FAILURE; 6194 6195 enable_phyerr_offload_cmd = 6196 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 6197 wmi_buf_data(buf); 6198 6199 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 6200 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 6201 WMITLV_GET_STRUCT_TLVLEN 6202 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 6203 6204 /* 6205 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 6206 * to the firmware to enable the phyerror 6207 * filtering offload. 6208 */ 6209 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 6210 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6211 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 6212 6213 if (QDF_IS_STATUS_ERROR(ret)) { 6214 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 6215 wmi_buf_free(buf); 6216 return QDF_STATUS_E_FAILURE; 6217 } 6218 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 6219 } 6220 6221 return QDF_STATUS_SUCCESS; 6222 } 6223 6224 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 6225 /** 6226 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 6227 * @wmi_handle: wmi handle 6228 * @pktlog_event: pktlog event 6229 * @cmd_id: pktlog cmd id 6230 * @user_triggered: user triggered input for PKTLOG enable mode 6231 * 6232 * Return: CDF status 6233 */ 6234 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 6235 WMI_PKTLOG_EVENT pktlog_event, 6236 WMI_CMD_ID cmd_id, uint8_t user_triggered) 6237 { 6238 WMI_PKTLOG_EVENT PKTLOG_EVENT; 6239 WMI_CMD_ID CMD_ID; 6240 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 6241 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 6242 int len = 0; 6243 wmi_buf_t buf; 6244 int32_t idx, max_idx; 6245 6246 PKTLOG_EVENT = pktlog_event; 6247 CMD_ID = cmd_id; 6248 6249 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 6250 switch (CMD_ID) { 6251 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 6252 len = sizeof(*cmd); 6253 buf = wmi_buf_alloc(wmi_handle, len); 6254 if (!buf) 6255 return QDF_STATUS_E_NOMEM; 6256 6257 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 6258 wmi_buf_data(buf); 6259 WMITLV_SET_HDR(&cmd->tlv_header, 6260 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 6261 WMITLV_GET_STRUCT_TLVLEN 6262 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 6263 cmd->evlist = 0; 6264 for (idx = 0; idx < max_idx; idx++) { 6265 if (PKTLOG_EVENT & (1 << idx)) 6266 cmd->evlist |= pktlog_event_tlv[idx]; 6267 } 6268 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 6269 : WMI_PKTLOG_ENABLE_AUTO; 6270 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6271 wmi_handle, 6272 WMI_HOST_PDEV_ID_SOC); 6273 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 6274 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6275 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 6276 wmi_err("Failed to send pktlog enable cmdid"); 6277 goto wmi_send_failed; 6278 } 6279 break; 6280 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 6281 len = sizeof(*disable_cmd); 6282 buf = wmi_buf_alloc(wmi_handle, len); 6283 if (!buf) 6284 return QDF_STATUS_E_NOMEM; 6285 6286 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 6287 wmi_buf_data(buf); 6288 WMITLV_SET_HDR(&disable_cmd->tlv_header, 6289 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 6290 WMITLV_GET_STRUCT_TLVLEN 6291 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 6292 disable_cmd->pdev_id = 6293 wmi_handle->ops->convert_pdev_id_host_to_target( 6294 wmi_handle, 6295 WMI_HOST_PDEV_ID_SOC); 6296 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 6297 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6298 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 6299 wmi_err("failed to send pktlog disable cmdid"); 6300 goto wmi_send_failed; 6301 } 6302 break; 6303 default: 6304 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 6305 break; 6306 } 6307 6308 return QDF_STATUS_SUCCESS; 6309 6310 wmi_send_failed: 6311 wmi_buf_free(buf); 6312 return QDF_STATUS_E_FAILURE; 6313 } 6314 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 6315 6316 /** 6317 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 6318 * @wmi_handle: wmi handle 6319 * @preq: stats ext params 6320 * 6321 * Return: CDF status 6322 */ 6323 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 6324 struct stats_ext_params *preq) 6325 { 6326 QDF_STATUS ret; 6327 wmi_req_stats_ext_cmd_fixed_param *cmd; 6328 wmi_buf_t buf; 6329 size_t len; 6330 uint8_t *buf_ptr; 6331 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 6332 6333 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 6334 sizeof(*cmd))) { 6335 wmi_err("Data length=%d is greater than max wmi msg size", 6336 preq->request_data_len); 6337 return QDF_STATUS_E_FAILURE; 6338 } 6339 6340 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 6341 6342 buf = wmi_buf_alloc(wmi_handle, len); 6343 if (!buf) 6344 return QDF_STATUS_E_NOMEM; 6345 6346 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6347 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 6348 6349 WMITLV_SET_HDR(&cmd->tlv_header, 6350 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 6351 WMITLV_GET_STRUCT_TLVLEN 6352 (wmi_req_stats_ext_cmd_fixed_param)); 6353 cmd->vdev_id = preq->vdev_id; 6354 cmd->data_len = preq->request_data_len; 6355 6356 wmi_debug("The data len value is %u and vdev id set is %u", 6357 preq->request_data_len, preq->vdev_id); 6358 6359 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 6360 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 6361 6362 buf_ptr += WMI_TLV_HDR_SIZE; 6363 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 6364 6365 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 6366 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6367 WMI_REQUEST_STATS_EXT_CMDID); 6368 if (QDF_IS_STATUS_ERROR(ret)) { 6369 wmi_err("Failed to send notify cmd ret = %d", ret); 6370 wmi_buf_free(buf); 6371 } 6372 6373 return ret; 6374 } 6375 6376 /** 6377 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 6378 * @wmi_handle: wmi handle 6379 * @params: DHCP server offload info 6380 * 6381 * Return: QDF_STATUS_SUCCESS for success or error code 6382 */ 6383 static QDF_STATUS 6384 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 6385 struct dhcp_offload_info_params *params) 6386 { 6387 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 6388 wmi_buf_t buf; 6389 QDF_STATUS status; 6390 6391 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 6392 if (!buf) 6393 return QDF_STATUS_E_NOMEM; 6394 6395 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 6396 6397 WMITLV_SET_HDR(&cmd->tlv_header, 6398 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 6399 WMITLV_GET_STRUCT_TLVLEN 6400 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 6401 cmd->vdev_id = params->vdev_id; 6402 cmd->enable = params->dhcp_offload_enabled; 6403 cmd->num_client = params->dhcp_client_num; 6404 cmd->srv_ipv4 = params->dhcp_srv_addr; 6405 cmd->start_lsb = 0; 6406 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 6407 status = wmi_unified_cmd_send(wmi_handle, buf, 6408 sizeof(*cmd), 6409 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 6410 if (QDF_IS_STATUS_ERROR(status)) { 6411 wmi_err("Failed to send set_dhcp_server_offload cmd"); 6412 wmi_buf_free(buf); 6413 return QDF_STATUS_E_FAILURE; 6414 } 6415 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 6416 6417 return status; 6418 } 6419 6420 /** 6421 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 6422 * @wmi_handle: wmi handle 6423 * @param: pointer to pdev regdomain params 6424 * 6425 * Return: 0 for success or error code 6426 */ 6427 static QDF_STATUS 6428 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 6429 struct pdev_set_regdomain_params *param) 6430 { 6431 wmi_buf_t buf; 6432 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6433 int32_t len = sizeof(*cmd); 6434 6435 buf = wmi_buf_alloc(wmi_handle, len); 6436 if (!buf) 6437 return QDF_STATUS_E_NOMEM; 6438 6439 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6440 WMITLV_SET_HDR(&cmd->tlv_header, 6441 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6442 WMITLV_GET_STRUCT_TLVLEN 6443 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6444 6445 cmd->reg_domain = param->currentRDinuse; 6446 cmd->reg_domain_2G = param->currentRD2G; 6447 cmd->reg_domain_5G = param->currentRD5G; 6448 cmd->conformance_test_limit_2G = param->ctl_2G; 6449 cmd->conformance_test_limit_5G = param->ctl_5G; 6450 cmd->dfs_domain = param->dfsDomain; 6451 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6452 wmi_handle, 6453 param->pdev_id); 6454 6455 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6456 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6457 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6458 wmi_err("Failed to send pdev set regdomain command"); 6459 wmi_buf_free(buf); 6460 return QDF_STATUS_E_FAILURE; 6461 } 6462 6463 return QDF_STATUS_SUCCESS; 6464 } 6465 6466 /** 6467 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 6468 * @wmi_handle: wmi handle 6469 * @reg_dmn: reg domain 6470 * @regdmn2G: 2G reg domain 6471 * @regdmn5G: 5G reg domain 6472 * @ctl2G: 2G test limit 6473 * @ctl5G: 5G test limit 6474 * 6475 * Return: none 6476 */ 6477 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 6478 uint32_t reg_dmn, uint16_t regdmn2G, 6479 uint16_t regdmn5G, uint8_t ctl2G, 6480 uint8_t ctl5G) 6481 { 6482 wmi_buf_t buf; 6483 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6484 int32_t len = sizeof(*cmd); 6485 6486 6487 buf = wmi_buf_alloc(wmi_handle, len); 6488 if (!buf) 6489 return QDF_STATUS_E_NOMEM; 6490 6491 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6492 WMITLV_SET_HDR(&cmd->tlv_header, 6493 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6494 WMITLV_GET_STRUCT_TLVLEN 6495 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6496 cmd->reg_domain = reg_dmn; 6497 cmd->reg_domain_2G = regdmn2G; 6498 cmd->reg_domain_5G = regdmn5G; 6499 cmd->conformance_test_limit_2G = ctl2G; 6500 cmd->conformance_test_limit_5G = ctl5G; 6501 6502 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 6503 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 6504 cmd->conformance_test_limit_2G, 6505 cmd->conformance_test_limit_5G); 6506 6507 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6508 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6509 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6510 wmi_err("Failed to send pdev set regdomain command"); 6511 wmi_buf_free(buf); 6512 return QDF_STATUS_E_FAILURE; 6513 } 6514 6515 return QDF_STATUS_SUCCESS; 6516 } 6517 6518 /** 6519 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 6520 * @param: param sent from the host side 6521 * @cmd: param to be sent to the fw side 6522 */ 6523 static inline void copy_custom_aggr_bitmap( 6524 struct set_custom_aggr_size_params *param, 6525 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 6526 { 6527 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 6528 param->ac); 6529 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 6530 param->aggr_type); 6531 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6532 param->tx_aggr_size_disable); 6533 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6534 param->rx_aggr_size_disable); 6535 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 6536 param->tx_ac_enable); 6537 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 6538 param->aggr_ba_enable); 6539 } 6540 6541 /** 6542 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 6543 * @wmi_handle: wmi handle 6544 * @param: pointer to hold custom aggr size params 6545 * 6546 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6547 */ 6548 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 6549 wmi_unified_t wmi_handle, 6550 struct set_custom_aggr_size_params *param) 6551 { 6552 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 6553 wmi_buf_t buf; 6554 int32_t len = sizeof(*cmd); 6555 6556 buf = wmi_buf_alloc(wmi_handle, len); 6557 if (!buf) 6558 return QDF_STATUS_E_FAILURE; 6559 6560 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 6561 wmi_buf_data(buf); 6562 WMITLV_SET_HDR(&cmd->tlv_header, 6563 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 6564 WMITLV_GET_STRUCT_TLVLEN( 6565 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 6566 cmd->vdev_id = param->vdev_id; 6567 cmd->tx_aggr_size = param->tx_aggr_size; 6568 cmd->rx_aggr_size = param->rx_aggr_size; 6569 copy_custom_aggr_bitmap(param, cmd); 6570 6571 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 6572 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 6573 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 6574 "tx_ac_enable=0x%X", 6575 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 6576 param->ac, param->aggr_type, param->tx_aggr_size_disable, 6577 param->rx_aggr_size_disable, param->tx_ac_enable); 6578 6579 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 6580 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6581 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 6582 wmi_err("Setting custom aggregation size failed"); 6583 wmi_buf_free(buf); 6584 return QDF_STATUS_E_FAILURE; 6585 } 6586 6587 return QDF_STATUS_SUCCESS; 6588 } 6589 6590 /** 6591 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 6592 * @param wmi_handle : handle to WMI. 6593 * @param param : pointer to tx antenna param 6594 * 6595 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6596 */ 6597 6598 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6599 struct set_qdepth_thresh_params *param) 6600 { 6601 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 6602 wmi_msduq_qdepth_thresh_update *cmd_update; 6603 wmi_buf_t buf; 6604 int32_t len = 0; 6605 int i; 6606 uint8_t *buf_ptr; 6607 QDF_STATUS ret; 6608 6609 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 6610 wmi_err("Invalid Update Count!"); 6611 return QDF_STATUS_E_INVAL; 6612 } 6613 6614 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 6615 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 6616 param->num_of_msduq_updates); 6617 buf = wmi_buf_alloc(wmi_handle, len); 6618 6619 if (!buf) 6620 return QDF_STATUS_E_NOMEM; 6621 6622 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6623 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 6624 buf_ptr; 6625 6626 WMITLV_SET_HDR(&cmd->tlv_header, 6627 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 6628 , WMITLV_GET_STRUCT_TLVLEN( 6629 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 6630 6631 cmd->pdev_id = 6632 wmi_handle->ops->convert_pdev_id_host_to_target( 6633 wmi_handle, 6634 param->pdev_id); 6635 cmd->vdev_id = param->vdev_id; 6636 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 6637 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 6638 6639 buf_ptr += sizeof( 6640 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 6641 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6642 param->num_of_msduq_updates * 6643 sizeof(wmi_msduq_qdepth_thresh_update)); 6644 buf_ptr += WMI_TLV_HDR_SIZE; 6645 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 6646 6647 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 6648 WMITLV_SET_HDR(&cmd_update->tlv_header, 6649 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 6650 WMITLV_GET_STRUCT_TLVLEN( 6651 wmi_msduq_qdepth_thresh_update)); 6652 cmd_update->tid_num = param->update_params[i].tid_num; 6653 cmd_update->msduq_update_mask = 6654 param->update_params[i].msduq_update_mask; 6655 cmd_update->qdepth_thresh_value = 6656 param->update_params[i].qdepth_thresh_value; 6657 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 6658 "mac_addr_upper4=%X, mac_addr_lower2:%X," 6659 " update mask=0x%X thresh val=0x%X", 6660 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 6661 cmd->peer_mac_address.mac_addr31to0, 6662 cmd->peer_mac_address.mac_addr47to32, 6663 cmd_update->msduq_update_mask, 6664 cmd_update->qdepth_thresh_value); 6665 cmd_update++; 6666 } 6667 6668 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 6669 cmd->vdev_id, 0); 6670 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6671 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 6672 6673 if (ret != 0) { 6674 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 6675 wmi_buf_free(buf); 6676 } 6677 6678 return ret; 6679 } 6680 6681 /** 6682 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 6683 * @wmi_handle: wmi handle 6684 * @param: pointer to hold vap dscp tid map param 6685 * 6686 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6687 */ 6688 static QDF_STATUS 6689 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 6690 struct vap_dscp_tid_map_params *param) 6691 { 6692 wmi_buf_t buf; 6693 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 6694 int32_t len = sizeof(*cmd); 6695 6696 buf = wmi_buf_alloc(wmi_handle, len); 6697 if (!buf) 6698 return QDF_STATUS_E_FAILURE; 6699 6700 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 6701 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 6702 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 6703 6704 cmd->vdev_id = param->vdev_id; 6705 cmd->enable_override = 0; 6706 6707 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 6708 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 6709 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6710 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 6711 wmi_err("Failed to set dscp cmd"); 6712 wmi_buf_free(buf); 6713 return QDF_STATUS_E_FAILURE; 6714 } 6715 6716 return QDF_STATUS_SUCCESS; 6717 } 6718 6719 /** 6720 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 6721 * @wmi_handle: wmi handle 6722 * @param: pointer to hold fwtest param 6723 * 6724 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6725 */ 6726 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 6727 struct set_fwtest_params *param) 6728 { 6729 wmi_fwtest_set_param_cmd_fixed_param *cmd; 6730 wmi_buf_t buf; 6731 int32_t len = sizeof(*cmd); 6732 6733 buf = wmi_buf_alloc(wmi_handle, len); 6734 6735 if (!buf) 6736 return QDF_STATUS_E_FAILURE; 6737 6738 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 6739 WMITLV_SET_HDR(&cmd->tlv_header, 6740 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 6741 WMITLV_GET_STRUCT_TLVLEN( 6742 wmi_fwtest_set_param_cmd_fixed_param)); 6743 cmd->param_id = param->arg; 6744 cmd->param_value = param->value; 6745 6746 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 6747 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 6748 wmi_err("Setting FW test param failed"); 6749 wmi_buf_free(buf); 6750 return QDF_STATUS_E_FAILURE; 6751 } 6752 6753 return QDF_STATUS_SUCCESS; 6754 } 6755 6756 /** 6757 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 6758 * 6759 * @param wmi_handle : handle to WMI. 6760 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6761 */ 6762 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 6763 { 6764 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 6765 wmi_buf_t buf; 6766 QDF_STATUS ret; 6767 int32_t len; 6768 6769 len = sizeof(*cmd); 6770 6771 buf = wmi_buf_alloc(wmi_handle, len); 6772 if (!buf) 6773 return QDF_STATUS_E_FAILURE; 6774 6775 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 6776 WMITLV_SET_HDR(&cmd->tlv_header, 6777 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 6778 WMITLV_GET_STRUCT_TLVLEN( 6779 wmi_pdev_dfs_disable_cmd_fixed_param)); 6780 /* Filling it with WMI_PDEV_ID_SOC for now */ 6781 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6782 wmi_handle, 6783 WMI_HOST_PDEV_ID_SOC); 6784 6785 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 6786 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6787 WMI_PDEV_DFS_DISABLE_CMDID); 6788 6789 if (ret != 0) { 6790 wmi_err("Sending PDEV DFS disable cmd failed"); 6791 wmi_buf_free(buf); 6792 } 6793 6794 return ret; 6795 } 6796 6797 /** 6798 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 6799 * 6800 * @param wmi_handle : handle to WMI. 6801 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6802 */ 6803 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 6804 { 6805 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 6806 wmi_buf_t buf; 6807 QDF_STATUS ret; 6808 int32_t len; 6809 6810 len = sizeof(*cmd); 6811 6812 buf = wmi_buf_alloc(wmi_handle, len); 6813 if (!buf) 6814 return QDF_STATUS_E_FAILURE; 6815 6816 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 6817 WMITLV_SET_HDR(&cmd->tlv_header, 6818 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 6819 WMITLV_GET_STRUCT_TLVLEN( 6820 wmi_pdev_dfs_enable_cmd_fixed_param)); 6821 /* Reserved for future use */ 6822 cmd->reserved0 = 0; 6823 6824 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 6825 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6826 WMI_PDEV_DFS_ENABLE_CMDID); 6827 6828 if (ret != 0) { 6829 wmi_err("Sending PDEV DFS enable cmd failed"); 6830 wmi_buf_free(buf); 6831 } 6832 6833 return ret; 6834 } 6835 6836 /** 6837 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 6838 * to fw 6839 * @wmi_handle: wmi handle 6840 * @param: pointer to hold periodic chan stats param 6841 * 6842 * Return: 0 for success or error code 6843 */ 6844 static QDF_STATUS 6845 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 6846 struct periodic_chan_stats_params *param) 6847 { 6848 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 6849 wmi_buf_t buf; 6850 QDF_STATUS ret; 6851 int32_t len; 6852 6853 len = sizeof(*cmd); 6854 6855 buf = wmi_buf_alloc(wmi_handle, len); 6856 if (!buf) 6857 return QDF_STATUS_E_FAILURE; 6858 6859 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 6860 wmi_buf_data(buf); 6861 WMITLV_SET_HDR(&cmd->tlv_header, 6862 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 6863 WMITLV_GET_STRUCT_TLVLEN( 6864 wmi_set_periodic_channel_stats_config_fixed_param)); 6865 cmd->enable = param->enable; 6866 cmd->stats_period = param->stats_period; 6867 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6868 wmi_handle, 6869 param->pdev_id); 6870 6871 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 6872 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6873 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 6874 6875 if (ret != 0) { 6876 wmi_err("Sending periodic chan stats config failed"); 6877 wmi_buf_free(buf); 6878 } 6879 6880 return ret; 6881 } 6882 6883 #ifdef WLAN_IOT_SIM_SUPPORT 6884 /** 6885 * send_simulation_test_cmd_tlv() - send simulation test command to fw 6886 * 6887 * @wmi_handle: wmi handle 6888 * @param: pointer to hold simulation test parameter 6889 * 6890 * Return: 0 for success or error code 6891 */ 6892 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 6893 struct simulation_test_params 6894 *param) 6895 { 6896 wmi_simulation_test_cmd_fixed_param *cmd; 6897 u32 wmi_buf_len; 6898 wmi_buf_t buf; 6899 u8 *buf_ptr; 6900 u32 aligned_len = 0; 6901 6902 wmi_buf_len = sizeof(*cmd); 6903 if (param->buf_len) { 6904 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 6905 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 6906 } 6907 6908 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6909 if (!buf) { 6910 wmi_err("wmi_buf_alloc failed"); 6911 return QDF_STATUS_E_NOMEM; 6912 } 6913 6914 buf_ptr = wmi_buf_data(buf); 6915 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 6916 WMITLV_SET_HDR(&cmd->tlv_header, 6917 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 6918 WMITLV_GET_STRUCT_TLVLEN( 6919 wmi_simulation_test_cmd_fixed_param)); 6920 cmd->pdev_id = param->pdev_id; 6921 cmd->vdev_id = param->vdev_id; 6922 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 6923 cmd->test_cmd_type = param->test_cmd_type; 6924 cmd->test_subcmd_type = param->test_subcmd_type; 6925 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 6926 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 6927 param->frame_subtype); 6928 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 6929 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 6930 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 6931 cmd->buf_len = param->buf_len; 6932 6933 if (param->buf_len) { 6934 buf_ptr += sizeof(*cmd); 6935 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 6936 buf_ptr += WMI_TLV_HDR_SIZE; 6937 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 6938 } 6939 6940 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 6941 WMI_SIMULATION_TEST_CMDID)) { 6942 wmi_err("Failed to send test simulation cmd"); 6943 wmi_buf_free(buf); 6944 return QDF_STATUS_E_FAILURE; 6945 } 6946 6947 return QDF_STATUS_SUCCESS; 6948 } 6949 #endif 6950 6951 /** 6952 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 6953 * command to fw 6954 * @wmi_handle: wmi handle 6955 * @param: pointer to hold spectral config parameter 6956 * 6957 * Return: 0 for success or error code 6958 */ 6959 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 6960 struct vdev_spectral_configure_params *param) 6961 { 6962 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 6963 wmi_buf_t buf; 6964 QDF_STATUS ret; 6965 int32_t len; 6966 6967 len = sizeof(*cmd); 6968 buf = wmi_buf_alloc(wmi_handle, len); 6969 if (!buf) 6970 return QDF_STATUS_E_FAILURE; 6971 6972 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 6973 WMITLV_SET_HDR(&cmd->tlv_header, 6974 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 6975 WMITLV_GET_STRUCT_TLVLEN( 6976 wmi_vdev_spectral_configure_cmd_fixed_param)); 6977 6978 cmd->vdev_id = param->vdev_id; 6979 cmd->spectral_scan_count = param->count; 6980 cmd->spectral_scan_period = param->period; 6981 cmd->spectral_scan_priority = param->spectral_pri; 6982 cmd->spectral_scan_fft_size = param->fft_size; 6983 cmd->spectral_scan_gc_ena = param->gc_enable; 6984 cmd->spectral_scan_restart_ena = param->restart_enable; 6985 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 6986 cmd->spectral_scan_init_delay = param->init_delay; 6987 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 6988 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 6989 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 6990 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 6991 cmd->spectral_scan_rssi_thr = param->rssi_thr; 6992 cmd->spectral_scan_pwr_format = param->pwr_format; 6993 cmd->spectral_scan_rpt_mode = param->rpt_mode; 6994 cmd->spectral_scan_bin_scale = param->bin_scale; 6995 cmd->spectral_scan_dBm_adj = param->dbm_adj; 6996 cmd->spectral_scan_chn_mask = param->chn_mask; 6997 cmd->spectral_scan_mode = param->mode; 6998 cmd->spectral_scan_center_freq1 = param->center_freq1; 6999 cmd->spectral_scan_center_freq2 = param->center_freq2; 7000 cmd->spectral_scan_chan_width = param->chan_width; 7001 /* Not used, fill with zeros */ 7002 cmd->spectral_scan_chan_freq = 0; 7003 7004 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 7005 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7006 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 7007 7008 if (ret != 0) { 7009 wmi_err("Sending set quiet cmd failed"); 7010 wmi_buf_free(buf); 7011 } 7012 7013 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 7014 wmi_debug("vdev_id: %u spectral_scan_count: %u", 7015 param->vdev_id, param->count); 7016 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 7017 param->period, param->spectral_pri); 7018 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 7019 param->fft_size, param->gc_enable); 7020 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 7021 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 7022 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 7023 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 7024 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 7025 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 7026 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 7027 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 7028 param->rssi_thr, param->pwr_format); 7029 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 7030 param->rpt_mode, param->bin_scale); 7031 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 7032 param->dbm_adj, param->chn_mask); 7033 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 7034 param->mode, param->center_freq1); 7035 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 7036 param->center_freq2, param->chan_freq); 7037 wmi_debug("spectral_scan_chan_width: %u Status: %d", 7038 param->chan_width, ret); 7039 7040 return ret; 7041 } 7042 7043 /** 7044 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 7045 * command to fw 7046 * @wmi_handle: wmi handle 7047 * @param: pointer to hold spectral enable parameter 7048 * 7049 * Return: 0 for success or error code 7050 */ 7051 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 7052 struct vdev_spectral_enable_params *param) 7053 { 7054 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 7055 wmi_buf_t buf; 7056 QDF_STATUS ret; 7057 int32_t len; 7058 7059 len = sizeof(*cmd); 7060 buf = wmi_buf_alloc(wmi_handle, len); 7061 if (!buf) 7062 return QDF_STATUS_E_FAILURE; 7063 7064 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 7065 WMITLV_SET_HDR(&cmd->tlv_header, 7066 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 7067 WMITLV_GET_STRUCT_TLVLEN( 7068 wmi_vdev_spectral_enable_cmd_fixed_param)); 7069 7070 cmd->vdev_id = param->vdev_id; 7071 7072 if (param->active_valid) { 7073 cmd->trigger_cmd = param->active ? 1 : 2; 7074 /* 1: Trigger, 2: Clear Trigger */ 7075 } else { 7076 cmd->trigger_cmd = 0; /* 0: Ignore */ 7077 } 7078 7079 if (param->enabled_valid) { 7080 cmd->enable_cmd = param->enabled ? 1 : 2; 7081 /* 1: Enable 2: Disable */ 7082 } else { 7083 cmd->enable_cmd = 0; /* 0: Ignore */ 7084 } 7085 cmd->spectral_scan_mode = param->mode; 7086 7087 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 7088 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 7089 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 7090 7091 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 7092 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7093 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 7094 7095 if (ret != 0) { 7096 wmi_err("Sending scan enable CMD failed"); 7097 wmi_buf_free(buf); 7098 } 7099 7100 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 7101 ret); 7102 7103 return ret; 7104 } 7105 7106 #ifdef WLAN_CONV_SPECTRAL_ENABLE 7107 static QDF_STATUS 7108 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 7109 wmi_unified_t wmi_handle, 7110 uint8_t *event, struct spectral_startscan_resp_params *param) 7111 { 7112 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7113 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 7114 7115 if (!wmi_handle) { 7116 wmi_err("WMI handle is null"); 7117 return QDF_STATUS_E_INVAL; 7118 } 7119 7120 if (!event) { 7121 wmi_err("WMI event is null"); 7122 return QDF_STATUS_E_INVAL; 7123 } 7124 7125 if (!param) { 7126 wmi_err("Spectral startscan response params is null"); 7127 return QDF_STATUS_E_INVAL; 7128 } 7129 7130 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7131 if (!param_buf) 7132 return QDF_STATUS_E_INVAL; 7133 7134 ev = param_buf->fixed_param; 7135 if (!ev) 7136 return QDF_STATUS_E_INVAL; 7137 7138 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 7139 wmi_handle, 7140 ev->pdev_id); 7141 param->smode = ev->spectral_scan_mode; 7142 param->num_fft_bin_index = param_buf->num_fft_bin_index; 7143 wmi_debug("pdev id %u scan mode %u num_fft_bin_index %u", 7144 param->pdev_id, param->smode, param->num_fft_bin_index); 7145 7146 return QDF_STATUS_SUCCESS; 7147 } 7148 7149 static QDF_STATUS 7150 extract_pdev_sscan_fft_bin_index_tlv( 7151 wmi_unified_t wmi_handle, uint8_t *event, 7152 struct spectral_fft_bin_markers_160_165mhz *param) 7153 { 7154 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 7155 wmi_pdev_sscan_fft_bin_index *ev; 7156 7157 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 7158 if (!param_buf) 7159 return QDF_STATUS_E_INVAL; 7160 7161 ev = param_buf->fft_bin_index; 7162 if (!ev) 7163 return QDF_STATUS_E_INVAL; 7164 7165 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 7166 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 7167 param->start_pri80 + 1; 7168 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 7169 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 7170 param->start_sec80 + 1; 7171 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 7172 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 7173 param->start_5mhz + 1; 7174 param->is_valid = true; 7175 7176 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 7177 param->start_pri80, param->num_pri80, 7178 param->start_sec80, param->num_sec80, 7179 param->start_5mhz, param->num_5mhz); 7180 7181 return QDF_STATUS_SUCCESS; 7182 } 7183 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 7184 7185 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 7186 static inline void 7187 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 7188 struct thermal_mitigation_params *param) 7189 { 7190 tt_conf->client_id = param->client_id; 7191 tt_conf->priority = param->priority; 7192 } 7193 #else 7194 static inline void 7195 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 7196 struct thermal_mitigation_params *param) 7197 { 7198 } 7199 #endif 7200 7201 /** 7202 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 7203 * @param wmi_handle : handle to WMI. 7204 * @param param : pointer to hold thermal mitigation param 7205 * 7206 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 7207 */ 7208 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 7209 wmi_unified_t wmi_handle, 7210 struct thermal_mitigation_params *param) 7211 { 7212 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 7213 wmi_therm_throt_level_config_info *lvl_conf = NULL; 7214 wmi_buf_t buf = NULL; 7215 uint8_t *buf_ptr = NULL; 7216 int error; 7217 int32_t len; 7218 int i; 7219 7220 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 7221 param->num_thermal_conf * 7222 sizeof(wmi_therm_throt_level_config_info); 7223 7224 buf = wmi_buf_alloc(wmi_handle, len); 7225 if (!buf) 7226 return QDF_STATUS_E_NOMEM; 7227 7228 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 7229 7230 /* init fixed params */ 7231 WMITLV_SET_HDR(tt_conf, 7232 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 7233 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 7234 7235 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7236 wmi_handle, 7237 param->pdev_id); 7238 tt_conf->enable = param->enable; 7239 tt_conf->dc = param->dc; 7240 tt_conf->dc_per_event = param->dc_per_event; 7241 tt_conf->therm_throt_levels = param->num_thermal_conf; 7242 wmi_fill_client_id_priority(tt_conf, param); 7243 buf_ptr = (uint8_t *) ++tt_conf; 7244 /* init TLV params */ 7245 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7246 (param->num_thermal_conf * 7247 sizeof(wmi_therm_throt_level_config_info))); 7248 7249 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 7250 for (i = 0; i < param->num_thermal_conf; i++) { 7251 WMITLV_SET_HDR(&lvl_conf->tlv_header, 7252 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 7253 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 7254 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 7255 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 7256 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 7257 lvl_conf->prio = param->levelconf[i].priority; 7258 lvl_conf++; 7259 } 7260 7261 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 7262 error = wmi_unified_cmd_send(wmi_handle, buf, len, 7263 WMI_THERM_THROT_SET_CONF_CMDID); 7264 if (QDF_IS_STATUS_ERROR(error)) { 7265 wmi_buf_free(buf); 7266 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 7267 } 7268 7269 return error; 7270 } 7271 7272 /** 7273 * send_coex_config_cmd_tlv() - send coex config command to fw 7274 * @wmi_handle: wmi handle 7275 * @param: pointer to coex config param 7276 * 7277 * Return: 0 for success or error code 7278 */ 7279 static QDF_STATUS 7280 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 7281 struct coex_config_params *param) 7282 { 7283 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 7284 wmi_buf_t buf; 7285 QDF_STATUS ret; 7286 int32_t len; 7287 7288 len = sizeof(*cmd); 7289 buf = wmi_buf_alloc(wmi_handle, len); 7290 if (!buf) 7291 return QDF_STATUS_E_FAILURE; 7292 7293 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 7294 WMITLV_SET_HDR(&cmd->tlv_header, 7295 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 7296 WMITLV_GET_STRUCT_TLVLEN( 7297 WMI_COEX_CONFIG_CMD_fixed_param)); 7298 7299 cmd->vdev_id = param->vdev_id; 7300 cmd->config_type = param->config_type; 7301 cmd->config_arg1 = param->config_arg1; 7302 cmd->config_arg2 = param->config_arg2; 7303 cmd->config_arg3 = param->config_arg3; 7304 cmd->config_arg4 = param->config_arg4; 7305 cmd->config_arg5 = param->config_arg5; 7306 cmd->config_arg6 = param->config_arg6; 7307 7308 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 7309 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7310 WMI_COEX_CONFIG_CMDID); 7311 7312 if (ret != 0) { 7313 wmi_err("Sending COEX CONFIG CMD failed"); 7314 wmi_buf_free(buf); 7315 } 7316 7317 return ret; 7318 } 7319 7320 #ifdef WLAN_SUPPORT_TWT 7321 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 7322 target_resource_config *tgt_res_cfg) 7323 { 7324 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 7325 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 7326 } 7327 #else 7328 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 7329 target_resource_config *tgt_res_cfg) 7330 { 7331 resource_cfg->twt_ap_pdev_count = 0; 7332 resource_cfg->twt_ap_sta_count = 0; 7333 } 7334 #endif 7335 7336 #ifdef WLAN_FEATURE_NAN 7337 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 7338 { 7339 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 7340 resource_cfg->host_service_flags, 1); 7341 } 7342 #else 7343 static inline 7344 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 7345 { 7346 } 7347 #endif 7348 7349 static 7350 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 7351 target_resource_config *tgt_res_cfg) 7352 { 7353 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 7354 resource_cfg->num_peers = tgt_res_cfg->num_peers; 7355 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 7356 resource_cfg->num_offload_reorder_buffs = 7357 tgt_res_cfg->num_offload_reorder_buffs; 7358 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 7359 resource_cfg->num_tids = tgt_res_cfg->num_tids; 7360 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 7361 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 7362 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 7363 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 7364 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 7365 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 7366 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 7367 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 7368 resource_cfg->scan_max_pending_req = 7369 tgt_res_cfg->scan_max_pending_req; 7370 resource_cfg->bmiss_offload_max_vdev = 7371 tgt_res_cfg->bmiss_offload_max_vdev; 7372 resource_cfg->roam_offload_max_vdev = 7373 tgt_res_cfg->roam_offload_max_vdev; 7374 resource_cfg->roam_offload_max_ap_profiles = 7375 tgt_res_cfg->roam_offload_max_ap_profiles; 7376 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 7377 resource_cfg->num_mcast_table_elems = 7378 tgt_res_cfg->num_mcast_table_elems; 7379 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 7380 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 7381 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 7382 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 7383 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 7384 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 7385 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 7386 resource_cfg->vow_config = tgt_res_cfg->vow_config; 7387 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 7388 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 7389 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 7390 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 7391 resource_cfg->num_tdls_conn_table_entries = 7392 tgt_res_cfg->num_tdls_conn_table_entries; 7393 resource_cfg->beacon_tx_offload_max_vdev = 7394 tgt_res_cfg->beacon_tx_offload_max_vdev; 7395 resource_cfg->num_multicast_filter_entries = 7396 tgt_res_cfg->num_multicast_filter_entries; 7397 resource_cfg->num_wow_filters = 7398 tgt_res_cfg->num_wow_filters; 7399 resource_cfg->num_keep_alive_pattern = 7400 tgt_res_cfg->num_keep_alive_pattern; 7401 resource_cfg->keep_alive_pattern_size = 7402 tgt_res_cfg->keep_alive_pattern_size; 7403 resource_cfg->max_tdls_concurrent_sleep_sta = 7404 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 7405 resource_cfg->max_tdls_concurrent_buffer_sta = 7406 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 7407 resource_cfg->wmi_send_separate = 7408 tgt_res_cfg->wmi_send_separate; 7409 resource_cfg->num_ocb_vdevs = 7410 tgt_res_cfg->num_ocb_vdevs; 7411 resource_cfg->num_ocb_channels = 7412 tgt_res_cfg->num_ocb_channels; 7413 resource_cfg->num_ocb_schedules = 7414 tgt_res_cfg->num_ocb_schedules; 7415 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 7416 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 7417 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 7418 resource_cfg->max_num_dbs_scan_duty_cycle = 7419 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 7420 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 7421 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 7422 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 7423 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 7424 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 7425 /* Deferred AI: Max rnr neighbors supported in multisoc case 7426 * where in SoC can support 6ghz. During WMI init of a SoC 7427 * currently there is no way to figure if another SOC is plugged in 7428 * and it can support 6Ghz. 7429 */ 7430 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 7431 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 7432 resource_cfg->ema_max_profile_period = 7433 tgt_res_cfg->ema_max_profile_period; 7434 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 7435 7436 if (tgt_res_cfg->max_ndp_sessions) 7437 resource_cfg->max_ndp_sessions = 7438 tgt_res_cfg->max_ndp_sessions; 7439 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 7440 7441 if (tgt_res_cfg->atf_config) 7442 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 7443 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 7444 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 7445 resource_cfg->flag1, 1); 7446 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 7447 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 7448 resource_cfg->flag1, 1); 7449 if (tgt_res_cfg->cce_disable) 7450 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 7451 if (tgt_res_cfg->enable_pci_gen) 7452 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 7453 resource_cfg->flag1, 1); 7454 if (tgt_res_cfg->eapol_minrate_set) { 7455 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 7456 resource_cfg->flag1, 1); 7457 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 7458 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 7459 resource_cfg->flag1, 1); 7460 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 7461 resource_cfg->flag1, 7462 tgt_res_cfg->eapol_minrate_ac_set); 7463 } 7464 } 7465 if (tgt_res_cfg->new_htt_msg_format) { 7466 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 7467 resource_cfg->flag1, 1); 7468 } 7469 7470 if (tgt_res_cfg->peer_unmap_conf_support) 7471 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 7472 resource_cfg->flag1, 1); 7473 7474 if (tgt_res_cfg->tstamp64_en) 7475 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 7476 resource_cfg->flag1, 1); 7477 7478 if (tgt_res_cfg->three_way_coex_config_legacy_en) 7479 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 7480 resource_cfg->flag1, 1); 7481 if (tgt_res_cfg->pktcapture_support) 7482 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 7483 resource_cfg->flag1, 1); 7484 7485 /* 7486 * Control padding using config param/ini of iphdr_pad_config 7487 */ 7488 if (tgt_res_cfg->iphdr_pad_config) 7489 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 7490 resource_cfg->flag1, 1); 7491 7492 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 7493 tgt_res_cfg->ipa_disable); 7494 7495 if (tgt_res_cfg->time_sync_ftm) 7496 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 7497 1); 7498 7499 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 7500 resource_cfg->peer_map_unmap_v2_support = 7501 tgt_res_cfg->peer_map_unmap_v2; 7502 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 7503 if (tgt_res_cfg->re_ul_resp) 7504 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 7505 tgt_res_cfg->re_ul_resp); 7506 7507 7508 /* 7509 * Enable ast flow override per peer 7510 */ 7511 resource_cfg->msdu_flow_override_config0 = 0; 7512 WMI_MSDU_FLOW_AST_ENABLE_SET( 7513 resource_cfg->msdu_flow_override_config0, 7514 WMI_CONFIG_MSDU_AST_INDEX_1, 7515 tgt_res_cfg->ast_1_valid_mask_enable); 7516 7517 WMI_MSDU_FLOW_AST_ENABLE_SET( 7518 resource_cfg->msdu_flow_override_config0, 7519 WMI_CONFIG_MSDU_AST_INDEX_2, 7520 tgt_res_cfg->ast_2_valid_mask_enable); 7521 7522 WMI_MSDU_FLOW_AST_ENABLE_SET( 7523 resource_cfg->msdu_flow_override_config0, 7524 WMI_CONFIG_MSDU_AST_INDEX_3, 7525 tgt_res_cfg->ast_3_valid_mask_enable); 7526 7527 /* 7528 * Enable ast flow mask and TID valid mask configurations 7529 */ 7530 resource_cfg->msdu_flow_override_config1 = 0; 7531 7532 /*Enable UDP flow for Ast index 0*/ 7533 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7534 resource_cfg->msdu_flow_override_config1, 7535 WMI_CONFIG_MSDU_AST_INDEX_0, 7536 tgt_res_cfg->ast_0_flow_mask_enable); 7537 7538 /*Enable Non UDP flow for Ast index 1*/ 7539 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7540 resource_cfg->msdu_flow_override_config1, 7541 WMI_CONFIG_MSDU_AST_INDEX_1, 7542 tgt_res_cfg->ast_1_flow_mask_enable); 7543 7544 /*Enable Hi-Priority flow for Ast index 2*/ 7545 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7546 resource_cfg->msdu_flow_override_config1, 7547 WMI_CONFIG_MSDU_AST_INDEX_2, 7548 tgt_res_cfg->ast_2_flow_mask_enable); 7549 7550 /*Enable Low-Priority flow for Ast index 3*/ 7551 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7552 resource_cfg->msdu_flow_override_config1, 7553 WMI_CONFIG_MSDU_AST_INDEX_3, 7554 tgt_res_cfg->ast_3_flow_mask_enable); 7555 7556 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 7557 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 7558 resource_cfg->msdu_flow_override_config1, 7559 tgt_res_cfg->ast_tid_high_mask_enable); 7560 7561 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 7562 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 7563 resource_cfg->msdu_flow_override_config1, 7564 tgt_res_cfg->ast_tid_low_mask_enable); 7565 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 7566 resource_cfg->host_service_flags, 7567 tgt_res_cfg->nan_separate_iface_support); 7568 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 7569 resource_cfg->host_service_flags, 1); 7570 7571 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 7572 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 7573 7574 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 7575 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 7576 resource_cfg->flags2, 1); 7577 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 7578 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 7579 resource_cfg->flags2, 1); 7580 7581 if (tgt_res_cfg->sae_eapol_offload) 7582 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 7583 resource_cfg->host_service_flags, 1); 7584 7585 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 7586 resource_cfg->host_service_flags, 7587 tgt_res_cfg->is_reg_cc_ext_event_supported); 7588 7589 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 7590 resource_cfg->host_service_flags, 7591 tgt_res_cfg->lpi_only_mode); 7592 7593 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 7594 resource_cfg->host_service_flags, 7595 tgt_res_cfg->afc_timer_check_disable); 7596 7597 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 7598 resource_cfg->host_service_flags, 7599 tgt_res_cfg->afc_req_id_check_disable); 7600 7601 wmi_set_nan_channel_support(resource_cfg); 7602 7603 wmi_info("Enable dynamic PCIe gen speed: %d", 7604 tgt_res_cfg->dynamic_pcie_gen_speed_change); 7605 7606 WMI_RSRC_CFG_FLAGS2_IS_DYNAMIC_PCIE_GEN_SPEED_SWITCH_ENABLED_SET(resource_cfg->flags2, tgt_res_cfg->dynamic_pcie_gen_speed_change); 7607 7608 if (tgt_res_cfg->twt_ack_support_cap) 7609 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 7610 resource_cfg->host_service_flags, 1); 7611 7612 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, 7613 tgt_res_cfg->target_cap_flags); 7614 } 7615 7616 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 7617 * @wmi_handle: pointer to wmi handle 7618 * @buf_ptr: pointer to current position in init command buffer 7619 * @len: pointer to length. This will be updated with current length of cmd 7620 * @param: point host parameters for init command 7621 * 7622 * Return: Updated pointer of buf_ptr. 7623 */ 7624 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 7625 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 7626 { 7627 uint16_t idx; 7628 7629 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 7630 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 7631 wmi_pdev_band_to_mac *band_to_mac; 7632 7633 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 7634 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 7635 sizeof(wmi_resource_config) + 7636 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 7637 sizeof(wlan_host_memory_chunk))); 7638 7639 WMITLV_SET_HDR(&hw_mode->tlv_header, 7640 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 7641 (WMITLV_GET_STRUCT_TLVLEN 7642 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 7643 7644 hw_mode->hw_mode_index = param->hw_mode_id; 7645 hw_mode->num_band_to_mac = param->num_band_to_mac; 7646 7647 buf_ptr = (uint8_t *) (hw_mode + 1); 7648 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 7649 WMI_TLV_HDR_SIZE); 7650 for (idx = 0; idx < param->num_band_to_mac; idx++) { 7651 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 7652 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 7653 WMITLV_GET_STRUCT_TLVLEN 7654 (wmi_pdev_band_to_mac)); 7655 band_to_mac[idx].pdev_id = 7656 wmi_handle->ops->convert_pdev_id_host_to_target( 7657 wmi_handle, 7658 param->band_to_mac[idx].pdev_id); 7659 band_to_mac[idx].start_freq = 7660 param->band_to_mac[idx].start_freq; 7661 band_to_mac[idx].end_freq = 7662 param->band_to_mac[idx].end_freq; 7663 } 7664 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 7665 (param->num_band_to_mac * 7666 sizeof(wmi_pdev_band_to_mac)) + 7667 WMI_TLV_HDR_SIZE; 7668 7669 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7670 (param->num_band_to_mac * 7671 sizeof(wmi_pdev_band_to_mac))); 7672 } 7673 7674 return buf_ptr; 7675 } 7676 7677 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 7678 wmi_init_cmd_fixed_param *cmd) 7679 { 7680 int num_whitelist; 7681 wmi_abi_version my_vers; 7682 7683 num_whitelist = sizeof(version_whitelist) / 7684 sizeof(wmi_whitelist_version_info); 7685 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 7686 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 7687 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 7688 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 7689 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 7690 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 7691 7692 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 7693 &my_vers, 7694 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 7695 &cmd->host_abi_vers); 7696 7697 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 7698 __func__, 7699 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 7700 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 7701 cmd->host_abi_vers.abi_version_ns_0, 7702 cmd->host_abi_vers.abi_version_ns_1, 7703 cmd->host_abi_vers.abi_version_ns_2, 7704 cmd->host_abi_vers.abi_version_ns_3); 7705 7706 /* Save version sent from host - 7707 * Will be used to check ready event 7708 */ 7709 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 7710 sizeof(wmi_abi_version)); 7711 } 7712 7713 /* 7714 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 7715 * @wmi_handle: Pointer to WMi handle 7716 * @ie_data: Pointer for ie data 7717 * 7718 * This function sends action frame tb ppdu cfg to FW 7719 * 7720 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7721 * 7722 */ 7723 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 7724 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 7725 { 7726 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 7727 wmi_buf_t buf; 7728 uint8_t *buf_ptr; 7729 uint32_t len, frm_len_aligned; 7730 QDF_STATUS ret; 7731 7732 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 7733 /* Allocate memory for the WMI command */ 7734 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 7735 7736 buf = wmi_buf_alloc(wmi_handle, len); 7737 if (!buf) 7738 return QDF_STATUS_E_NOMEM; 7739 7740 buf_ptr = wmi_buf_data(buf); 7741 qdf_mem_zero(buf_ptr, len); 7742 7743 /* Populate the WMI command */ 7744 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 7745 7746 WMITLV_SET_HDR(&cmd->tlv_header, 7747 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 7748 WMITLV_GET_STRUCT_TLVLEN( 7749 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 7750 cmd->enable = cfg_msg->cfg; 7751 cmd->data_len = cfg_msg->frm_len; 7752 7753 buf_ptr += sizeof(*cmd); 7754 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 7755 buf_ptr += WMI_TLV_HDR_SIZE; 7756 7757 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 7758 7759 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7760 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 7761 if (QDF_IS_STATUS_ERROR(ret)) { 7762 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 7763 wmi_buf_free(buf); 7764 } 7765 7766 return ret; 7767 } 7768 7769 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 7770 { 7771 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7772 wmi_service_ready_event_fixed_param *ev; 7773 7774 7775 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7776 7777 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7778 if (!ev) 7779 return QDF_STATUS_E_FAILURE; 7780 7781 /*Save fw version from service ready message */ 7782 /*This will be used while sending INIT message */ 7783 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7784 sizeof(wmi_handle->fw_abi_version)); 7785 7786 return QDF_STATUS_SUCCESS; 7787 } 7788 7789 /** 7790 * wmi_unified_save_fw_version_cmd() - save fw version 7791 * @wmi_handle: pointer to wmi handle 7792 * @res_cfg: resource config 7793 * @num_mem_chunks: no of mem chunck 7794 * @mem_chunk: pointer to mem chunck structure 7795 * 7796 * This function sends IE information to firmware 7797 * 7798 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7799 * 7800 */ 7801 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 7802 void *evt_buf) 7803 { 7804 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7805 wmi_ready_event_fixed_param *ev = NULL; 7806 7807 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7808 ev = param_buf->fixed_param; 7809 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 7810 &wmi_handle->final_abi_vers, 7811 &ev->fw_abi_vers)) { 7812 /* 7813 * Error: Our host version and the given firmware version 7814 * are incompatible. 7815 **/ 7816 wmi_debug("Error: Incompatible WMI version." 7817 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 7818 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 7819 abi_version_0), 7820 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 7821 abi_version_0), 7822 wmi_handle->final_abi_vers.abi_version_ns_0, 7823 wmi_handle->final_abi_vers.abi_version_ns_1, 7824 wmi_handle->final_abi_vers.abi_version_ns_2, 7825 wmi_handle->final_abi_vers.abi_version_ns_3, 7826 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 7827 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 7828 ev->fw_abi_vers.abi_version_ns_0, 7829 ev->fw_abi_vers.abi_version_ns_1, 7830 ev->fw_abi_vers.abi_version_ns_2, 7831 ev->fw_abi_vers.abi_version_ns_3); 7832 7833 return QDF_STATUS_E_FAILURE; 7834 } 7835 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 7836 sizeof(wmi_abi_version)); 7837 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7838 sizeof(wmi_abi_version)); 7839 7840 return QDF_STATUS_SUCCESS; 7841 } 7842 7843 /** 7844 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 7845 * @handle: wmi handle 7846 * @event: Event received from FW 7847 * @len: Length of the event 7848 * 7849 * Enables the low frequency events and disables the high frequency 7850 * events. Bit 17 indicates if the event if low/high frequency. 7851 * 1 - high frequency, 0 - low frequency 7852 * 7853 * Return: 0 on successfully enabling/disabling the events 7854 */ 7855 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 7856 uint8_t *event, 7857 uint32_t len) 7858 { 7859 uint32_t num_of_diag_events_logs; 7860 wmi_diag_event_log_config_fixed_param *cmd; 7861 wmi_buf_t buf; 7862 uint8_t *buf_ptr; 7863 uint32_t *cmd_args, *evt_args; 7864 uint32_t buf_len, i; 7865 7866 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 7867 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 7868 7869 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 7870 7871 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 7872 if (!param_buf) { 7873 wmi_err("Invalid log supported event buffer"); 7874 return QDF_STATUS_E_INVAL; 7875 } 7876 wmi_event = param_buf->fixed_param; 7877 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 7878 7879 if (num_of_diag_events_logs > 7880 param_buf->num_diag_events_logs_list) { 7881 wmi_err("message number of events %d is more than tlv hdr content %d", 7882 num_of_diag_events_logs, 7883 param_buf->num_diag_events_logs_list); 7884 return QDF_STATUS_E_INVAL; 7885 } 7886 7887 evt_args = param_buf->diag_events_logs_list; 7888 if (!evt_args) { 7889 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 7890 num_of_diag_events_logs); 7891 return QDF_STATUS_E_INVAL; 7892 } 7893 7894 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 7895 7896 /* Free any previous allocation */ 7897 if (wmi_handle->events_logs_list) { 7898 qdf_mem_free(wmi_handle->events_logs_list); 7899 wmi_handle->events_logs_list = NULL; 7900 } 7901 7902 if (num_of_diag_events_logs > 7903 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 7904 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 7905 QDF_ASSERT(0); 7906 return QDF_STATUS_E_INVAL; 7907 } 7908 /* Store the event list for run time enable/disable */ 7909 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 7910 sizeof(uint32_t)); 7911 if (!wmi_handle->events_logs_list) 7912 return QDF_STATUS_E_NOMEM; 7913 7914 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 7915 7916 /* Prepare the send buffer */ 7917 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7918 (num_of_diag_events_logs * sizeof(uint32_t)); 7919 7920 buf = wmi_buf_alloc(wmi_handle, buf_len); 7921 if (!buf) { 7922 qdf_mem_free(wmi_handle->events_logs_list); 7923 wmi_handle->events_logs_list = NULL; 7924 return QDF_STATUS_E_NOMEM; 7925 } 7926 7927 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7928 buf_ptr = (uint8_t *) cmd; 7929 7930 WMITLV_SET_HDR(&cmd->tlv_header, 7931 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7932 WMITLV_GET_STRUCT_TLVLEN( 7933 wmi_diag_event_log_config_fixed_param)); 7934 7935 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 7936 7937 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7938 7939 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7940 (num_of_diag_events_logs * sizeof(uint32_t))); 7941 7942 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7943 7944 /* Populate the events */ 7945 for (i = 0; i < num_of_diag_events_logs; i++) { 7946 /* Low freq (0) - Enable (1) the event 7947 * High freq (1) - Disable (0) the event 7948 */ 7949 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 7950 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 7951 /* Set the event ID */ 7952 WMI_DIAG_ID_SET(cmd_args[i], 7953 WMI_DIAG_ID_GET(evt_args[i])); 7954 /* Set the type */ 7955 WMI_DIAG_TYPE_SET(cmd_args[i], 7956 WMI_DIAG_TYPE_GET(evt_args[i])); 7957 /* Storing the event/log list in WMI */ 7958 wmi_handle->events_logs_list[i] = evt_args[i]; 7959 } 7960 7961 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7962 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 7963 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7964 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 7965 wmi_buf_free(buf); 7966 /* Not clearing events_logs_list, though wmi cmd failed. 7967 * Host can still have this list 7968 */ 7969 return QDF_STATUS_E_INVAL; 7970 } 7971 7972 return 0; 7973 } 7974 7975 /** 7976 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 7977 * @wmi_handle: wmi handle 7978 * @start_log: Start logging related parameters 7979 * 7980 * Send the command to the FW based on which specific logging of diag 7981 * event/log id can be started/stopped 7982 * 7983 * Return: None 7984 */ 7985 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 7986 struct wmi_wifi_start_log *start_log) 7987 { 7988 wmi_diag_event_log_config_fixed_param *cmd; 7989 wmi_buf_t buf; 7990 uint8_t *buf_ptr; 7991 uint32_t len, count, log_level, i; 7992 uint32_t *cmd_args; 7993 uint32_t total_len; 7994 count = 0; 7995 7996 if (!wmi_handle->events_logs_list) { 7997 wmi_debug("Not received event/log list from FW, yet"); 7998 return QDF_STATUS_E_NOMEM; 7999 } 8000 /* total_len stores the number of events where BITS 17 and 18 are set. 8001 * i.e., events of high frequency (17) and for extended debugging (18) 8002 */ 8003 total_len = 0; 8004 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8005 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 8006 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 8007 total_len++; 8008 } 8009 8010 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 8011 (total_len * sizeof(uint32_t)); 8012 8013 buf = wmi_buf_alloc(wmi_handle, len); 8014 if (!buf) 8015 return QDF_STATUS_E_NOMEM; 8016 8017 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 8018 buf_ptr = (uint8_t *) cmd; 8019 8020 WMITLV_SET_HDR(&cmd->tlv_header, 8021 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 8022 WMITLV_GET_STRUCT_TLVLEN( 8023 wmi_diag_event_log_config_fixed_param)); 8024 8025 cmd->num_of_diag_events_logs = total_len; 8026 8027 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 8028 8029 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8030 (total_len * sizeof(uint32_t))); 8031 8032 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8033 8034 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 8035 log_level = 1; 8036 else 8037 log_level = 0; 8038 8039 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 8040 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 8041 uint32_t val = wmi_handle->events_logs_list[i]; 8042 if ((WMI_DIAG_FREQUENCY_GET(val)) && 8043 (WMI_DIAG_EXT_FEATURE_GET(val))) { 8044 8045 WMI_DIAG_ID_SET(cmd_args[count], 8046 WMI_DIAG_ID_GET(val)); 8047 WMI_DIAG_TYPE_SET(cmd_args[count], 8048 WMI_DIAG_TYPE_GET(val)); 8049 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 8050 log_level); 8051 wmi_debug("Idx:%d, val:%x", i, val); 8052 count++; 8053 } 8054 } 8055 8056 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 8057 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8058 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 8059 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 8060 wmi_buf_free(buf); 8061 return QDF_STATUS_E_INVAL; 8062 } 8063 8064 return QDF_STATUS_SUCCESS; 8065 } 8066 8067 /** 8068 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 8069 * @wmi_handle: WMI handle 8070 * 8071 * This function is used to send the flush command to the FW, 8072 * that will flush the fw logs that are residue in the FW 8073 * 8074 * Return: None 8075 */ 8076 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 8077 { 8078 wmi_debug_mesg_flush_fixed_param *cmd; 8079 wmi_buf_t buf; 8080 int len = sizeof(*cmd); 8081 QDF_STATUS ret; 8082 8083 buf = wmi_buf_alloc(wmi_handle, len); 8084 if (!buf) 8085 return QDF_STATUS_E_NOMEM; 8086 8087 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 8088 WMITLV_SET_HDR(&cmd->tlv_header, 8089 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 8090 WMITLV_GET_STRUCT_TLVLEN( 8091 wmi_debug_mesg_flush_fixed_param)); 8092 cmd->reserved0 = 0; 8093 8094 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 8095 ret = wmi_unified_cmd_send(wmi_handle, 8096 buf, 8097 len, 8098 WMI_DEBUG_MESG_FLUSH_CMDID); 8099 if (QDF_IS_STATUS_ERROR(ret)) { 8100 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 8101 wmi_buf_free(buf); 8102 return QDF_STATUS_E_INVAL; 8103 } 8104 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 8105 8106 return ret; 8107 } 8108 8109 #ifdef BIG_ENDIAN_HOST 8110 /** 8111 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 8112 * @param data_len - data length 8113 * @param data - pointer to data 8114 * 8115 * Return: QDF_STATUS - success or error status 8116 */ 8117 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 8118 struct fips_params *param) 8119 { 8120 unsigned char *key_unaligned, *data_unaligned; 8121 int c; 8122 u_int8_t *key_aligned = NULL; 8123 u_int8_t *data_aligned = NULL; 8124 8125 /* Assigning unaligned space to copy the key */ 8126 key_unaligned = qdf_mem_malloc( 8127 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 8128 data_unaligned = qdf_mem_malloc( 8129 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 8130 8131 /* Checking if kmalloc is successful to allocate space */ 8132 if (!key_unaligned) 8133 return QDF_STATUS_SUCCESS; 8134 /* Checking if space is aligned */ 8135 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 8136 /* align to 4 */ 8137 key_aligned = 8138 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 8139 FIPS_ALIGN); 8140 } else { 8141 key_aligned = (u_int8_t *)key_unaligned; 8142 } 8143 8144 /* memset and copy content from key to key aligned */ 8145 OS_MEMSET(key_aligned, 0, param->key_len); 8146 OS_MEMCPY(key_aligned, param->key, param->key_len); 8147 8148 /* print a hexdump for host debug */ 8149 print_hex_dump(KERN_DEBUG, 8150 "\t Aligned and Copied Key:@@@@ ", 8151 DUMP_PREFIX_NONE, 8152 16, 1, key_aligned, param->key_len, true); 8153 8154 /* Checking if kmalloc is successful to allocate space */ 8155 if (!data_unaligned) 8156 return QDF_STATUS_SUCCESS; 8157 /* Checking of space is aligned */ 8158 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 8159 /* align to 4 */ 8160 data_aligned = 8161 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 8162 FIPS_ALIGN); 8163 } else { 8164 data_aligned = (u_int8_t *)data_unaligned; 8165 } 8166 8167 /* memset and copy content from data to data aligned */ 8168 OS_MEMSET(data_aligned, 0, param->data_len); 8169 OS_MEMCPY(data_aligned, param->data, param->data_len); 8170 8171 /* print a hexdump for host debug */ 8172 print_hex_dump(KERN_DEBUG, 8173 "\t Properly Aligned and Copied Data:@@@@ ", 8174 DUMP_PREFIX_NONE, 8175 16, 1, data_aligned, param->data_len, true); 8176 8177 /* converting to little Endian both key_aligned and 8178 * data_aligned*/ 8179 for (c = 0; c < param->key_len/4; c++) { 8180 *((u_int32_t *)key_aligned+c) = 8181 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 8182 } 8183 for (c = 0; c < param->data_len/4; c++) { 8184 *((u_int32_t *)data_aligned+c) = 8185 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 8186 } 8187 8188 /* update endian data to key and data vectors */ 8189 OS_MEMCPY(param->key, key_aligned, param->key_len); 8190 OS_MEMCPY(param->data, data_aligned, param->data_len); 8191 8192 /* clean up allocated spaces */ 8193 qdf_mem_free(key_unaligned); 8194 key_unaligned = NULL; 8195 key_aligned = NULL; 8196 8197 qdf_mem_free(data_unaligned); 8198 data_unaligned = NULL; 8199 data_aligned = NULL; 8200 8201 return QDF_STATUS_SUCCESS; 8202 } 8203 #else 8204 /** 8205 * fips_align_data_be() - DUMMY for LE platform 8206 * 8207 * Return: QDF_STATUS - success 8208 */ 8209 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 8210 struct fips_params *param) 8211 { 8212 return QDF_STATUS_SUCCESS; 8213 } 8214 #endif 8215 8216 #ifdef WLAN_FEATURE_DISA 8217 /** 8218 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 8219 * @wmi_handle: wmi handle 8220 * @params: encrypt/decrypt params 8221 * 8222 * Return: QDF_STATUS_SUCCESS for success or error code 8223 */ 8224 static QDF_STATUS 8225 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 8226 struct disa_encrypt_decrypt_req_params 8227 *encrypt_decrypt_params) 8228 { 8229 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 8230 wmi_buf_t wmi_buf; 8231 uint8_t *buf_ptr; 8232 QDF_STATUS ret; 8233 uint32_t len; 8234 8235 wmi_debug("Send encrypt decrypt cmd"); 8236 8237 len = sizeof(*cmd) + 8238 encrypt_decrypt_params->data_len + 8239 WMI_TLV_HDR_SIZE; 8240 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8241 if (!wmi_buf) 8242 return QDF_STATUS_E_NOMEM; 8243 8244 buf_ptr = wmi_buf_data(wmi_buf); 8245 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 8246 8247 WMITLV_SET_HDR(&cmd->tlv_header, 8248 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 8249 WMITLV_GET_STRUCT_TLVLEN( 8250 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 8251 8252 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 8253 cmd->key_flag = encrypt_decrypt_params->key_flag; 8254 cmd->key_idx = encrypt_decrypt_params->key_idx; 8255 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 8256 cmd->key_len = encrypt_decrypt_params->key_len; 8257 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 8258 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 8259 8260 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 8261 encrypt_decrypt_params->key_len); 8262 8263 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 8264 MAX_MAC_HEADER_LEN); 8265 8266 cmd->data_len = encrypt_decrypt_params->data_len; 8267 8268 if (cmd->data_len) { 8269 buf_ptr += sizeof(*cmd); 8270 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 8271 roundup(encrypt_decrypt_params->data_len, 8272 sizeof(uint32_t))); 8273 buf_ptr += WMI_TLV_HDR_SIZE; 8274 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 8275 encrypt_decrypt_params->data_len); 8276 } 8277 8278 /* This conversion is to facilitate data to FW in little endian */ 8279 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 8280 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 8281 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 8282 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 8283 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 8284 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 8285 8286 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 8287 ret = wmi_unified_cmd_send(wmi_handle, 8288 wmi_buf, len, 8289 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 8290 if (QDF_IS_STATUS_ERROR(ret)) { 8291 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 8292 wmi_buf_free(wmi_buf); 8293 } 8294 8295 return ret; 8296 } 8297 #endif /* WLAN_FEATURE_DISA */ 8298 8299 /** 8300 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 8301 * @wmi_handle: wmi handle 8302 * @param: pointer to hold pdev fips param 8303 * 8304 * Return: 0 for success or error code 8305 */ 8306 static QDF_STATUS 8307 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 8308 struct fips_params *param) 8309 { 8310 wmi_pdev_fips_cmd_fixed_param *cmd; 8311 wmi_buf_t buf; 8312 uint8_t *buf_ptr; 8313 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 8314 QDF_STATUS retval = QDF_STATUS_SUCCESS; 8315 8316 /* Length TLV placeholder for array of bytes */ 8317 len += WMI_TLV_HDR_SIZE; 8318 if (param->data_len) 8319 len += (param->data_len*sizeof(uint8_t)); 8320 8321 /* 8322 * Data length must be multiples of 16 bytes - checked against 0xF - 8323 * and must be less than WMI_SVC_MSG_SIZE - static size of 8324 * wmi_pdev_fips_cmd structure 8325 */ 8326 8327 /* do sanity on the input */ 8328 if (!(((param->data_len & 0xF) == 0) && 8329 ((param->data_len > 0) && 8330 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 8331 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 8332 return QDF_STATUS_E_INVAL; 8333 } 8334 8335 buf = wmi_buf_alloc(wmi_handle, len); 8336 if (!buf) 8337 return QDF_STATUS_E_FAILURE; 8338 8339 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8340 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 8341 WMITLV_SET_HDR(&cmd->tlv_header, 8342 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 8343 WMITLV_GET_STRUCT_TLVLEN 8344 (wmi_pdev_fips_cmd_fixed_param)); 8345 8346 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8347 wmi_handle, 8348 param->pdev_id); 8349 if (param->key && param->data) { 8350 cmd->key_len = param->key_len; 8351 cmd->data_len = param->data_len; 8352 cmd->fips_cmd = !!(param->op); 8353 8354 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 8355 return QDF_STATUS_E_FAILURE; 8356 8357 qdf_mem_copy(cmd->key, param->key, param->key_len); 8358 8359 if (param->mode == FIPS_ENGINE_AES_CTR || 8360 param->mode == FIPS_ENGINE_AES_MIC) { 8361 cmd->mode = param->mode; 8362 } else { 8363 cmd->mode = FIPS_ENGINE_AES_CTR; 8364 } 8365 qdf_print("Key len = %d, Data len = %d", 8366 cmd->key_len, cmd->data_len); 8367 8368 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 8369 cmd->key, cmd->key_len, true); 8370 buf_ptr += sizeof(*cmd); 8371 8372 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 8373 8374 buf_ptr += WMI_TLV_HDR_SIZE; 8375 if (param->data_len) 8376 qdf_mem_copy(buf_ptr, 8377 (uint8_t *) param->data, param->data_len); 8378 8379 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 8380 16, 1, buf_ptr, cmd->data_len, true); 8381 8382 buf_ptr += param->data_len; 8383 8384 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 8385 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 8386 WMI_PDEV_FIPS_CMDID); 8387 qdf_print("%s return value %d", __func__, retval); 8388 } else { 8389 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 8390 wmi_buf_free(buf); 8391 retval = -QDF_STATUS_E_BADMSG; 8392 } 8393 8394 return retval; 8395 } 8396 8397 /** 8398 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 8399 * to fw 8400 * @wmi_handle: wmi handle 8401 * @param: pointer to wlan profile param 8402 * 8403 * Return: 0 for success or error code 8404 */ 8405 static QDF_STATUS 8406 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 8407 struct wlan_profile_params *param) 8408 { 8409 wmi_buf_t buf; 8410 uint16_t len; 8411 QDF_STATUS ret; 8412 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 8413 8414 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 8415 buf = wmi_buf_alloc(wmi_handle, len); 8416 if (!buf) { 8417 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 8418 return QDF_STATUS_E_NOMEM; 8419 } 8420 8421 profile_enable_cmd = 8422 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 8423 wmi_buf_data(buf); 8424 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 8425 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 8426 WMITLV_GET_STRUCT_TLVLEN 8427 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 8428 8429 profile_enable_cmd->profile_id = param->profile_id; 8430 profile_enable_cmd->enable = param->enable; 8431 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 8432 NO_SESSION, 0); 8433 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8434 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 8435 if (ret) { 8436 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 8437 wmi_buf_free(buf); 8438 } 8439 return ret; 8440 } 8441 8442 /** 8443 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 8444 * to fw 8445 * @wmi_handle: wmi handle 8446 * @param: pointer to wlan profile param 8447 * 8448 * Return: 0 for success or error code 8449 */ 8450 static QDF_STATUS 8451 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 8452 struct wlan_profile_params *param) 8453 { 8454 wmi_buf_t buf; 8455 uint16_t len; 8456 QDF_STATUS ret; 8457 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 8458 8459 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 8460 buf = wmi_buf_alloc(wmi_handle, len); 8461 if (!buf) { 8462 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 8463 return QDF_STATUS_E_NOMEM; 8464 } 8465 8466 prof_trig_cmd = 8467 (wmi_wlan_profile_trigger_cmd_fixed_param *) 8468 wmi_buf_data(buf); 8469 8470 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 8471 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 8472 WMITLV_GET_STRUCT_TLVLEN 8473 (wmi_wlan_profile_trigger_cmd_fixed_param)); 8474 8475 prof_trig_cmd->enable = param->enable; 8476 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 8477 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8478 WMI_WLAN_PROFILE_TRIGGER_CMDID); 8479 if (ret) { 8480 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 8481 wmi_buf_free(buf); 8482 } 8483 return ret; 8484 } 8485 8486 /** 8487 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 8488 * to fw 8489 * @wmi_handle: wmi handle 8490 * @param: pointer to wlan profile param 8491 * 8492 * Return: 0 for success or error code 8493 */ 8494 static QDF_STATUS 8495 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 8496 struct wlan_profile_params *param) 8497 { 8498 wmi_buf_t buf; 8499 int32_t len = 0; 8500 QDF_STATUS ret; 8501 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 8502 8503 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 8504 buf = wmi_buf_alloc(wmi_handle, len); 8505 if (!buf) { 8506 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 8507 return QDF_STATUS_E_NOMEM; 8508 } 8509 8510 hist_intvl_cmd = 8511 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 8512 wmi_buf_data(buf); 8513 8514 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 8515 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 8516 WMITLV_GET_STRUCT_TLVLEN 8517 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 8518 8519 hist_intvl_cmd->profile_id = param->profile_id; 8520 hist_intvl_cmd->value = param->enable; 8521 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 8522 NO_SESSION, 0); 8523 8524 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8525 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 8526 if (ret) { 8527 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 8528 wmi_buf_free(buf); 8529 } 8530 return ret; 8531 } 8532 8533 /** 8534 * send_fw_test_cmd_tlv() - send fw test command to fw. 8535 * @wmi_handle: wmi handle 8536 * @wmi_fwtest: fw test command 8537 * 8538 * This function sends fw test command to fw. 8539 * 8540 * Return: CDF STATUS 8541 */ 8542 static 8543 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 8544 struct set_fwtest_params *wmi_fwtest) 8545 { 8546 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8547 wmi_buf_t wmi_buf; 8548 uint16_t len; 8549 8550 len = sizeof(*cmd); 8551 8552 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8553 if (!wmi_buf) 8554 return QDF_STATUS_E_NOMEM; 8555 8556 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 8557 WMITLV_SET_HDR(&cmd->tlv_header, 8558 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8559 WMITLV_GET_STRUCT_TLVLEN( 8560 wmi_fwtest_set_param_cmd_fixed_param)); 8561 cmd->param_id = wmi_fwtest->arg; 8562 cmd->param_value = wmi_fwtest->value; 8563 8564 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8565 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8566 WMI_FWTEST_CMDID)) { 8567 wmi_err("Failed to send fw test command"); 8568 wmi_buf_free(wmi_buf); 8569 return QDF_STATUS_E_FAILURE; 8570 } 8571 8572 return QDF_STATUS_SUCCESS; 8573 } 8574 8575 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 8576 { 8577 uint16_t len = 0; 8578 8579 if (config == WFA_CONFIG_RXNE) 8580 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 8581 else 8582 len += WMI_TLV_HDR_SIZE; 8583 8584 if (config == WFA_CONFIG_CSA) 8585 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 8586 else 8587 len += WMI_TLV_HDR_SIZE; 8588 8589 if (config == WFA_CONFIG_OCV) 8590 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 8591 else 8592 len += WMI_TLV_HDR_SIZE; 8593 8594 if (config == WFA_CONFIG_SA_QUERY) 8595 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 8596 else 8597 len += WMI_TLV_HDR_SIZE; 8598 8599 return len; 8600 } 8601 8602 /** 8603 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 8604 * @host_frmtype: Host defined OCV frame type 8605 * @ocv_frmtype: Pointer to hold WMI OCV frame type 8606 * 8607 * This function converts and fills host defined OCV frame type into WMI OCV 8608 * frame type. 8609 * 8610 * Return: CDF STATUS 8611 */ 8612 static QDF_STATUS 8613 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 8614 { 8615 switch (host_frmtype) { 8616 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 8617 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 8618 break; 8619 8620 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 8621 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 8622 break; 8623 8624 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 8625 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 8626 break; 8627 8628 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 8629 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 8630 break; 8631 8632 default: 8633 wmi_err("Invalid command type cmd %d", host_frmtype); 8634 return QDF_STATUS_E_FAILURE; 8635 } 8636 8637 return QDF_STATUS_SUCCESS; 8638 } 8639 8640 /** 8641 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 8642 * @wmi_handle: wmi handle 8643 * @wmi_wfatest: wfa test command 8644 * 8645 * This function sends wfa test command to fw. 8646 * 8647 * Return: CDF STATUS 8648 */ 8649 static 8650 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 8651 struct set_wfatest_params *wmi_wfatest) 8652 { 8653 wmi_wfa_config_cmd_fixed_param *cmd; 8654 wmi_wfa_config_rsnxe *rxne; 8655 wmi_wfa_config_csa *csa; 8656 wmi_wfa_config_ocv *ocv; 8657 wmi_wfa_config_saquery *saquery; 8658 wmi_buf_t wmi_buf; 8659 uint16_t len = sizeof(*cmd); 8660 uint8_t *buf_ptr; 8661 8662 len += wfa_config_param_len(wmi_wfatest->cmd); 8663 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8664 if (!wmi_buf) 8665 return QDF_STATUS_E_NOMEM; 8666 8667 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 8668 WMITLV_SET_HDR(&cmd->tlv_header, 8669 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 8670 WMITLV_GET_STRUCT_TLVLEN( 8671 wmi_wfa_config_cmd_fixed_param)); 8672 8673 cmd->vdev_id = wmi_wfatest->vdev_id; 8674 buf_ptr = (uint8_t *)(cmd + 1); 8675 8676 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 8677 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8678 sizeof(wmi_wfa_config_rsnxe)); 8679 buf_ptr += WMI_TLV_HDR_SIZE; 8680 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 8681 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 8682 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 8683 rxne->rsnxe_param = wmi_wfatest->value; 8684 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 8685 } else { 8686 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8687 buf_ptr += WMI_TLV_HDR_SIZE; 8688 } 8689 8690 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 8691 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8692 sizeof(wmi_wfa_config_csa)); 8693 buf_ptr += WMI_TLV_HDR_SIZE; 8694 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 8695 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 8696 csa = (wmi_wfa_config_csa *)buf_ptr; 8697 csa->ignore_csa = wmi_wfatest->value; 8698 buf_ptr += sizeof(wmi_wfa_config_csa); 8699 } else { 8700 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8701 buf_ptr += WMI_TLV_HDR_SIZE; 8702 } 8703 8704 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 8705 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8706 sizeof(wmi_wfa_config_ocv)); 8707 buf_ptr += WMI_TLV_HDR_SIZE; 8708 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 8709 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 8710 ocv = (wmi_wfa_config_ocv *)buf_ptr; 8711 8712 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 8713 &ocv->frame_types)) 8714 goto error; 8715 8716 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 8717 buf_ptr += sizeof(wmi_wfa_config_ocv); 8718 } else { 8719 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8720 buf_ptr += WMI_TLV_HDR_SIZE; 8721 } 8722 8723 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 8724 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8725 sizeof(wmi_wfa_config_saquery)); 8726 buf_ptr += WMI_TLV_HDR_SIZE; 8727 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 8728 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 8729 8730 saquery = (wmi_wfa_config_saquery *)buf_ptr; 8731 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 8732 } else { 8733 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 8734 buf_ptr += WMI_TLV_HDR_SIZE; 8735 } 8736 8737 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 8738 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8739 WMI_WFA_CONFIG_CMDID)) { 8740 wmi_err("Failed to send wfa test command"); 8741 goto error; 8742 } 8743 8744 return QDF_STATUS_SUCCESS; 8745 8746 error: 8747 wmi_buf_free(wmi_buf); 8748 return QDF_STATUS_E_FAILURE; 8749 } 8750 8751 /** 8752 * send_unit_test_cmd_tlv() - send unit test command to fw. 8753 * @wmi_handle: wmi handle 8754 * @wmi_utest: unit test command 8755 * 8756 * This function send unit test command to fw. 8757 * 8758 * Return: CDF STATUS 8759 */ 8760 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 8761 struct wmi_unit_test_cmd *wmi_utest) 8762 { 8763 wmi_unit_test_cmd_fixed_param *cmd; 8764 wmi_buf_t wmi_buf; 8765 uint8_t *buf_ptr; 8766 int i; 8767 uint16_t len, args_tlv_len; 8768 uint32_t *unit_test_cmd_args; 8769 8770 args_tlv_len = 8771 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 8772 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 8773 8774 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8775 if (!wmi_buf) 8776 return QDF_STATUS_E_NOMEM; 8777 8778 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 8779 buf_ptr = (uint8_t *) cmd; 8780 WMITLV_SET_HDR(&cmd->tlv_header, 8781 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 8782 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 8783 cmd->vdev_id = wmi_utest->vdev_id; 8784 cmd->module_id = wmi_utest->module_id; 8785 cmd->num_args = wmi_utest->num_args; 8786 cmd->diag_token = wmi_utest->diag_token; 8787 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 8788 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8789 (wmi_utest->num_args * sizeof(uint32_t))); 8790 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8791 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 8792 cmd->vdev_id, cmd->module_id, cmd->diag_token); 8793 wmi_debug("%d num of args = ", wmi_utest->num_args); 8794 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 8795 unit_test_cmd_args[i] = wmi_utest->args[i]; 8796 wmi_debug("%d,", wmi_utest->args[i]); 8797 } 8798 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 8799 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8800 WMI_UNIT_TEST_CMDID)) { 8801 wmi_err("Failed to send unit test command"); 8802 wmi_buf_free(wmi_buf); 8803 return QDF_STATUS_E_FAILURE; 8804 } 8805 8806 return QDF_STATUS_SUCCESS; 8807 } 8808 8809 /** 8810 * send_power_dbg_cmd_tlv() - send power debug commands 8811 * @wmi_handle: wmi handle 8812 * @param: wmi power debug parameter 8813 * 8814 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 8815 * 8816 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8817 */ 8818 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 8819 struct wmi_power_dbg_params *param) 8820 { 8821 wmi_buf_t buf = NULL; 8822 QDF_STATUS status; 8823 int len, args_tlv_len; 8824 uint8_t *buf_ptr; 8825 uint8_t i; 8826 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 8827 uint32_t *cmd_args; 8828 8829 /* Prepare and send power debug cmd parameters */ 8830 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 8831 len = sizeof(*cmd) + args_tlv_len; 8832 buf = wmi_buf_alloc(wmi_handle, len); 8833 if (!buf) 8834 return QDF_STATUS_E_NOMEM; 8835 8836 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8837 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 8838 WMITLV_SET_HDR(&cmd->tlv_header, 8839 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 8840 WMITLV_GET_STRUCT_TLVLEN 8841 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 8842 8843 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8844 wmi_handle, 8845 param->pdev_id); 8846 cmd->module_id = param->module_id; 8847 cmd->num_args = param->num_args; 8848 buf_ptr += sizeof(*cmd); 8849 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8850 (param->num_args * sizeof(uint32_t))); 8851 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8852 wmi_debug("%d num of args = ", param->num_args); 8853 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 8854 cmd_args[i] = param->args[i]; 8855 wmi_debug("%d,", param->args[i]); 8856 } 8857 8858 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 8859 status = wmi_unified_cmd_send(wmi_handle, buf, 8860 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 8861 if (QDF_IS_STATUS_ERROR(status)) { 8862 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 8863 status); 8864 goto error; 8865 } 8866 8867 return QDF_STATUS_SUCCESS; 8868 error: 8869 wmi_buf_free(buf); 8870 8871 return status; 8872 } 8873 8874 /** 8875 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 8876 * @wmi_handle: wmi handle 8877 * @pdev_id: pdev id 8878 * 8879 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 8880 * 8881 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8882 */ 8883 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 8884 uint32_t pdev_id) 8885 { 8886 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 8887 wmi_buf_t buf; 8888 uint16_t len; 8889 QDF_STATUS ret; 8890 8891 len = sizeof(*cmd); 8892 buf = wmi_buf_alloc(wmi_handle, len); 8893 8894 wmi_debug("pdev_id=%d", pdev_id); 8895 8896 if (!buf) 8897 return QDF_STATUS_E_NOMEM; 8898 8899 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 8900 wmi_buf_data(buf); 8901 8902 WMITLV_SET_HDR(&cmd->tlv_header, 8903 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 8904 WMITLV_GET_STRUCT_TLVLEN( 8905 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 8906 8907 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8908 wmi_handle, 8909 pdev_id); 8910 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 8911 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8912 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 8913 if (QDF_IS_STATUS_ERROR(ret)) { 8914 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 8915 ret, pdev_id); 8916 wmi_buf_free(buf); 8917 return QDF_STATUS_E_FAILURE; 8918 } 8919 8920 return QDF_STATUS_SUCCESS; 8921 } 8922 8923 /** 8924 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 8925 * @wmi_handle: wmi handle 8926 * @pdev_id: pdev id 8927 * 8928 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 8929 * 8930 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8931 */ 8932 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 8933 uint32_t pdev_id) 8934 { 8935 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 8936 wmi_buf_t buf; 8937 uint16_t len; 8938 QDF_STATUS ret; 8939 8940 len = sizeof(*cmd); 8941 buf = wmi_buf_alloc(wmi_handle, len); 8942 8943 wmi_debug("pdev_id=%d", pdev_id); 8944 8945 if (!buf) 8946 return QDF_STATUS_E_NOMEM; 8947 8948 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 8949 wmi_buf_data(buf); 8950 8951 WMITLV_SET_HDR(&cmd->tlv_header, 8952 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 8953 WMITLV_GET_STRUCT_TLVLEN( 8954 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 8955 8956 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8957 wmi_handle, 8958 pdev_id); 8959 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 8960 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8961 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 8962 if (QDF_IS_STATUS_ERROR(ret)) { 8963 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 8964 ret, pdev_id); 8965 wmi_buf_free(buf); 8966 return QDF_STATUS_E_FAILURE; 8967 } 8968 8969 return QDF_STATUS_SUCCESS; 8970 } 8971 8972 #ifdef QCA_SUPPORT_AGILE_DFS 8973 static 8974 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8975 struct vdev_adfs_ch_cfg_params *param) 8976 { 8977 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 8978 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 8979 wmi_buf_t buf; 8980 QDF_STATUS ret; 8981 uint16_t len; 8982 8983 len = sizeof(*cmd); 8984 buf = wmi_buf_alloc(wmi_handle, len); 8985 8986 if (!buf) { 8987 wmi_err("wmi_buf_alloc failed"); 8988 return QDF_STATUS_E_NOMEM; 8989 } 8990 8991 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 8992 wmi_buf_data(buf); 8993 8994 WMITLV_SET_HDR(&cmd->tlv_header, 8995 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 8996 WMITLV_GET_STRUCT_TLVLEN 8997 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 8998 8999 cmd->vdev_id = param->vdev_id; 9000 cmd->ocac_mode = param->ocac_mode; 9001 cmd->center_freq1 = param->center_freq1; 9002 cmd->center_freq2 = param->center_freq2; 9003 cmd->chan_freq = param->chan_freq; 9004 cmd->chan_width = param->chan_width; 9005 cmd->min_duration_ms = param->min_duration_ms; 9006 cmd->max_duration_ms = param->max_duration_ms; 9007 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 9008 cmd->vdev_id, cmd->ocac_mode, 9009 cmd->center_freq); 9010 9011 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 9012 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9013 WMI_VDEV_ADFS_CH_CFG_CMDID); 9014 9015 if (QDF_IS_STATUS_ERROR(ret)) { 9016 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9017 wmi_buf_free(buf); 9018 return QDF_STATUS_E_FAILURE; 9019 } 9020 9021 return QDF_STATUS_SUCCESS; 9022 } 9023 9024 static 9025 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 9026 struct vdev_adfs_abort_params *param) 9027 { 9028 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 9029 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 9030 wmi_buf_t buf; 9031 QDF_STATUS ret; 9032 uint16_t len; 9033 9034 len = sizeof(*cmd); 9035 buf = wmi_buf_alloc(wmi_handle, len); 9036 9037 if (!buf) { 9038 wmi_err("wmi_buf_alloc failed"); 9039 return QDF_STATUS_E_NOMEM; 9040 } 9041 9042 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 9043 wmi_buf_data(buf); 9044 9045 WMITLV_SET_HDR 9046 (&cmd->tlv_header, 9047 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 9048 WMITLV_GET_STRUCT_TLVLEN 9049 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 9050 9051 cmd->vdev_id = param->vdev_id; 9052 9053 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 9054 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9055 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 9056 9057 if (QDF_IS_STATUS_ERROR(ret)) { 9058 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9059 wmi_buf_free(buf); 9060 return QDF_STATUS_E_FAILURE; 9061 } 9062 9063 return QDF_STATUS_SUCCESS; 9064 } 9065 #endif 9066 9067 /** 9068 * init_cmd_send_tlv() - send initialization cmd to fw 9069 * @wmi_handle: wmi handle 9070 * @param param: pointer to wmi init param 9071 * 9072 * Return: QDF_STATUS_SUCCESS for success or error code 9073 */ 9074 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 9075 struct wmi_init_cmd_param *param) 9076 { 9077 wmi_buf_t buf; 9078 wmi_init_cmd_fixed_param *cmd; 9079 uint8_t *buf_ptr; 9080 wmi_resource_config *resource_cfg; 9081 wlan_host_memory_chunk *host_mem_chunks; 9082 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 9083 uint16_t idx; 9084 int len; 9085 QDF_STATUS ret; 9086 9087 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 9088 WMI_TLV_HDR_SIZE; 9089 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 9090 9091 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 9092 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 9093 WMI_TLV_HDR_SIZE + 9094 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 9095 9096 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 9097 if (!buf) 9098 return QDF_STATUS_E_FAILURE; 9099 9100 buf_ptr = (uint8_t *) wmi_buf_data(buf); 9101 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 9102 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 9103 9104 host_mem_chunks = (wlan_host_memory_chunk *) 9105 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 9106 + WMI_TLV_HDR_SIZE); 9107 9108 WMITLV_SET_HDR(&cmd->tlv_header, 9109 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 9110 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 9111 wmi_copy_resource_config(resource_cfg, param->res_cfg); 9112 WMITLV_SET_HDR(&resource_cfg->tlv_header, 9113 WMITLV_TAG_STRUC_wmi_resource_config, 9114 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 9115 9116 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 9117 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 9118 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 9119 WMITLV_GET_STRUCT_TLVLEN 9120 (wlan_host_memory_chunk)); 9121 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 9122 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 9123 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 9124 if (is_service_enabled_tlv(wmi_handle, 9125 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 9126 host_mem_chunks[idx].ptr_high = 9127 qdf_get_upper_32_bits( 9128 param->mem_chunks[idx].paddr); 9129 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 9130 "chunk %d len %d requested ,ptr 0x%x ", 9131 idx, host_mem_chunks[idx].size, 9132 host_mem_chunks[idx].ptr); 9133 } 9134 cmd->num_host_mem_chunks = param->num_mem_chunks; 9135 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 9136 9137 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 9138 WMITLV_TAG_ARRAY_STRUC, 9139 (sizeof(wlan_host_memory_chunk) * 9140 param->num_mem_chunks)); 9141 9142 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", 9143 resource_cfg->num_peers, resource_cfg->num_offload_peers, 9144 resource_cfg->num_vdevs, resource_cfg->num_tids, 9145 resource_cfg->num_tdls_conn_table_entries, 9146 resource_cfg->num_tdls_vdevs); 9147 9148 /* Fill hw mode id config */ 9149 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 9150 9151 /* Fill fw_abi_vers */ 9152 copy_fw_abi_version_tlv(wmi_handle, cmd); 9153 9154 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 9155 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 9156 if (QDF_IS_STATUS_ERROR(ret)) { 9157 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 9158 ret); 9159 wmi_buf_free(buf); 9160 } 9161 9162 return ret; 9163 9164 } 9165 9166 /** 9167 * send_addba_send_cmd_tlv() - send addba send command to fw 9168 * @wmi_handle: wmi handle 9169 * @param: pointer to delba send params 9170 * @macaddr: peer mac address 9171 * 9172 * Send WMI_ADDBA_SEND_CMDID command to firmware 9173 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 9174 */ 9175 static QDF_STATUS 9176 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 9177 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 9178 struct addba_send_params *param) 9179 { 9180 wmi_addba_send_cmd_fixed_param *cmd; 9181 wmi_buf_t buf; 9182 uint16_t len; 9183 QDF_STATUS ret; 9184 9185 len = sizeof(*cmd); 9186 9187 buf = wmi_buf_alloc(wmi_handle, len); 9188 if (!buf) 9189 return QDF_STATUS_E_NOMEM; 9190 9191 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 9192 9193 WMITLV_SET_HDR(&cmd->tlv_header, 9194 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 9195 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 9196 9197 cmd->vdev_id = param->vdev_id; 9198 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 9199 cmd->tid = param->tidno; 9200 cmd->buffersize = param->buffersize; 9201 9202 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 9203 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 9204 if (QDF_IS_STATUS_ERROR(ret)) { 9205 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9206 wmi_buf_free(buf); 9207 return QDF_STATUS_E_FAILURE; 9208 } 9209 9210 return QDF_STATUS_SUCCESS; 9211 } 9212 9213 /** 9214 * send_delba_send_cmd_tlv() - send delba send command to fw 9215 * @wmi_handle: wmi handle 9216 * @param: pointer to delba send params 9217 * @macaddr: peer mac address 9218 * 9219 * Send WMI_DELBA_SEND_CMDID command to firmware 9220 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 9221 */ 9222 static QDF_STATUS 9223 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 9224 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 9225 struct delba_send_params *param) 9226 { 9227 wmi_delba_send_cmd_fixed_param *cmd; 9228 wmi_buf_t buf; 9229 uint16_t len; 9230 QDF_STATUS ret; 9231 9232 len = sizeof(*cmd); 9233 9234 buf = wmi_buf_alloc(wmi_handle, len); 9235 if (!buf) 9236 return QDF_STATUS_E_NOMEM; 9237 9238 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 9239 9240 WMITLV_SET_HDR(&cmd->tlv_header, 9241 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 9242 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 9243 9244 cmd->vdev_id = param->vdev_id; 9245 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 9246 cmd->tid = param->tidno; 9247 cmd->initiator = param->initiator; 9248 cmd->reasoncode = param->reasoncode; 9249 9250 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 9251 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 9252 if (QDF_IS_STATUS_ERROR(ret)) { 9253 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9254 wmi_buf_free(buf); 9255 return QDF_STATUS_E_FAILURE; 9256 } 9257 9258 return QDF_STATUS_SUCCESS; 9259 } 9260 9261 /** 9262 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 9263 * to fw 9264 * @wmi_handle: wmi handle 9265 * @param: pointer to addba clearresp params 9266 * @macaddr: peer mac address 9267 * Return: 0 for success or error code 9268 */ 9269 static QDF_STATUS 9270 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 9271 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 9272 struct addba_clearresponse_params *param) 9273 { 9274 wmi_addba_clear_resp_cmd_fixed_param *cmd; 9275 wmi_buf_t buf; 9276 uint16_t len; 9277 QDF_STATUS ret; 9278 9279 len = sizeof(*cmd); 9280 9281 buf = wmi_buf_alloc(wmi_handle, len); 9282 if (!buf) 9283 return QDF_STATUS_E_FAILURE; 9284 9285 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 9286 9287 WMITLV_SET_HDR(&cmd->tlv_header, 9288 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 9289 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 9290 9291 cmd->vdev_id = param->vdev_id; 9292 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 9293 9294 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 9295 ret = wmi_unified_cmd_send(wmi_handle, 9296 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 9297 if (QDF_IS_STATUS_ERROR(ret)) { 9298 wmi_err("Failed to send cmd to fw, ret=%d", ret); 9299 wmi_buf_free(buf); 9300 return QDF_STATUS_E_FAILURE; 9301 } 9302 9303 return QDF_STATUS_SUCCESS; 9304 } 9305 9306 #ifdef OBSS_PD 9307 /** 9308 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 9309 * def thresh to fw 9310 * @wmi_handle: wmi handle 9311 * @thresh: pointer to obss_spatial_reuse_def_thresh 9312 * 9313 * Return: QDF_STATUS_SUCCESS for success or error code 9314 */ 9315 static 9316 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 9317 wmi_unified_t wmi_handle, 9318 struct wmi_host_obss_spatial_reuse_set_def_thresh 9319 *thresh) 9320 { 9321 wmi_buf_t buf; 9322 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 9323 QDF_STATUS ret; 9324 uint32_t cmd_len; 9325 uint32_t tlv_len; 9326 9327 cmd_len = sizeof(*cmd); 9328 9329 buf = wmi_buf_alloc(wmi_handle, cmd_len); 9330 if (!buf) 9331 return QDF_STATUS_E_NOMEM; 9332 9333 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 9334 wmi_buf_data(buf); 9335 9336 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 9337 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 9338 9339 WMITLV_SET_HDR(&cmd->tlv_header, 9340 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 9341 tlv_len); 9342 9343 cmd->obss_min = thresh->obss_min; 9344 cmd->obss_max = thresh->obss_max; 9345 cmd->vdev_type = thresh->vdev_type; 9346 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 9347 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 9348 if (QDF_IS_STATUS_ERROR(ret)) 9349 wmi_buf_free(buf); 9350 9351 return ret; 9352 } 9353 9354 /** 9355 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 9356 * @wmi_handle: wmi handle 9357 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 9358 * 9359 * Return: QDF_STATUS_SUCCESS for success or error code 9360 */ 9361 static 9362 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 9363 struct wmi_host_obss_spatial_reuse_set_param 9364 *obss_spatial_reuse_param) 9365 { 9366 wmi_buf_t buf; 9367 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 9368 QDF_STATUS ret; 9369 uint32_t len; 9370 9371 len = sizeof(*cmd); 9372 9373 buf = wmi_buf_alloc(wmi_handle, len); 9374 if (!buf) 9375 return QDF_STATUS_E_FAILURE; 9376 9377 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 9378 WMITLV_SET_HDR(&cmd->tlv_header, 9379 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 9380 WMITLV_GET_STRUCT_TLVLEN 9381 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 9382 9383 cmd->enable = obss_spatial_reuse_param->enable; 9384 cmd->obss_min = obss_spatial_reuse_param->obss_min; 9385 cmd->obss_max = obss_spatial_reuse_param->obss_max; 9386 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 9387 9388 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9389 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 9390 9391 if (QDF_IS_STATUS_ERROR(ret)) { 9392 wmi_err( 9393 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 9394 ret); 9395 wmi_buf_free(buf); 9396 } 9397 9398 return ret; 9399 } 9400 9401 /** 9402 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 9403 * to be used by SRG based Spatial Reuse feature to the FW 9404 * @wmi_handle: wmi handle 9405 * @bitmap_0: lower 32 bits in BSS color bitmap 9406 * @bitmap_1: upper 32 bits in BSS color bitmap 9407 * @pdev_id: pdev ID 9408 * 9409 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9410 */ 9411 static QDF_STATUS 9412 send_self_srg_bss_color_bitmap_set_cmd_tlv( 9413 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9414 uint32_t bitmap_1, uint8_t pdev_id) 9415 { 9416 wmi_buf_t buf; 9417 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 9418 QDF_STATUS ret; 9419 uint32_t len; 9420 9421 len = sizeof(*cmd); 9422 9423 buf = wmi_buf_alloc(wmi_handle, len); 9424 if (!buf) 9425 return QDF_STATUS_E_FAILURE; 9426 9427 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 9428 wmi_buf_data(buf); 9429 9430 WMITLV_SET_HDR( 9431 &cmd->tlv_header, 9432 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 9433 WMITLV_GET_STRUCT_TLVLEN 9434 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 9435 9436 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9437 wmi_handle, pdev_id); 9438 cmd->srg_bss_color_bitmap[0] = bitmap_0; 9439 cmd->srg_bss_color_bitmap[1] = bitmap_1; 9440 9441 ret = wmi_unified_cmd_send( 9442 wmi_handle, buf, len, 9443 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 9444 9445 if (QDF_IS_STATUS_ERROR(ret)) { 9446 wmi_err( 9447 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 9448 ret); 9449 wmi_buf_free(buf); 9450 } 9451 9452 return ret; 9453 } 9454 9455 /** 9456 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 9457 * bitmap to be used by SRG based Spatial Reuse feature to the FW 9458 * @wmi_handle: wmi handle 9459 * @bitmap_0: lower 32 bits in partial BSSID bitmap 9460 * @bitmap_1: upper 32 bits in partial BSSID bitmap 9461 * @pdev_id: pdev ID 9462 * 9463 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9464 */ 9465 static QDF_STATUS 9466 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 9467 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9468 uint32_t bitmap_1, uint8_t pdev_id) 9469 { 9470 wmi_buf_t buf; 9471 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 9472 QDF_STATUS ret; 9473 uint32_t len; 9474 9475 len = sizeof(*cmd); 9476 9477 buf = wmi_buf_alloc(wmi_handle, len); 9478 if (!buf) 9479 return QDF_STATUS_E_FAILURE; 9480 9481 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 9482 wmi_buf_data(buf); 9483 9484 WMITLV_SET_HDR( 9485 &cmd->tlv_header, 9486 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 9487 WMITLV_GET_STRUCT_TLVLEN 9488 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 9489 9490 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9491 wmi_handle, pdev_id); 9492 9493 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 9494 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 9495 9496 ret = wmi_unified_cmd_send( 9497 wmi_handle, buf, len, 9498 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 9499 9500 if (QDF_IS_STATUS_ERROR(ret)) { 9501 wmi_err( 9502 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 9503 ret); 9504 wmi_buf_free(buf); 9505 } 9506 9507 return ret; 9508 } 9509 9510 /** 9511 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 9512 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 9513 * @wmi_handle: wmi handle 9514 * @bitmap_0: lower 32 bits in BSS color enable bitmap 9515 * @bitmap_1: upper 32 bits in BSS color enable bitmap 9516 * @pdev_id: pdev ID 9517 * 9518 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9519 */ 9520 static QDF_STATUS 9521 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 9522 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9523 uint32_t bitmap_1, uint8_t pdev_id) 9524 { 9525 wmi_buf_t buf; 9526 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 9527 QDF_STATUS ret; 9528 uint32_t len; 9529 9530 len = sizeof(*cmd); 9531 9532 buf = wmi_buf_alloc(wmi_handle, len); 9533 if (!buf) 9534 return QDF_STATUS_E_FAILURE; 9535 9536 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 9537 wmi_buf_data(buf); 9538 9539 WMITLV_SET_HDR( 9540 &cmd->tlv_header, 9541 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 9542 WMITLV_GET_STRUCT_TLVLEN 9543 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 9544 9545 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9546 wmi_handle, pdev_id); 9547 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 9548 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 9549 9550 ret = wmi_unified_cmd_send( 9551 wmi_handle, buf, len, 9552 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 9553 9554 if (QDF_IS_STATUS_ERROR(ret)) { 9555 wmi_err( 9556 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 9557 ret); 9558 wmi_buf_free(buf); 9559 } 9560 9561 return ret; 9562 } 9563 9564 /** 9565 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 9566 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 9567 * @wmi_handle: wmi handle 9568 * @bitmap_0: lower 32 bits in BSSID enable bitmap 9569 * @bitmap_1: upper 32 bits in BSSID enable bitmap 9570 * @pdev_id: pdev ID 9571 * 9572 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9573 */ 9574 static QDF_STATUS 9575 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 9576 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9577 uint32_t bitmap_1, uint8_t pdev_id) 9578 { 9579 wmi_buf_t buf; 9580 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 9581 QDF_STATUS ret; 9582 uint32_t len; 9583 9584 len = sizeof(*cmd); 9585 9586 buf = wmi_buf_alloc(wmi_handle, len); 9587 if (!buf) 9588 return QDF_STATUS_E_FAILURE; 9589 9590 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 9591 wmi_buf_data(buf); 9592 9593 WMITLV_SET_HDR( 9594 &cmd->tlv_header, 9595 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 9596 WMITLV_GET_STRUCT_TLVLEN 9597 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 9598 9599 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9600 wmi_handle, pdev_id); 9601 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 9602 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 9603 9604 ret = wmi_unified_cmd_send( 9605 wmi_handle, buf, len, 9606 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 9607 9608 if (QDF_IS_STATUS_ERROR(ret)) { 9609 wmi_err( 9610 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 9611 ret); 9612 wmi_buf_free(buf); 9613 } 9614 9615 return ret; 9616 } 9617 9618 /** 9619 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 9620 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 9621 * @wmi_handle: wmi handle 9622 * @bitmap_0: lower 32 bits in BSS color enable bitmap 9623 * @bitmap_1: upper 32 bits in BSS color enable bitmap 9624 * @pdev_id: pdev ID 9625 * 9626 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9627 */ 9628 static QDF_STATUS 9629 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 9630 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9631 uint32_t bitmap_1, uint8_t pdev_id) 9632 { 9633 wmi_buf_t buf; 9634 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 9635 QDF_STATUS ret; 9636 uint32_t len; 9637 9638 len = sizeof(*cmd); 9639 9640 buf = wmi_buf_alloc(wmi_handle, len); 9641 if (!buf) 9642 return QDF_STATUS_E_FAILURE; 9643 9644 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 9645 wmi_buf_data(buf); 9646 9647 WMITLV_SET_HDR( 9648 &cmd->tlv_header, 9649 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 9650 WMITLV_GET_STRUCT_TLVLEN 9651 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 9652 9653 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9654 wmi_handle, pdev_id); 9655 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 9656 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 9657 9658 ret = wmi_unified_cmd_send( 9659 wmi_handle, buf, len, 9660 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 9661 9662 if (QDF_IS_STATUS_ERROR(ret)) { 9663 wmi_err( 9664 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 9665 ret); 9666 wmi_buf_free(buf); 9667 } 9668 9669 return ret; 9670 } 9671 9672 /** 9673 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 9674 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 9675 * @wmi_handle: wmi handle 9676 * @bitmap_0: lower 32 bits in BSSID enable bitmap 9677 * @bitmap_1: upper 32 bits in BSSID enable bitmap 9678 * @pdev_id: pdev ID 9679 * 9680 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9681 */ 9682 static QDF_STATUS 9683 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 9684 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9685 uint32_t bitmap_1, uint8_t pdev_id) 9686 { 9687 wmi_buf_t buf; 9688 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 9689 QDF_STATUS ret; 9690 uint32_t len; 9691 9692 len = sizeof(*cmd); 9693 9694 buf = wmi_buf_alloc(wmi_handle, len); 9695 if (!buf) 9696 return QDF_STATUS_E_FAILURE; 9697 9698 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 9699 wmi_buf_data(buf); 9700 9701 WMITLV_SET_HDR( 9702 &cmd->tlv_header, 9703 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 9704 WMITLV_GET_STRUCT_TLVLEN 9705 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 9706 9707 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9708 wmi_handle, pdev_id); 9709 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 9710 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 9711 9712 ret = wmi_unified_cmd_send( 9713 wmi_handle, buf, len, 9714 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 9715 9716 if (QDF_IS_STATUS_ERROR(ret)) { 9717 wmi_err( 9718 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 9719 ret); 9720 wmi_buf_free(buf); 9721 } 9722 9723 return ret; 9724 } 9725 #endif 9726 9727 static 9728 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 9729 struct wmi_host_injector_frame_params *inject_config_params) 9730 { 9731 wmi_buf_t buf; 9732 wmi_frame_inject_cmd_fixed_param *cmd; 9733 QDF_STATUS ret; 9734 uint32_t len; 9735 9736 len = sizeof(*cmd); 9737 9738 buf = wmi_buf_alloc(wmi_handle, len); 9739 if (!buf) 9740 return QDF_STATUS_E_NOMEM; 9741 9742 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 9743 WMITLV_SET_HDR(&cmd->tlv_header, 9744 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 9745 WMITLV_GET_STRUCT_TLVLEN 9746 (wmi_frame_inject_cmd_fixed_param)); 9747 9748 cmd->vdev_id = inject_config_params->vdev_id; 9749 cmd->enable = inject_config_params->enable; 9750 cmd->frame_type = inject_config_params->frame_type; 9751 cmd->frame_inject_period = inject_config_params->frame_inject_period; 9752 cmd->fc_duration = inject_config_params->frame_duration; 9753 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 9754 &cmd->frame_addr1); 9755 9756 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9757 WMI_PDEV_FRAME_INJECT_CMDID); 9758 9759 if (QDF_IS_STATUS_ERROR(ret)) { 9760 wmi_err( 9761 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 9762 ret); 9763 wmi_buf_free(buf); 9764 } 9765 9766 return ret; 9767 } 9768 #ifdef QCA_SUPPORT_CP_STATS 9769 /** 9770 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 9771 * @wmi_handle: wma handle 9772 * @evt_buf: event buffer 9773 * @out_buff: buffer to populated after stats extraction 9774 * 9775 * Return: status of operation 9776 */ 9777 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 9778 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 9779 { 9780 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9781 wmi_congestion_stats *congestion_stats; 9782 9783 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 9784 congestion_stats = param_buf->congestion_stats; 9785 if (!congestion_stats) 9786 return QDF_STATUS_E_INVAL; 9787 9788 out_buff->vdev_id = congestion_stats->vdev_id; 9789 out_buff->congestion = congestion_stats->congestion; 9790 9791 wmi_debug("cca stats event processed"); 9792 return QDF_STATUS_SUCCESS; 9793 } 9794 #endif /* QCA_SUPPORT_CP_STATS */ 9795 9796 /** 9797 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 9798 * event 9799 * @wmi_handle: wmi handle 9800 * @param evt_buf: pointer to event buffer 9801 * @param param: Pointer to hold peer ctl data 9802 * 9803 * Return: QDF_STATUS_SUCCESS for success or error code 9804 */ 9805 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 9806 wmi_unified_t wmi_handle, 9807 void *evt_buf, 9808 struct wmi_host_pdev_ctl_failsafe_event *param) 9809 { 9810 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 9811 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 9812 9813 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 9814 if (!param_buf) { 9815 wmi_err("Invalid ctl_failsafe event buffer"); 9816 return QDF_STATUS_E_INVAL; 9817 } 9818 9819 fix_param = param_buf->fixed_param; 9820 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 9821 9822 return QDF_STATUS_SUCCESS; 9823 } 9824 9825 /** 9826 * save_service_bitmap_tlv() - save service bitmap 9827 * @wmi_handle: wmi handle 9828 * @param evt_buf: pointer to event buffer 9829 * @param bitmap_buf: bitmap buffer, for converged legacy support 9830 * 9831 * Return: QDF_STATUS 9832 */ 9833 static 9834 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9835 void *bitmap_buf) 9836 { 9837 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9838 struct wmi_soc *soc = wmi_handle->soc; 9839 9840 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9841 9842 /* If it is already allocated, use that buffer. This can happen 9843 * during target stop/start scenarios where host allocation is skipped. 9844 */ 9845 if (!soc->wmi_service_bitmap) { 9846 soc->wmi_service_bitmap = 9847 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 9848 if (!soc->wmi_service_bitmap) 9849 return QDF_STATUS_E_NOMEM; 9850 } 9851 9852 qdf_mem_copy(soc->wmi_service_bitmap, 9853 param_buf->wmi_service_bitmap, 9854 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 9855 9856 if (bitmap_buf) 9857 qdf_mem_copy(bitmap_buf, 9858 param_buf->wmi_service_bitmap, 9859 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 9860 9861 return QDF_STATUS_SUCCESS; 9862 } 9863 9864 /** 9865 * save_ext_service_bitmap_tlv() - save extendend service bitmap 9866 * @wmi_handle: wmi handle 9867 * @param evt_buf: pointer to event buffer 9868 * @param bitmap_buf: bitmap buffer, for converged legacy support 9869 * 9870 * Return: QDF_STATUS 9871 */ 9872 static 9873 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9874 void *bitmap_buf) 9875 { 9876 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 9877 wmi_service_available_event_fixed_param *ev; 9878 struct wmi_soc *soc = wmi_handle->soc; 9879 uint32_t i = 0; 9880 9881 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 9882 9883 ev = param_buf->fixed_param; 9884 9885 /* If it is already allocated, use that buffer. This can happen 9886 * during target stop/start scenarios where host allocation is skipped. 9887 */ 9888 if (!soc->wmi_ext_service_bitmap) { 9889 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 9890 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 9891 if (!soc->wmi_ext_service_bitmap) 9892 return QDF_STATUS_E_NOMEM; 9893 } 9894 9895 qdf_mem_copy(soc->wmi_ext_service_bitmap, 9896 ev->wmi_service_segment_bitmap, 9897 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 9898 9899 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 9900 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 9901 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 9902 9903 if (bitmap_buf) 9904 qdf_mem_copy(bitmap_buf, 9905 soc->wmi_ext_service_bitmap, 9906 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 9907 9908 if (!param_buf->wmi_service_ext_bitmap) { 9909 wmi_debug("wmi_service_ext_bitmap not available"); 9910 return QDF_STATUS_SUCCESS; 9911 } 9912 9913 if (!soc->wmi_ext2_service_bitmap) { 9914 soc->wmi_ext2_service_bitmap = 9915 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 9916 sizeof(uint32_t)); 9917 if (!soc->wmi_ext2_service_bitmap) 9918 return QDF_STATUS_E_NOMEM; 9919 } 9920 9921 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 9922 param_buf->wmi_service_ext_bitmap, 9923 (param_buf->num_wmi_service_ext_bitmap * 9924 sizeof(uint32_t))); 9925 9926 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 9927 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 9928 i, soc->wmi_ext2_service_bitmap[i]); 9929 } 9930 9931 return QDF_STATUS_SUCCESS; 9932 } 9933 9934 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 9935 struct wlan_psoc_target_capability_info *cap) 9936 { 9937 /* except LDPC all flags are common betwen legacy and here 9938 * also IBFEER is not defined for TLV 9939 */ 9940 cap->ht_cap_info |= ev_target_cap & ( 9941 WMI_HT_CAP_ENABLED 9942 | WMI_HT_CAP_HT20_SGI 9943 | WMI_HT_CAP_DYNAMIC_SMPS 9944 | WMI_HT_CAP_TX_STBC 9945 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 9946 | WMI_HT_CAP_RX_STBC 9947 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 9948 | WMI_HT_CAP_LDPC 9949 | WMI_HT_CAP_L_SIG_TXOP_PROT 9950 | WMI_HT_CAP_MPDU_DENSITY 9951 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 9952 | WMI_HT_CAP_HT40_SGI); 9953 if (ev_target_cap & WMI_HT_CAP_LDPC) 9954 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 9955 WMI_HOST_HT_CAP_TX_LDPC; 9956 } 9957 /** 9958 * extract_service_ready_tlv() - extract service ready event 9959 * @wmi_handle: wmi handle 9960 * @param evt_buf: pointer to received event buffer 9961 * @param cap: pointer to hold target capability information extracted from even 9962 * 9963 * Return: QDF_STATUS_SUCCESS for success or error code 9964 */ 9965 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 9966 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 9967 { 9968 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9969 wmi_service_ready_event_fixed_param *ev; 9970 9971 9972 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9973 9974 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9975 if (!ev) { 9976 qdf_print("%s: wmi_buf_alloc failed", __func__); 9977 return QDF_STATUS_E_FAILURE; 9978 } 9979 9980 cap->phy_capability = ev->phy_capability; 9981 cap->max_frag_entry = ev->max_frag_entry; 9982 cap->num_rf_chains = ev->num_rf_chains; 9983 copy_ht_cap_info(ev->ht_cap_info, cap); 9984 cap->vht_cap_info = ev->vht_cap_info; 9985 cap->vht_supp_mcs = ev->vht_supp_mcs; 9986 cap->hw_min_tx_power = ev->hw_min_tx_power; 9987 cap->hw_max_tx_power = ev->hw_max_tx_power; 9988 cap->sys_cap_info = ev->sys_cap_info; 9989 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 9990 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 9991 cap->max_num_scan_channels = ev->max_num_scan_channels; 9992 cap->max_supported_macs = ev->max_supported_macs; 9993 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 9994 cap->txrx_chainmask = ev->txrx_chainmask; 9995 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 9996 cap->num_msdu_desc = ev->num_msdu_desc; 9997 cap->fw_version = ev->fw_build_vers; 9998 /* fw_version_1 is not available in TLV. */ 9999 cap->fw_version_1 = 0; 10000 10001 return QDF_STATUS_SUCCESS; 10002 } 10003 10004 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 10005 * to host internal WMI_HOST_REGDMN_MODE values. 10006 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 10007 * host currently. Add this in the future if required. 10008 * 11AX (Phase II) : 11ax related values are not currently 10009 * advertised separately by FW. As part of phase II regulatory bring-up, 10010 * finalize the advertisement mechanism. 10011 * @target_wireless_mode: target wireless mode received in message 10012 * 10013 * Return: returns the host internal wireless mode. 10014 */ 10015 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 10016 { 10017 10018 uint32_t wireless_modes = 0; 10019 10020 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 10021 10022 if (target_wireless_mode & REGDMN_MODE_11A) 10023 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 10024 10025 if (target_wireless_mode & REGDMN_MODE_TURBO) 10026 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 10027 10028 if (target_wireless_mode & REGDMN_MODE_11B) 10029 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 10030 10031 if (target_wireless_mode & REGDMN_MODE_PUREG) 10032 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 10033 10034 if (target_wireless_mode & REGDMN_MODE_11G) 10035 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 10036 10037 if (target_wireless_mode & REGDMN_MODE_108G) 10038 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 10039 10040 if (target_wireless_mode & REGDMN_MODE_108A) 10041 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 10042 10043 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 10044 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20_2G; 10045 10046 if (target_wireless_mode & REGDMN_MODE_XR) 10047 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 10048 10049 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 10050 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 10051 10052 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 10053 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 10054 10055 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 10056 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 10057 10058 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 10059 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 10060 10061 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 10062 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 10063 10064 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 10065 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 10066 10067 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 10068 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 10069 10070 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 10071 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 10072 10073 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 10074 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 10075 10076 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 10077 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 10078 10079 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 10080 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 10081 10082 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 10083 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 10084 10085 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 10086 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 10087 10088 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 10089 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 10090 10091 return wireless_modes; 10092 } 10093 10094 /** 10095 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 10096 * to regulatory flags. 10097 * @target_phybitmap: target phybitmap. 10098 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 10099 * phybitmap. 10100 * 10101 * Return: None 10102 */ 10103 10104 #ifdef WLAN_FEATURE_11BE 10105 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 10106 uint32_t *phybitmap) 10107 { 10108 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 10109 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 10110 } 10111 #else 10112 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 10113 uint32_t *phybitmap) 10114 { 10115 } 10116 #endif 10117 10118 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 10119 * target to host internal REGULATORY_PHYMODE values. 10120 * 10121 * @target_target_phybitmap: target phybitmap received in the message. 10122 * 10123 * Return: returns the host internal REGULATORY_PHYMODE. 10124 */ 10125 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 10126 { 10127 uint32_t phybitmap = 0; 10128 10129 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 10130 10131 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 10132 phybitmap |= REGULATORY_PHYMODE_NO11A; 10133 10134 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 10135 phybitmap |= REGULATORY_PHYMODE_NO11B; 10136 10137 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 10138 phybitmap |= REGULATORY_PHYMODE_NO11G; 10139 10140 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 10141 phybitmap |= REGULATORY_CHAN_NO11N; 10142 10143 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 10144 phybitmap |= REGULATORY_PHYMODE_NO11AC; 10145 10146 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 10147 phybitmap |= REGULATORY_PHYMODE_NO11AX; 10148 10149 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 10150 10151 return phybitmap; 10152 } 10153 10154 /** 10155 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 10156 * advertised by the target to wireless mode ext flags. 10157 * @target_wireless_modes_ext: Target wireless mode 10158 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 10159 * 10160 * Return: None 10161 */ 10162 #ifdef WLAN_FEATURE_11BE 10163 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 10164 uint64_t *wireless_modes_ext) 10165 { 10166 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 10167 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEG_EHT20; 10168 10169 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 10170 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEG_EHT40PLUS; 10171 10172 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 10173 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEG_EHT40MINUS; 10174 10175 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 10176 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEA_EHT20; 10177 10178 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 10179 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEA_EHT40PLUS; 10180 10181 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 10182 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEA_EHT40MINUS; 10183 10184 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 10185 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEA_EHT80; 10186 10187 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 10188 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEA_EHT160; 10189 10190 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 10191 *wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11BEA_EHT320; 10192 } 10193 #else 10194 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 10195 uint64_t *wireless_modes_ext) 10196 { 10197 } 10198 #endif 10199 10200 static inline uint64_t convert_wireless_modes_ext_tlv( 10201 uint32_t target_wireless_modes_ext) 10202 { 10203 uint64_t wireless_modes_ext = 0; 10204 10205 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 10206 10207 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 10208 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE20; 10209 10210 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 10211 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40PLUS; 10212 10213 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 10214 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40MINUS; 10215 10216 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 10217 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE20; 10218 10219 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 10220 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40PLUS; 10221 10222 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 10223 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40MINUS; 10224 10225 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 10226 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80; 10227 10228 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 10229 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE160; 10230 10231 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 10232 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80_80; 10233 10234 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 10235 &wireless_modes_ext); 10236 10237 return wireless_modes_ext; 10238 } 10239 10240 /** 10241 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 10242 * @wmi_handle: wmi handle 10243 * @param evt_buf: Pointer to event buffer 10244 * @param cap: pointer to hold HAL reg capabilities 10245 * 10246 * Return: QDF_STATUS_SUCCESS for success or error code 10247 */ 10248 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 10249 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 10250 { 10251 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10252 10253 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10254 if (!param_buf || !param_buf->hal_reg_capabilities) { 10255 wmi_err("Invalid arguments"); 10256 return QDF_STATUS_E_FAILURE; 10257 } 10258 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 10259 sizeof(uint32_t)), 10260 sizeof(struct wlan_psoc_hal_reg_capability)); 10261 10262 cap->wireless_modes = convert_wireless_modes_tlv( 10263 param_buf->hal_reg_capabilities->wireless_modes); 10264 10265 return QDF_STATUS_SUCCESS; 10266 } 10267 10268 /** 10269 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 10270 * @wmi_handle: wmi handle 10271 * @param evt_buf: Pointer to event buffer 10272 * @param cap: pointer to hold HAL reg capabilities 10273 * 10274 * Return: QDF_STATUS_SUCCESS for success or error code 10275 */ 10276 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 10277 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 10278 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 10279 { 10280 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 10281 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 10282 10283 if (!evt_buf) { 10284 wmi_err("null evt_buf"); 10285 return QDF_STATUS_E_INVAL; 10286 } 10287 10288 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 10289 10290 if (!param_buf->num_hal_reg_caps) 10291 return QDF_STATUS_SUCCESS; 10292 10293 if (phy_idx >= param_buf->num_hal_reg_caps) 10294 return QDF_STATUS_E_INVAL; 10295 10296 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 10297 10298 param->phy_id = reg_caps->phy_id; 10299 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 10300 reg_caps->wireless_modes_ext); 10301 10302 return QDF_STATUS_SUCCESS; 10303 } 10304 10305 /** 10306 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 10307 * @wmi_handle: wmi handle 10308 * @evt_buf: pointer to event buffer 10309 * 10310 * Return: Number of entries requested 10311 */ 10312 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 10313 void *evt_buf) 10314 { 10315 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10316 wmi_service_ready_event_fixed_param *ev; 10317 10318 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10319 10320 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10321 if (!ev) { 10322 qdf_print("%s: wmi_buf_alloc failed", __func__); 10323 return 0; 10324 } 10325 10326 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 10327 wmi_err("Invalid num_mem_reqs %d:%d", 10328 ev->num_mem_reqs, param_buf->num_mem_reqs); 10329 return 0; 10330 } 10331 10332 return ev->num_mem_reqs; 10333 } 10334 10335 /** 10336 * extract_host_mem_req_tlv() - Extract host memory required from 10337 * service ready event 10338 * @wmi_handle: wmi handle 10339 * @evt_buf: pointer to event buffer 10340 * @mem_reqs: pointer to host memory request structure 10341 * @num_active_peers: number of active peers for peer cache 10342 * @num_peers: number of peers 10343 * @fw_prio: FW priority 10344 * @idx: index for memory request 10345 * 10346 * Return: Host memory request parameters requested by target 10347 */ 10348 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 10349 void *evt_buf, 10350 host_mem_req *mem_reqs, 10351 uint32_t num_active_peers, 10352 uint32_t num_peers, 10353 enum wmi_fw_mem_prio fw_prio, 10354 uint16_t idx) 10355 { 10356 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10357 10358 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 10359 10360 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 10361 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 10362 mem_reqs->num_unit_info = 10363 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 10364 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 10365 mem_reqs->tgt_num_units = 0; 10366 10367 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 10368 (mem_reqs->num_unit_info & 10369 REQ_TO_HOST_FOR_CONT_MEMORY)) || 10370 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 10371 (!(mem_reqs->num_unit_info & 10372 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 10373 /* First allocate the memory that requires contiguous memory */ 10374 mem_reqs->tgt_num_units = mem_reqs->num_units; 10375 if (mem_reqs->num_unit_info) { 10376 if (mem_reqs->num_unit_info & 10377 NUM_UNITS_IS_NUM_PEERS) { 10378 /* 10379 * number of units allocated is equal to number 10380 * of peers, 1 extra for self peer on target. 10381 * this needs to be fixed, host and target can 10382 * get out of sync 10383 */ 10384 mem_reqs->tgt_num_units = num_peers + 1; 10385 } 10386 if (mem_reqs->num_unit_info & 10387 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 10388 /* 10389 * Requesting allocation of memory using 10390 * num_active_peers in qcache. if qcache is 10391 * disabled in host, then it should allocate 10392 * memory for num_peers instead of 10393 * num_active_peers. 10394 */ 10395 if (num_active_peers) 10396 mem_reqs->tgt_num_units = 10397 num_active_peers + 1; 10398 else 10399 mem_reqs->tgt_num_units = 10400 num_peers + 1; 10401 } 10402 } 10403 10404 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 10405 "unit size %d actual units %d", 10406 idx, mem_reqs->req_id, 10407 mem_reqs->num_units, 10408 mem_reqs->num_unit_info, 10409 mem_reqs->unit_size, 10410 mem_reqs->tgt_num_units); 10411 } 10412 10413 return QDF_STATUS_SUCCESS; 10414 } 10415 10416 /** 10417 * save_fw_version_in_service_ready_tlv() - Save fw version in service 10418 * ready function 10419 * @wmi_handle: wmi handle 10420 * @param evt_buf: pointer to event buffer 10421 * 10422 * Return: QDF_STATUS_SUCCESS for success or error code 10423 */ 10424 static QDF_STATUS 10425 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10426 { 10427 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10428 wmi_service_ready_event_fixed_param *ev; 10429 10430 10431 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10432 10433 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10434 if (!ev) { 10435 qdf_print("%s: wmi_buf_alloc failed", __func__); 10436 return QDF_STATUS_E_FAILURE; 10437 } 10438 10439 /*Save fw version from service ready message */ 10440 /*This will be used while sending INIT message */ 10441 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10442 sizeof(wmi_handle->fw_abi_version)); 10443 10444 return QDF_STATUS_SUCCESS; 10445 } 10446 10447 /** 10448 * ready_extract_init_status_tlv() - Extract init status from ready event 10449 * @wmi_handle: wmi handle 10450 * @param evt_buf: Pointer to event buffer 10451 * 10452 * Return: ready status 10453 */ 10454 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 10455 void *evt_buf) 10456 { 10457 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10458 wmi_ready_event_fixed_param *ev = NULL; 10459 10460 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10461 ev = param_buf->fixed_param; 10462 10463 qdf_print("%s:%d", __func__, ev->status); 10464 10465 return ev->status; 10466 } 10467 10468 /** 10469 * ready_extract_mac_addr_tlv() - extract mac address from ready event 10470 * @wmi_handle: wmi handle 10471 * @param evt_buf: pointer to event buffer 10472 * @param macaddr: Pointer to hold MAC address 10473 * 10474 * Return: QDF_STATUS_SUCCESS for success or error code 10475 */ 10476 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 10477 void *evt_buf, uint8_t *macaddr) 10478 { 10479 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10480 wmi_ready_event_fixed_param *ev = NULL; 10481 10482 10483 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10484 ev = param_buf->fixed_param; 10485 10486 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 10487 10488 return QDF_STATUS_SUCCESS; 10489 } 10490 10491 /** 10492 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 10493 * @wmi_handle: wmi handle 10494 * @param evt_buf: pointer to event buffer 10495 * @param macaddr: Pointer to hold number of MAC addresses 10496 * 10497 * Return: Pointer to addr list 10498 */ 10499 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 10500 void *evt_buf, uint8_t *num_mac) 10501 { 10502 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10503 wmi_ready_event_fixed_param *ev = NULL; 10504 10505 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10506 ev = param_buf->fixed_param; 10507 10508 *num_mac = ev->num_extra_mac_addr; 10509 10510 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 10511 } 10512 10513 /** 10514 * extract_ready_params_tlv() - Extract data from ready event apart from 10515 * status, macaddr and version. 10516 * @wmi_handle: Pointer to WMI handle. 10517 * @evt_buf: Pointer to Ready event buffer. 10518 * @ev_param: Pointer to host defined struct to copy the data from event. 10519 * 10520 * Return: QDF_STATUS_SUCCESS on success. 10521 */ 10522 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 10523 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 10524 { 10525 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10526 wmi_ready_event_fixed_param *ev = NULL; 10527 10528 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10529 ev = param_buf->fixed_param; 10530 10531 ev_param->status = ev->status; 10532 ev_param->num_dscp_table = ev->num_dscp_table; 10533 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 10534 ev_param->num_total_peer = ev->num_total_peers; 10535 ev_param->num_extra_peer = ev->num_extra_peers; 10536 /* Agile_capability in ready event is supported in TLV target, 10537 * as per aDFS FR 10538 */ 10539 ev_param->max_ast_index = ev->max_ast_index; 10540 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 10541 ev_param->agile_capability = 1; 10542 10543 return QDF_STATUS_SUCCESS; 10544 } 10545 10546 /** 10547 * extract_dbglog_data_len_tlv() - extract debuglog data length 10548 * @wmi_handle: wmi handle 10549 * @param evt_buf: pointer to event buffer 10550 * 10551 * Return: length 10552 */ 10553 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 10554 void *evt_buf, uint32_t *len) 10555 { 10556 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 10557 10558 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 10559 10560 *len = param_buf->num_bufp; 10561 10562 return param_buf->bufp; 10563 } 10564 10565 10566 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 10567 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 10568 #else 10569 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 10570 ((_status) & WMI_RXERR_DECRYPT) 10571 #endif 10572 10573 /** 10574 * extract_mgmt_rx_params_tlv() - extract management rx params from event 10575 * @wmi_handle: wmi handle 10576 * @param evt_buf: pointer to event buffer 10577 * @param hdr: Pointer to hold header 10578 * @param bufp: Pointer to hold pointer to rx param buffer 10579 * 10580 * Return: QDF_STATUS_SUCCESS for success or error code 10581 */ 10582 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 10583 void *evt_buf, struct mgmt_rx_event_params *hdr, 10584 uint8_t **bufp) 10585 { 10586 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 10587 wmi_mgmt_rx_hdr *ev_hdr = NULL; 10588 int i; 10589 10590 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 10591 if (!param_tlvs) { 10592 wmi_err("Get NULL point message from FW"); 10593 return QDF_STATUS_E_INVAL; 10594 } 10595 10596 ev_hdr = param_tlvs->hdr; 10597 if (!hdr) { 10598 wmi_err("Rx event is NULL"); 10599 return QDF_STATUS_E_INVAL; 10600 } 10601 10602 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 10603 wmi_err("RX mgmt frame decrypt error, discard it"); 10604 return QDF_STATUS_E_INVAL; 10605 } 10606 10607 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 10608 wmi_err("Rx mgmt frame length mismatch, discard it"); 10609 return QDF_STATUS_E_INVAL; 10610 } 10611 10612 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10613 wmi_handle, 10614 ev_hdr->pdev_id); 10615 hdr->chan_freq = ev_hdr->chan_freq; 10616 hdr->channel = ev_hdr->channel; 10617 hdr->snr = ev_hdr->snr; 10618 hdr->rate = ev_hdr->rate; 10619 hdr->phy_mode = ev_hdr->phy_mode; 10620 hdr->buf_len = ev_hdr->buf_len; 10621 hdr->status = ev_hdr->status; 10622 hdr->flags = ev_hdr->flags; 10623 hdr->rssi = ev_hdr->rssi; 10624 hdr->tsf_delta = ev_hdr->tsf_delta; 10625 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 10626 for (i = 0; i < ATH_MAX_ANTENNA; i++) 10627 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 10628 10629 *bufp = param_tlvs->bufp; 10630 10631 return QDF_STATUS_SUCCESS; 10632 } 10633 10634 #ifdef WLAN_MGMT_RX_REO_SUPPORT 10635 /** 10636 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 10637 * @wmi_handle: wmi handle 10638 * @evt_buf: pointer to event buffer 10639 * @params: Pointer to MGMT Rx REO parameters 10640 * 10641 * Return: QDF_STATUS_SUCCESS for success or error code 10642 */ 10643 static QDF_STATUS 10644 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 10645 void *evt_buf, 10646 struct mgmt_rx_reo_params *params) 10647 { 10648 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 10649 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 10650 10651 param_tlvs = evt_buf; 10652 if (!param_tlvs) { 10653 wmi_err("param_tlvs is NULL"); 10654 return QDF_STATUS_E_INVAL; 10655 } 10656 10657 ev_hdr = param_tlvs->hdr; 10658 if (!params) { 10659 wmi_err("Rx REO parameters is NULL"); 10660 return QDF_STATUS_E_INVAL; 10661 } 10662 10663 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10664 wmi_handle, 10665 ev_hdr->pdev_id); 10666 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 10667 ev_hdr->mgmt_pkt_ctr_info); 10668 params->global_timestamp = ev_hdr->global_timestamp; 10669 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 10670 ev_hdr->mgmt_pkt_ctr_info); 10671 10672 return QDF_STATUS_SUCCESS; 10673 } 10674 10675 /** 10676 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 10677 * MGMT_RX_EVENT_ID 10678 * @wmi_handle: wmi handle 10679 * @evt_buf: pointer to event buffer 10680 * @params: Pointer to MGMT Rx REO parameters 10681 * 10682 * Return: QDF_STATUS_SUCCESS for success or error code 10683 */ 10684 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 10685 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 10686 { 10687 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 10688 wmi_mgmt_rx_reo_params *reo_params_tlv; 10689 wmi_mgmt_rx_hdr *ev_hdr; 10690 10691 param_tlvs = evt_buf; 10692 if (!param_tlvs) { 10693 wmi_err("param_tlvs is NULL"); 10694 return QDF_STATUS_E_INVAL; 10695 } 10696 10697 ev_hdr = param_tlvs->hdr; 10698 if (!ev_hdr) { 10699 wmi_err("Rx event is NULL"); 10700 return QDF_STATUS_E_INVAL; 10701 } 10702 10703 reo_params_tlv = param_tlvs->reo_params; 10704 if (!reo_params_tlv) { 10705 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 10706 return QDF_STATUS_E_INVAL; 10707 } 10708 10709 if (!reo_params) { 10710 wmi_err("MGMT Rx REO params is NULL"); 10711 return QDF_STATUS_E_INVAL; 10712 } 10713 10714 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10715 wmi_handle, 10716 ev_hdr->pdev_id); 10717 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 10718 reo_params_tlv->mgmt_pkt_ctr_link_info); 10719 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 10720 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 10721 reo_params_tlv->mgmt_pkt_ctr_link_info); 10722 10723 return QDF_STATUS_SUCCESS; 10724 } 10725 10726 /** 10727 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 10728 * configuration command 10729 * @wmi_handle: wmi handle 10730 * @pdev_id: pdev ID of the radio 10731 * @filter: Pointer to MGMT Rx REO filter 10732 * 10733 * Return: QDF_STATUS_SUCCESS for success or error code 10734 */ 10735 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 10736 wmi_unified_t wmi_handle, 10737 uint8_t pdev_id, 10738 struct mgmt_rx_reo_filter *filter) 10739 { 10740 QDF_STATUS ret; 10741 wmi_buf_t buf; 10742 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 10743 size_t len = sizeof(*cmd); 10744 10745 if (!filter) { 10746 wmi_err("mgmt_rx_reo_filter is NULL"); 10747 return QDF_STATUS_E_INVAL; 10748 } 10749 10750 buf = wmi_buf_alloc(wmi_handle, len); 10751 if (!buf) { 10752 wmi_err("wmi_buf_alloc failed"); 10753 return QDF_STATUS_E_NOMEM; 10754 } 10755 10756 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 10757 wmi_buf_data(buf); 10758 10759 WMITLV_SET_HDR(&cmd->tlv_header, 10760 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 10761 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 10762 10763 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 10764 wmi_handle, 10765 pdev_id); 10766 cmd->filter_low = filter->low; 10767 cmd->filter_high = filter->high; 10768 10769 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 10770 ret = wmi_unified_cmd_send( 10771 wmi_handle, buf, len, 10772 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 10773 10774 if (QDF_IS_STATUS_ERROR(ret)) { 10775 wmi_err("Failed to send WMI command"); 10776 wmi_buf_free(buf); 10777 } 10778 10779 return ret; 10780 } 10781 #endif 10782 10783 /** 10784 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 10785 * @wmi_handle: wmi handle 10786 * @param evt_buf: pointer to event buffer 10787 * @param param: Pointer to hold roam param 10788 * 10789 * Return: QDF_STATUS_SUCCESS for success or error code 10790 */ 10791 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 10792 void *evt_buf, wmi_host_roam_event *param) 10793 { 10794 WMI_ROAM_EVENTID_param_tlvs *param_buf; 10795 wmi_roam_event_fixed_param *evt; 10796 10797 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 10798 if (!param_buf) { 10799 wmi_err("Invalid roam event buffer"); 10800 return QDF_STATUS_E_INVAL; 10801 } 10802 10803 evt = param_buf->fixed_param; 10804 qdf_mem_zero(param, sizeof(*param)); 10805 10806 param->vdev_id = evt->vdev_id; 10807 param->reason = evt->reason; 10808 param->rssi = evt->rssi; 10809 10810 return QDF_STATUS_SUCCESS; 10811 } 10812 10813 /** 10814 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 10815 * @wmi_handle: wmi handle 10816 * @param evt_buf: pointer to event buffer 10817 * @param param: Pointer to hold vdev scan param 10818 * 10819 * Return: QDF_STATUS_SUCCESS for success or error code 10820 */ 10821 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 10822 void *evt_buf, struct scan_event *param) 10823 { 10824 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 10825 wmi_scan_event_fixed_param *evt = NULL; 10826 10827 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 10828 evt = param_buf->fixed_param; 10829 10830 qdf_mem_zero(param, sizeof(*param)); 10831 10832 switch (evt->event) { 10833 case WMI_SCAN_EVENT_STARTED: 10834 param->type = SCAN_EVENT_TYPE_STARTED; 10835 break; 10836 case WMI_SCAN_EVENT_COMPLETED: 10837 param->type = SCAN_EVENT_TYPE_COMPLETED; 10838 break; 10839 case WMI_SCAN_EVENT_BSS_CHANNEL: 10840 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 10841 break; 10842 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 10843 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 10844 break; 10845 case WMI_SCAN_EVENT_DEQUEUED: 10846 param->type = SCAN_EVENT_TYPE_DEQUEUED; 10847 break; 10848 case WMI_SCAN_EVENT_PREEMPTED: 10849 param->type = SCAN_EVENT_TYPE_PREEMPTED; 10850 break; 10851 case WMI_SCAN_EVENT_START_FAILED: 10852 param->type = SCAN_EVENT_TYPE_START_FAILED; 10853 break; 10854 case WMI_SCAN_EVENT_RESTARTED: 10855 param->type = SCAN_EVENT_TYPE_RESTARTED; 10856 break; 10857 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 10858 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 10859 break; 10860 case WMI_SCAN_EVENT_MAX: 10861 default: 10862 param->type = SCAN_EVENT_TYPE_MAX; 10863 break; 10864 }; 10865 10866 switch (evt->reason) { 10867 case WMI_SCAN_REASON_NONE: 10868 param->reason = SCAN_REASON_NONE; 10869 break; 10870 case WMI_SCAN_REASON_COMPLETED: 10871 param->reason = SCAN_REASON_COMPLETED; 10872 break; 10873 case WMI_SCAN_REASON_CANCELLED: 10874 param->reason = SCAN_REASON_CANCELLED; 10875 break; 10876 case WMI_SCAN_REASON_PREEMPTED: 10877 param->reason = SCAN_REASON_PREEMPTED; 10878 break; 10879 case WMI_SCAN_REASON_TIMEDOUT: 10880 param->reason = SCAN_REASON_TIMEDOUT; 10881 break; 10882 case WMI_SCAN_REASON_INTERNAL_FAILURE: 10883 param->reason = SCAN_REASON_INTERNAL_FAILURE; 10884 break; 10885 case WMI_SCAN_REASON_SUSPENDED: 10886 param->reason = SCAN_REASON_SUSPENDED; 10887 break; 10888 case WMI_SCAN_REASON_DFS_VIOLATION: 10889 param->reason = SCAN_REASON_DFS_VIOLATION; 10890 break; 10891 case WMI_SCAN_REASON_MAX: 10892 param->reason = SCAN_REASON_MAX; 10893 break; 10894 default: 10895 param->reason = SCAN_REASON_MAX; 10896 break; 10897 }; 10898 10899 param->chan_freq = evt->channel_freq; 10900 param->requester = evt->requestor; 10901 param->scan_id = evt->scan_id; 10902 param->vdev_id = evt->vdev_id; 10903 param->timestamp = evt->tsf_timestamp; 10904 10905 return QDF_STATUS_SUCCESS; 10906 } 10907 10908 #ifdef FEATURE_WLAN_SCAN_PNO 10909 /** 10910 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 10911 * @wmi_handle: pointer to WMI handle 10912 * @evt_buf: pointer to WMI event buffer 10913 * @param: pointer to scan event param for NLO match 10914 * 10915 * Return: QDF_STATUS_SUCCESS for success or error code 10916 */ 10917 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 10918 void *evt_buf, 10919 struct scan_event *param) 10920 { 10921 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 10922 wmi_nlo_event *evt = param_buf->fixed_param; 10923 10924 qdf_mem_zero(param, sizeof(*param)); 10925 10926 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 10927 param->vdev_id = evt->vdev_id; 10928 10929 return QDF_STATUS_SUCCESS; 10930 } 10931 10932 /** 10933 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 10934 * @wmi_handle: pointer to WMI handle 10935 * @evt_buf: pointer to WMI event buffer 10936 * @param: pointer to scan event param for NLO complete 10937 * 10938 * Return: QDF_STATUS_SUCCESS for success or error code 10939 */ 10940 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 10941 void *evt_buf, 10942 struct scan_event *param) 10943 { 10944 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 10945 wmi_nlo_event *evt = param_buf->fixed_param; 10946 10947 qdf_mem_zero(param, sizeof(*param)); 10948 10949 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 10950 param->vdev_id = evt->vdev_id; 10951 10952 return QDF_STATUS_SUCCESS; 10953 } 10954 #endif 10955 10956 /** 10957 * extract_unit_test_tlv() - extract unit test data 10958 * @wmi_handle: wmi handle 10959 * @param evt_buf: pointer to event buffer 10960 * @param unit_test: pointer to hold unit test data 10961 * @param maxspace: Amount of space in evt_buf 10962 * 10963 * Return: QDF_STATUS_SUCCESS for success or error code 10964 */ 10965 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 10966 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 10967 { 10968 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 10969 wmi_unit_test_event_fixed_param *ev_param; 10970 uint32_t num_bufp; 10971 uint32_t copy_size; 10972 uint8_t *bufp; 10973 10974 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 10975 ev_param = param_buf->fixed_param; 10976 bufp = param_buf->bufp; 10977 num_bufp = param_buf->num_bufp; 10978 unit_test->vdev_id = ev_param->vdev_id; 10979 unit_test->module_id = ev_param->module_id; 10980 unit_test->diag_token = ev_param->diag_token; 10981 unit_test->flag = ev_param->flag; 10982 unit_test->payload_len = ev_param->payload_len; 10983 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 10984 ev_param->vdev_id, 10985 ev_param->module_id, 10986 ev_param->diag_token, 10987 ev_param->flag); 10988 wmi_debug("Unit-test data given below %d", num_bufp); 10989 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10990 bufp, num_bufp); 10991 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 10992 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 10993 unit_test->buffer_len = copy_size; 10994 10995 return QDF_STATUS_SUCCESS; 10996 } 10997 10998 /** 10999 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 11000 * @wmi_handle: wmi handle 11001 * @param evt_buf: pointer to event buffer 11002 * @param index: Index into extended pdev stats 11003 * @param pdev_ext_stats: Pointer to hold extended pdev stats 11004 * 11005 * Return: QDF_STATUS_SUCCESS for success or error code 11006 */ 11007 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 11008 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 11009 { 11010 return QDF_STATUS_SUCCESS; 11011 } 11012 11013 /** 11014 * extract_bcn_stats_tlv() - extract bcn stats from event 11015 * @wmi_handle: wmi handle 11016 * @param evt_buf: pointer to event buffer 11017 * @param index: Index into vdev stats 11018 * @param bcn_stats: Pointer to hold bcn stats 11019 * 11020 * Return: QDF_STATUS_SUCCESS for success or error code 11021 */ 11022 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 11023 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 11024 { 11025 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11026 wmi_stats_event_fixed_param *ev_param; 11027 uint8_t *data; 11028 11029 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 11030 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 11031 data = (uint8_t *) param_buf->data; 11032 11033 if (index < ev_param->num_bcn_stats) { 11034 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 11035 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 11036 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 11037 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 11038 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 11039 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 11040 (index * sizeof(wmi_bcn_stats))); 11041 11042 bcn_stats->vdev_id = ev->vdev_id; 11043 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 11044 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 11045 } 11046 11047 return QDF_STATUS_SUCCESS; 11048 } 11049 11050 /** 11051 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 11052 * stats from event 11053 * @wmi_handle: wmi handle 11054 * @param evt_buf: pointer to event buffer 11055 * @param index: Index into vdev stats 11056 * @param vdev_prb_fd_stats: Pointer to hold vdev probe and fils stats 11057 * 11058 * Return: QDF_STATUS_SUCCESS for success or error code 11059 */ 11060 static QDF_STATUS 11061 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 11062 void *evt_buf, uint32_t index, 11063 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 11064 { 11065 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11066 wmi_vdev_extd_stats *ev; 11067 11068 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 11069 11070 if (param_buf->vdev_extd_stats) { 11071 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 11072 index); 11073 vdev_stats->vdev_id = ev->vdev_id; 11074 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 11075 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 11076 vdev_stats->unsolicited_prb_succ_cnt = 11077 ev->unsolicited_prb_succ_cnt; 11078 vdev_stats->unsolicited_prb_fail_cnt = 11079 ev->unsolicited_prb_fail_cnt; 11080 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 11081 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 11082 ev->unsolicited_prb_succ_cnt, 11083 ev->unsolicited_prb_fail_cnt); 11084 } 11085 11086 return QDF_STATUS_SUCCESS; 11087 } 11088 11089 /** 11090 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 11091 * @wmi_handle: wmi handle 11092 * @param evt_buf: pointer to event buffer 11093 * @param index: Index into bcn fault stats 11094 * @param bcnflt_stats: Pointer to hold bcn fault stats 11095 * 11096 * Return: QDF_STATUS_SUCCESS for success or error code 11097 */ 11098 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 11099 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 11100 { 11101 return QDF_STATUS_SUCCESS; 11102 } 11103 11104 /** 11105 * extract_chan_stats_tlv() - extract chan stats from event 11106 * @wmi_handle: wmi handle 11107 * @param evt_buf: pointer to event buffer 11108 * @param index: Index into chan stats 11109 * @param vdev_extd_stats: Pointer to hold chan stats 11110 * 11111 * Return: QDF_STATUS_SUCCESS for success or error code 11112 */ 11113 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 11114 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 11115 { 11116 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 11117 wmi_stats_event_fixed_param *ev_param; 11118 uint8_t *data; 11119 11120 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 11121 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 11122 data = (uint8_t *) param_buf->data; 11123 11124 if (index < ev_param->num_chan_stats) { 11125 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 11126 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 11127 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 11128 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 11129 (index * sizeof(wmi_chan_stats))); 11130 11131 11132 /* Non-TLV doesn't have num_chan_stats */ 11133 chan_stats->chan_mhz = ev->chan_mhz; 11134 chan_stats->sampling_period_us = ev->sampling_period_us; 11135 chan_stats->rx_clear_count = ev->rx_clear_count; 11136 chan_stats->tx_duration_us = ev->tx_duration_us; 11137 chan_stats->rx_duration_us = ev->rx_duration_us; 11138 } 11139 11140 return QDF_STATUS_SUCCESS; 11141 } 11142 11143 /** 11144 * extract_profile_ctx_tlv() - extract profile context from event 11145 * @wmi_handle: wmi handle 11146 * @param evt_buf: pointer to event buffer 11147 * @idx: profile stats index to extract 11148 * @param profile_ctx: Pointer to hold profile context 11149 * 11150 * Return: QDF_STATUS_SUCCESS for success or error code 11151 */ 11152 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 11153 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 11154 { 11155 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 11156 11157 wmi_wlan_profile_ctx_t *ev; 11158 11159 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 11160 if (!param_buf) { 11161 wmi_err("Invalid profile data event buf"); 11162 return QDF_STATUS_E_INVAL; 11163 } 11164 11165 ev = param_buf->profile_ctx; 11166 11167 profile_ctx->tot = ev->tot; 11168 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 11169 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 11170 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 11171 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 11172 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 11173 profile_ctx->bin_count = ev->bin_count; 11174 11175 return QDF_STATUS_SUCCESS; 11176 } 11177 11178 /** 11179 * extract_profile_data_tlv() - extract profile data from event 11180 * @wmi_handle: wmi handle 11181 * @param evt_buf: pointer to event buffer 11182 * @param profile_data: Pointer to hold profile data 11183 * 11184 * Return: QDF_STATUS_SUCCESS for success or error code 11185 */ 11186 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 11187 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 11188 { 11189 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 11190 wmi_wlan_profile_t *ev; 11191 uint8_t *buf_ptr; 11192 11193 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 11194 if (!param_buf) { 11195 wmi_err("Invalid profile data event buf"); 11196 return QDF_STATUS_E_INVAL; 11197 } 11198 11199 buf_ptr = (uint8_t *)param_buf->profile_ctx; 11200 buf_ptr = buf_ptr + sizeof(wmi_wlan_profile_ctx_t) + WMI_TLV_HDR_SIZE; 11201 11202 buf_ptr = buf_ptr + (sizeof(wmi_wlan_profile_t) * idx); 11203 ev = (wmi_wlan_profile_t *)buf_ptr; 11204 11205 profile_data->id = ev->id; 11206 profile_data->cnt = ev->cnt; 11207 profile_data->tot = ev->tot; 11208 profile_data->min = ev->min; 11209 profile_data->max = ev->max; 11210 profile_data->hist_intvl = ev->hist_intvl; 11211 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 11212 11213 return QDF_STATUS_SUCCESS; 11214 } 11215 11216 /** 11217 * extract_pdev_utf_event_tlv() - extract UTF data info from event 11218 * @wmi_handle: WMI handle 11219 * @param evt_buf: Pointer to event buffer 11220 * @param param: Pointer to hold data 11221 * 11222 * Return : QDF_STATUS_SUCCESS for success or error code 11223 */ 11224 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 11225 uint8_t *evt_buf, 11226 struct wmi_host_pdev_utf_event *event) 11227 { 11228 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 11229 struct wmi_host_utf_seg_header_info *seg_hdr; 11230 11231 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 11232 event->data = param_buf->data; 11233 event->datalen = param_buf->num_data; 11234 11235 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 11236 wmi_err("Invalid datalen: %d", event->datalen); 11237 return QDF_STATUS_E_INVAL; 11238 } 11239 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 11240 /* Set pdev_id=1 until FW adds support to include pdev_id */ 11241 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11242 wmi_handle, 11243 seg_hdr->pdev_id); 11244 11245 return QDF_STATUS_SUCCESS; 11246 } 11247 11248 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 11249 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 11250 uint8_t *event, 11251 uint32_t *num_rf_characterization_entries) 11252 { 11253 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 11254 11255 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 11256 if (!param_buf) 11257 return QDF_STATUS_E_INVAL; 11258 11259 *num_rf_characterization_entries = 11260 param_buf->num_wmi_chan_rf_characterization_info; 11261 11262 return QDF_STATUS_SUCCESS; 11263 } 11264 11265 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 11266 uint8_t *event, 11267 uint32_t num_rf_characterization_entries, 11268 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 11269 { 11270 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 11271 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 11272 uint8_t ix; 11273 11274 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 11275 if (!param_buf) 11276 return QDF_STATUS_E_INVAL; 11277 11278 wmi_rf_characterization_entry = 11279 param_buf->wmi_chan_rf_characterization_info; 11280 if (!wmi_rf_characterization_entry) 11281 return QDF_STATUS_E_INVAL; 11282 11283 /* 11284 * Using num_wmi_chan_rf_characterization instead of param_buf value 11285 * since memory for rf_characterization_entries was allocated using 11286 * the former. 11287 */ 11288 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 11289 rf_characterization_entries[ix].freq = 11290 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 11291 &wmi_rf_characterization_entry[ix]); 11292 11293 rf_characterization_entries[ix].bw = 11294 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 11295 &wmi_rf_characterization_entry[ix]); 11296 11297 rf_characterization_entries[ix].chan_metric = 11298 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 11299 &wmi_rf_characterization_entry[ix]); 11300 11301 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 11302 "bw: %u, chan_metric: %u", 11303 ix, rf_characterization_entries[ix].freq, 11304 rf_characterization_entries[ix].bw, 11305 rf_characterization_entries[ix].chan_metric); 11306 } 11307 11308 return QDF_STATUS_SUCCESS; 11309 } 11310 #endif 11311 11312 #ifdef WLAN_FEATURE_11BE 11313 static void 11314 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 11315 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 11316 { 11317 cap->supports_chan_width_320 = 11318 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 11319 } 11320 #else 11321 static void 11322 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 11323 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 11324 { 11325 } 11326 #endif /* WLAN_FEATURE_11BE */ 11327 11328 /** 11329 * extract_chainmask_tables_tlv() - extract chain mask tables from event 11330 * @wmi_handle: wmi handle 11331 * @param evt_buf: pointer to event buffer 11332 * @param param: Pointer to hold evt buf 11333 * 11334 * Return: QDF_STATUS_SUCCESS for success or error code 11335 */ 11336 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 11337 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 11338 { 11339 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11340 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 11341 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11342 uint8_t i = 0, j = 0; 11343 uint32_t num_mac_phy_chainmask_caps = 0; 11344 11345 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11346 if (!param_buf) 11347 return QDF_STATUS_E_INVAL; 11348 11349 hw_caps = param_buf->soc_hw_mode_caps; 11350 if (!hw_caps) 11351 return QDF_STATUS_E_INVAL; 11352 11353 if ((!hw_caps->num_chainmask_tables) || 11354 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 11355 (hw_caps->num_chainmask_tables > 11356 param_buf->num_mac_phy_chainmask_combo)) 11357 return QDF_STATUS_E_INVAL; 11358 11359 chainmask_caps = param_buf->mac_phy_chainmask_caps; 11360 11361 if (!chainmask_caps) 11362 return QDF_STATUS_E_INVAL; 11363 11364 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 11365 if (chainmask_table[i].num_valid_chainmasks > 11366 (UINT_MAX - num_mac_phy_chainmask_caps)) { 11367 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 11368 num_mac_phy_chainmask_caps, i, 11369 chainmask_table[i].num_valid_chainmasks); 11370 return QDF_STATUS_E_INVAL; 11371 } 11372 num_mac_phy_chainmask_caps += 11373 chainmask_table[i].num_valid_chainmasks; 11374 } 11375 11376 if (num_mac_phy_chainmask_caps > 11377 param_buf->num_mac_phy_chainmask_caps) { 11378 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 11379 num_mac_phy_chainmask_caps, 11380 param_buf->num_mac_phy_chainmask_caps); 11381 return QDF_STATUS_E_INVAL; 11382 } 11383 11384 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 11385 11386 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 11387 i); 11388 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 11389 11390 chainmask_table[i].cap_list[j].chainmask = 11391 chainmask_caps->chainmask; 11392 11393 chainmask_table[i].cap_list[j].supports_chan_width_20 = 11394 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 11395 11396 chainmask_table[i].cap_list[j].supports_chan_width_40 = 11397 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 11398 11399 chainmask_table[i].cap_list[j].supports_chan_width_80 = 11400 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 11401 11402 chainmask_table[i].cap_list[j].supports_chan_width_160 = 11403 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 11404 11405 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 11406 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 11407 11408 chainmask_table[i].cap_list[j].chain_mask_2G = 11409 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 11410 11411 chainmask_table[i].cap_list[j].chain_mask_5G = 11412 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 11413 11414 chainmask_table[i].cap_list[j].chain_mask_tx = 11415 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 11416 11417 chainmask_table[i].cap_list[j].chain_mask_rx = 11418 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 11419 11420 chainmask_table[i].cap_list[j].supports_aDFS = 11421 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 11422 11423 chainmask_table[i].cap_list[j].supports_aSpectral = 11424 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 11425 11426 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 11427 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 11428 11429 chainmask_table[i].cap_list[j].supports_aDFS_160 = 11430 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 11431 11432 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 11433 chainmask_caps); 11434 11435 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 11436 chainmask_caps->supported_flags, 11437 chainmask_caps->chainmask); 11438 chainmask_caps++; 11439 } 11440 } 11441 11442 return QDF_STATUS_SUCCESS; 11443 } 11444 11445 /** 11446 * extract_service_ready_ext_tlv() - extract basic extended service ready params 11447 * from event 11448 * @wmi_handle: wmi handle 11449 * @param evt_buf: pointer to event buffer 11450 * @param param: Pointer to hold evt buf 11451 * 11452 * Return: QDF_STATUS_SUCCESS for success or error code 11453 */ 11454 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 11455 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 11456 { 11457 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11458 wmi_service_ready_ext_event_fixed_param *ev; 11459 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11460 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 11461 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 11462 uint8_t i = 0; 11463 11464 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11465 if (!param_buf) 11466 return QDF_STATUS_E_INVAL; 11467 11468 ev = param_buf->fixed_param; 11469 if (!ev) 11470 return QDF_STATUS_E_INVAL; 11471 11472 /* Move this to host based bitmap */ 11473 param->default_conc_scan_config_bits = 11474 ev->default_conc_scan_config_bits; 11475 param->default_fw_config_bits = ev->default_fw_config_bits; 11476 param->he_cap_info = ev->he_cap_info; 11477 param->mpdu_density = ev->mpdu_density; 11478 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 11479 param->fw_build_vers_ext = ev->fw_build_vers_ext; 11480 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 11481 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 11482 param->max_bssid_indicator = ev->max_bssid_indicator; 11483 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 11484 11485 hw_caps = param_buf->soc_hw_mode_caps; 11486 if (hw_caps) 11487 param->num_hw_modes = hw_caps->num_hw_modes; 11488 else 11489 param->num_hw_modes = 0; 11490 11491 reg_caps = param_buf->soc_hal_reg_caps; 11492 if (reg_caps) 11493 param->num_phy = reg_caps->num_phy; 11494 else 11495 param->num_phy = 0; 11496 11497 if (hw_caps) { 11498 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 11499 wmi_nofl_debug("Num chain mask tables: %d", 11500 hw_caps->num_chainmask_tables); 11501 } else 11502 param->num_chainmask_tables = 0; 11503 11504 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 11505 param->num_chainmask_tables > 11506 param_buf->num_mac_phy_chainmask_combo) { 11507 wmi_err_rl("num_chainmask_tables is OOB: %u", 11508 param->num_chainmask_tables); 11509 return QDF_STATUS_E_INVAL; 11510 } 11511 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 11512 11513 if (!chain_mask_combo) 11514 return QDF_STATUS_SUCCESS; 11515 11516 wmi_nofl_debug("Dumping chain mask combo data"); 11517 11518 for (i = 0; i < param->num_chainmask_tables; i++) { 11519 11520 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 11521 chain_mask_combo->chainmask_table_id, 11522 chain_mask_combo->num_valid_chainmask); 11523 11524 param->chainmask_table[i].table_id = 11525 chain_mask_combo->chainmask_table_id; 11526 param->chainmask_table[i].num_valid_chainmasks = 11527 chain_mask_combo->num_valid_chainmask; 11528 chain_mask_combo++; 11529 } 11530 wmi_nofl_debug("chain mask combo end"); 11531 11532 return QDF_STATUS_SUCCESS; 11533 } 11534 11535 /** 11536 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 11537 * event 11538 * @wmi_handle: wmi handle 11539 * @event: pointer to event buffer 11540 * @param: Pointer to hold the params 11541 * 11542 * Return: QDF_STATUS_SUCCESS for success or error code 11543 */ 11544 static QDF_STATUS 11545 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 11546 struct wlan_psoc_host_service_ext2_param *param) 11547 { 11548 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11549 wmi_service_ready_ext2_event_fixed_param *ev; 11550 11551 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11552 if (!param_buf) 11553 return QDF_STATUS_E_INVAL; 11554 11555 ev = param_buf->fixed_param; 11556 if (!ev) 11557 return QDF_STATUS_E_INVAL; 11558 11559 param->reg_db_version_major = 11560 WMI_REG_DB_VERSION_MAJOR_GET( 11561 ev->reg_db_version); 11562 param->reg_db_version_minor = 11563 WMI_REG_DB_VERSION_MINOR_GET( 11564 ev->reg_db_version); 11565 param->bdf_reg_db_version_major = 11566 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 11567 ev->reg_db_version); 11568 param->bdf_reg_db_version_minor = 11569 WMI_BDF_REG_DB_VERSION_MINOR_GET( 11570 ev->reg_db_version); 11571 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 11572 11573 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 11574 11575 if (param_buf->nan_cap) 11576 param->max_ndp_sessions = 11577 param_buf->nan_cap->max_ndp_sessions; 11578 else 11579 param->max_ndp_sessions = 0; 11580 11581 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 11582 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 11583 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 11584 ev->max_user_per_ppdu_ofdma); 11585 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 11586 ev->max_user_per_ppdu_ofdma); 11587 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 11588 ev->max_user_per_ppdu_mumimo); 11589 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 11590 ev->max_user_per_ppdu_mumimo); 11591 param->target_cap_flags = ev->target_cap_flags; 11592 wmi_debug("htt peer data :%d", ev->target_cap_flags); 11593 return QDF_STATUS_SUCCESS; 11594 } 11595 11596 /** 11597 * extract_sar_cap_service_ready_ext_tlv() - 11598 * extract SAR cap from service ready event 11599 * @wmi_handle: wmi handle 11600 * @event: pointer to event buffer 11601 * @ext_param: extended target info 11602 * 11603 * Return: QDF_STATUS_SUCCESS for success or error code 11604 */ 11605 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 11606 wmi_unified_t wmi_handle, 11607 uint8_t *event, 11608 struct wlan_psoc_host_service_ext_param *ext_param) 11609 { 11610 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11611 WMI_SAR_CAPABILITIES *sar_caps; 11612 11613 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 11614 11615 if (!param_buf) 11616 return QDF_STATUS_E_INVAL; 11617 11618 sar_caps = param_buf->sar_caps; 11619 if (sar_caps) 11620 ext_param->sar_version = sar_caps->active_version; 11621 else 11622 ext_param->sar_version = 0; 11623 11624 return QDF_STATUS_SUCCESS; 11625 } 11626 11627 /** 11628 * extract_hw_mode_cap_service_ready_ext_tlv() - 11629 * extract HW mode cap from service ready event 11630 * @wmi_handle: wmi handle 11631 * @param evt_buf: pointer to event buffer 11632 * @param param: Pointer to hold evt buf 11633 * @param hw_mode_idx: hw mode idx should be less than num_mode 11634 * 11635 * Return: QDF_STATUS_SUCCESS for success or error code 11636 */ 11637 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 11638 wmi_unified_t wmi_handle, 11639 uint8_t *event, uint8_t hw_mode_idx, 11640 struct wlan_psoc_host_hw_mode_caps *param) 11641 { 11642 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11643 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11644 11645 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11646 if (!param_buf) 11647 return QDF_STATUS_E_INVAL; 11648 11649 hw_caps = param_buf->soc_hw_mode_caps; 11650 if (!hw_caps) 11651 return QDF_STATUS_E_INVAL; 11652 11653 if (!hw_caps->num_hw_modes || 11654 !param_buf->hw_mode_caps || 11655 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 11656 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 11657 return QDF_STATUS_E_INVAL; 11658 11659 if (hw_mode_idx >= hw_caps->num_hw_modes) 11660 return QDF_STATUS_E_INVAL; 11661 11662 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 11663 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 11664 11665 param->hw_mode_config_type = 11666 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 11667 11668 return QDF_STATUS_SUCCESS; 11669 } 11670 11671 /** 11672 * extract_mac_phy_cap_service_ready_11be_support - api to extract 11be support 11673 * @param param: host mac phy capabilities 11674 * @param mac_phy_caps: mac phy capabilities 11675 * 11676 * Return: void 11677 */ 11678 #ifdef WLAN_FEATURE_11BE 11679 static void 11680 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 11681 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 11682 { 11683 param->supports_11be = 11684 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 11685 11686 wmi_debug("11be support %d", param->supports_11be); 11687 } 11688 #else 11689 static void 11690 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 11691 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 11692 { 11693 } 11694 #endif 11695 11696 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 11697 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 11698 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 11699 { 11700 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 11701 } 11702 #else 11703 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 11704 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 11705 { 11706 } 11707 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 11708 11709 /** 11710 * extract_mac_phy_cap_service_ready_ext_tlv() - 11711 * extract MAC phy cap from service ready event 11712 * @wmi_handle: wmi handle 11713 * @param evt_buf: pointer to event buffer 11714 * @param param: Pointer to hold evt buf 11715 * @param hw_mode_idx: hw mode idx should be less than num_mode 11716 * @param phy_id: phy id within hw_mode 11717 * 11718 * Return: QDF_STATUS_SUCCESS for success or error code 11719 */ 11720 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 11721 wmi_unified_t wmi_handle, 11722 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 11723 struct wlan_psoc_host_mac_phy_caps *param) 11724 { 11725 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11726 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 11727 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11728 uint32_t phy_map; 11729 uint8_t hw_idx, phy_idx = 0, pdev_id; 11730 11731 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11732 if (!param_buf) 11733 return QDF_STATUS_E_INVAL; 11734 11735 hw_caps = param_buf->soc_hw_mode_caps; 11736 if (!hw_caps) 11737 return QDF_STATUS_E_INVAL; 11738 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 11739 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 11740 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 11741 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 11742 return QDF_STATUS_E_INVAL; 11743 } 11744 11745 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 11746 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 11747 break; 11748 11749 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 11750 while (phy_map) { 11751 phy_map >>= 1; 11752 phy_idx++; 11753 } 11754 } 11755 11756 if (hw_idx == hw_caps->num_hw_modes) 11757 return QDF_STATUS_E_INVAL; 11758 11759 phy_idx += phy_id; 11760 if (phy_idx >= param_buf->num_mac_phy_caps) 11761 return QDF_STATUS_E_INVAL; 11762 11763 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 11764 11765 param->hw_mode_id = mac_phy_caps->hw_mode_id; 11766 param->phy_idx = phy_idx; 11767 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 11768 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11769 wmi_handle, 11770 pdev_id); 11771 param->tgt_pdev_id = pdev_id; 11772 extract_hw_link_id(param, mac_phy_caps); 11773 param->phy_id = mac_phy_caps->phy_id; 11774 param->supports_11b = 11775 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 11776 param->supports_11g = 11777 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 11778 param->supports_11a = 11779 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 11780 param->supports_11n = 11781 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 11782 param->supports_11ac = 11783 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 11784 param->supports_11ax = 11785 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 11786 11787 extract_service_ready_11be_support(param, mac_phy_caps); 11788 11789 param->supported_bands = mac_phy_caps->supported_bands; 11790 param->ampdu_density = mac_phy_caps->ampdu_density; 11791 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 11792 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 11793 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 11794 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 11795 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 11796 mac_phy_caps->he_cap_info_2G; 11797 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 11798 mac_phy_caps->he_cap_info_2G_ext; 11799 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 11800 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 11801 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 11802 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 11803 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 11804 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 11805 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 11806 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 11807 mac_phy_caps->he_cap_info_5G; 11808 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 11809 mac_phy_caps->he_cap_info_5G_ext; 11810 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 11811 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 11812 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 11813 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 11814 qdf_mem_copy(¶m->he_cap_phy_info_2G, 11815 &mac_phy_caps->he_cap_phy_info_2G, 11816 sizeof(param->he_cap_phy_info_2G)); 11817 qdf_mem_copy(¶m->he_cap_phy_info_5G, 11818 &mac_phy_caps->he_cap_phy_info_5G, 11819 sizeof(param->he_cap_phy_info_5G)); 11820 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 11821 sizeof(param->he_ppet2G)); 11822 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 11823 sizeof(param->he_ppet5G)); 11824 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 11825 param->lmac_id = mac_phy_caps->lmac_id; 11826 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 11827 (mac_phy_caps->wireless_modes); 11828 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 11829 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 11830 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 11831 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 11832 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 11833 mac_phy_caps->nss_ratio); 11834 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 11835 11836 return QDF_STATUS_SUCCESS; 11837 } 11838 11839 /** 11840 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 11841 * @param param: host ext2 mac phy capabilities 11842 * @param mac_phy_caps: ext mac phy capabilities 11843 * 11844 * Return: void 11845 */ 11846 #ifdef WLAN_FEATURE_11BE 11847 static void extract_mac_phy_cap_ehtcaps( 11848 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 11849 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 11850 { 11851 uint32_t i; 11852 11853 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 11854 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 11855 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 11856 11857 qdf_mem_copy(¶m->eht_cap_info_2G, 11858 &mac_phy_caps->eht_cap_mac_info_2G, 11859 sizeof(param->eht_cap_info_2G)); 11860 qdf_mem_copy(¶m->eht_cap_info_5G, 11861 &mac_phy_caps->eht_cap_mac_info_5G, 11862 sizeof(param->eht_cap_info_5G)); 11863 11864 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 11865 &mac_phy_caps->eht_cap_phy_info_2G, 11866 sizeof(param->eht_cap_phy_info_2G)); 11867 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 11868 &mac_phy_caps->eht_cap_phy_info_5G, 11869 sizeof(param->eht_cap_phy_info_5G)); 11870 11871 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", 11872 mac_phy_caps->eht_cap_mac_info_2G[0], 11873 mac_phy_caps->eht_cap_mac_info_5G[0], 11874 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 11875 mac_phy_caps->eht_cap_info_internal); 11876 11877 wmi_nofl_debug("EHT phy caps: "); 11878 11879 wmi_nofl_debug("2G: "); 11880 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 11881 wmi_nofl_debug("index %d value %d", 11882 i, param->eht_cap_phy_info_2G[i]); 11883 } 11884 wmi_nofl_debug("5G: "); 11885 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 11886 wmi_nofl_debug("index %d value %d", 11887 i, param->eht_cap_phy_info_5G[i]); 11888 } 11889 } 11890 #else 11891 static void extract_mac_phy_cap_ehtcaps( 11892 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 11893 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 11894 { 11895 } 11896 #endif 11897 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 11898 wmi_unified_t wmi_handle, 11899 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 11900 uint8_t phy_idx, 11901 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 11902 { 11903 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11904 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 11905 11906 if (!event) { 11907 wmi_err("null evt_buf"); 11908 return QDF_STATUS_E_INVAL; 11909 } 11910 11911 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11912 11913 if (!param_buf->num_mac_phy_caps) 11914 return QDF_STATUS_SUCCESS; 11915 11916 if (phy_idx >= param_buf->num_mac_phy_caps) 11917 return QDF_STATUS_E_INVAL; 11918 11919 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 11920 11921 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 11922 (phy_id != mac_phy_caps->phy_id)) 11923 return QDF_STATUS_E_INVAL; 11924 11925 param->hw_mode_id = mac_phy_caps->hw_mode_id; 11926 param->phy_id = mac_phy_caps->phy_id; 11927 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11928 wmi_handle, mac_phy_caps->pdev_id); 11929 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 11930 mac_phy_caps->wireless_modes_ext); 11931 11932 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 11933 11934 return QDF_STATUS_SUCCESS; 11935 } 11936 11937 /** 11938 * extract_reg_cap_service_ready_ext_tlv() - 11939 * extract REG cap from service ready event 11940 * @wmi_handle: wmi handle 11941 * @param evt_buf: pointer to event buffer 11942 * @param param: Pointer to hold evt buf 11943 * @param phy_idx: phy idx should be less than num_mode 11944 * 11945 * Return: QDF_STATUS_SUCCESS for success or error code 11946 */ 11947 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 11948 wmi_unified_t wmi_handle, 11949 uint8_t *event, uint8_t phy_idx, 11950 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 11951 { 11952 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11953 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 11954 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 11955 11956 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11957 if (!param_buf) 11958 return QDF_STATUS_E_INVAL; 11959 11960 reg_caps = param_buf->soc_hal_reg_caps; 11961 if (!reg_caps) 11962 return QDF_STATUS_E_INVAL; 11963 11964 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 11965 return QDF_STATUS_E_INVAL; 11966 11967 if (phy_idx >= reg_caps->num_phy) 11968 return QDF_STATUS_E_INVAL; 11969 11970 if (!param_buf->hal_reg_caps) 11971 return QDF_STATUS_E_INVAL; 11972 11973 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 11974 11975 param->phy_id = ext_reg_cap->phy_id; 11976 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 11977 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 11978 param->regcap1 = ext_reg_cap->regcap1; 11979 param->regcap2 = ext_reg_cap->regcap2; 11980 param->wireless_modes = convert_wireless_modes_tlv( 11981 ext_reg_cap->wireless_modes); 11982 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 11983 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 11984 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 11985 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 11986 11987 return QDF_STATUS_SUCCESS; 11988 } 11989 11990 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 11991 uint8_t num_dma_ring_caps) 11992 { 11993 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 11994 if (!num_dma_ring_caps) { 11995 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 11996 return QDF_STATUS_E_INVAL; 11997 } 11998 if (idx >= num_dma_ring_caps) { 11999 wmi_err("Index %d exceeds range", idx); 12000 return QDF_STATUS_E_INVAL; 12001 } 12002 return QDF_STATUS_SUCCESS; 12003 } 12004 12005 static void 12006 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 12007 struct wlan_psoc_host_dbr_ring_caps *param, 12008 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 12009 { 12010 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 12011 wmi_handle, 12012 dbr_ring_caps->pdev_id); 12013 param->mod_id = dbr_ring_caps->mod_id; 12014 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 12015 param->min_buf_size = dbr_ring_caps->min_buf_size; 12016 param->min_buf_align = dbr_ring_caps->min_buf_align; 12017 } 12018 12019 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 12020 wmi_unified_t wmi_handle, 12021 uint8_t *event, uint8_t idx, 12022 struct wlan_psoc_host_dbr_ring_caps *param) 12023 { 12024 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 12025 QDF_STATUS status; 12026 12027 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 12028 if (!param_buf) 12029 return QDF_STATUS_E_INVAL; 12030 12031 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 12032 if (status != QDF_STATUS_SUCCESS) 12033 return status; 12034 12035 populate_dbr_ring_cap_elems(wmi_handle, param, 12036 ¶m_buf->dma_ring_caps[idx]); 12037 return QDF_STATUS_SUCCESS; 12038 } 12039 12040 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 12041 wmi_unified_t wmi_handle, 12042 uint8_t *event, uint8_t idx, 12043 struct wlan_psoc_host_dbr_ring_caps *param) 12044 { 12045 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12046 QDF_STATUS status; 12047 12048 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12049 if (!param_buf) 12050 return QDF_STATUS_E_INVAL; 12051 12052 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 12053 if (status != QDF_STATUS_SUCCESS) 12054 return status; 12055 12056 populate_dbr_ring_cap_elems(wmi_handle, param, 12057 ¶m_buf->dma_ring_caps[idx]); 12058 return QDF_STATUS_SUCCESS; 12059 } 12060 12061 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 12062 wmi_unified_t wmi_handle, 12063 uint8_t *event, uint8_t idx, 12064 struct wlan_psoc_host_scan_radio_caps *param) 12065 { 12066 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 12067 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 12068 12069 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 12070 if (!param_buf) 12071 return QDF_STATUS_E_INVAL; 12072 12073 if (idx >= param_buf->num_wmi_scan_radio_caps) 12074 return QDF_STATUS_E_INVAL; 12075 12076 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 12077 param->phy_id = scan_radio_caps->phy_id; 12078 param->scan_radio_supported = 12079 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 12080 param->dfs_en = 12081 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 12082 12083 return QDF_STATUS_SUCCESS; 12084 } 12085 12086 /** 12087 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 12088 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 12089 * 12090 * Return: host thermal throt level 12091 */ 12092 static enum thermal_throttle_level 12093 wmi_tgt_thermal_level_to_host(uint32_t level) 12094 { 12095 switch (level) { 12096 case WMI_THERMAL_FULLPERF: 12097 return THERMAL_FULLPERF; 12098 case WMI_THERMAL_MITIGATION: 12099 return THERMAL_MITIGATION; 12100 case WMI_THERMAL_SHUTOFF: 12101 return THERMAL_SHUTOFF; 12102 case WMI_THERMAL_SHUTDOWN_TGT: 12103 return THERMAL_SHUTDOWN_TARGET; 12104 default: 12105 return THERMAL_UNKNOWN; 12106 } 12107 } 12108 12109 #ifdef THERMAL_STATS_SUPPORT 12110 static void 12111 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 12112 uint32_t *therm_throt_levels, 12113 struct thermal_throt_level_stats *tt_temp_range_stats) 12114 { 12115 uint8_t lvl_idx; 12116 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 12117 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 12118 12119 tt_stats_event = param_buf->fixed_param; 12120 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 12121 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 12122 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 12123 tt_stats_event->therm_throt_levels; 12124 12125 wmi_tt_stats = param_buf->temp_range_stats; 12126 if (!wmi_tt_stats) { 12127 wmi_err("wmi_tt_stats Null"); 12128 return; 12129 } 12130 12131 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 12132 tt_temp_range_stats[lvl_idx].start_temp_level = 12133 wmi_tt_stats[lvl_idx].start_temp_level; 12134 tt_temp_range_stats[lvl_idx].end_temp_level = 12135 wmi_tt_stats[lvl_idx].end_temp_level; 12136 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 12137 wmi_tt_stats[lvl_idx].total_time_ms_lo; 12138 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 12139 wmi_tt_stats[lvl_idx].total_time_ms_hi; 12140 tt_temp_range_stats[lvl_idx].num_entry = 12141 wmi_tt_stats[lvl_idx].num_entry; 12142 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 12143 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 12144 wmi_tt_stats[lvl_idx].end_temp_level, 12145 wmi_tt_stats[lvl_idx].total_time_ms_lo, 12146 wmi_tt_stats[lvl_idx].total_time_ms_hi, 12147 wmi_tt_stats[lvl_idx].num_entry); 12148 } 12149 } 12150 #else 12151 static void 12152 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 12153 uint32_t *therm_throt_levels, 12154 struct thermal_throt_level_stats *tt_temp_range_stats) 12155 { 12156 } 12157 #endif 12158 12159 /** 12160 * extract_thermal_stats_tlv() - extract thermal stats from event 12161 * @wmi_handle: wmi handle 12162 * @param evt_buf: Pointer to event buffer 12163 * @param temp: Pointer to hold extracted temperature 12164 * @param level: Pointer to hold extracted level in host enum 12165 * @param therm_throt_levels: Pointer to hold extracted thermal throttle temp 12166 * range 12167 * @param tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 12168 * every level 12169 * 12170 * Return: 0 for success or error code 12171 */ 12172 static QDF_STATUS 12173 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 12174 void *evt_buf, uint32_t *temp, 12175 enum thermal_throttle_level *level, 12176 uint32_t *therm_throt_levels, 12177 struct thermal_throt_level_stats *tt_temp_range_stats_event, 12178 uint32_t *pdev_id) 12179 { 12180 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 12181 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 12182 12183 param_buf = 12184 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 12185 if (!param_buf) 12186 return QDF_STATUS_E_INVAL; 12187 12188 tt_stats_event = param_buf->fixed_param; 12189 wmi_debug("thermal temperature %d level %d", 12190 tt_stats_event->temp, tt_stats_event->level); 12191 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12192 wmi_handle, 12193 tt_stats_event->pdev_id); 12194 *temp = tt_stats_event->temp; 12195 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 12196 12197 if (tt_stats_event->therm_throt_levels) 12198 populate_thermal_stats(param_buf, therm_throt_levels, 12199 tt_temp_range_stats_event); 12200 12201 return QDF_STATUS_SUCCESS; 12202 } 12203 12204 /** 12205 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 12206 * @wmi_handle: wmi handle 12207 * @param evt_buf: pointer to event buffer 12208 * @param idx: Index to level stats 12209 * @param levelcount: Pointer to hold levelcount 12210 * @param dccount: Pointer to hold dccount 12211 * 12212 * Return: 0 for success or error code 12213 */ 12214 static QDF_STATUS 12215 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 12216 void *evt_buf, uint8_t idx, uint32_t *levelcount, 12217 uint32_t *dccount) 12218 { 12219 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 12220 wmi_therm_throt_level_stats_info *tt_level_info; 12221 12222 param_buf = 12223 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 12224 if (!param_buf) 12225 return QDF_STATUS_E_INVAL; 12226 12227 tt_level_info = param_buf->therm_throt_level_stats_info; 12228 12229 if (idx < THERMAL_LEVELS) { 12230 *levelcount = tt_level_info[idx].level_count; 12231 *dccount = tt_level_info[idx].dc_count; 12232 return QDF_STATUS_SUCCESS; 12233 } 12234 12235 return QDF_STATUS_E_FAILURE; 12236 } 12237 #ifdef BIG_ENDIAN_HOST 12238 /** 12239 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 12240 * @param data_len - data length 12241 * @param data - pointer to data 12242 * 12243 * Return: QDF_STATUS - success or error status 12244 */ 12245 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 12246 { 12247 uint8_t *data_aligned = NULL; 12248 int c; 12249 unsigned char *data_unaligned; 12250 12251 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 12252 FIPS_ALIGN)); 12253 /* Assigning unaligned space to copy the data */ 12254 /* Checking if kmalloc does successful allocation */ 12255 if (!data_unaligned) 12256 return QDF_STATUS_E_FAILURE; 12257 12258 /* Checking if space is alligned */ 12259 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 12260 /* align the data space */ 12261 data_aligned = 12262 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 12263 } else { 12264 data_aligned = (u_int8_t *)data_unaligned; 12265 } 12266 12267 /* memset and copy content from data to data aligned */ 12268 OS_MEMSET(data_aligned, 0, data_len); 12269 OS_MEMCPY(data_aligned, data, data_len); 12270 /* Endianness to LE */ 12271 for (c = 0; c < data_len/4; c++) { 12272 *((u_int32_t *)data_aligned + c) = 12273 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 12274 } 12275 12276 /* Copy content to event->data */ 12277 OS_MEMCPY(data, data_aligned, data_len); 12278 12279 /* clean up allocated space */ 12280 qdf_mem_free(data_unaligned); 12281 data_aligned = NULL; 12282 data_unaligned = NULL; 12283 12284 /*************************************************************/ 12285 12286 return QDF_STATUS_SUCCESS; 12287 } 12288 #else 12289 /** 12290 * fips_conv_data_be() - DUMMY for LE platform 12291 * 12292 * Return: QDF_STATUS - success 12293 */ 12294 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 12295 { 12296 return QDF_STATUS_SUCCESS; 12297 } 12298 #endif 12299 12300 /** 12301 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 12302 * @wmi_handle - wmi handle 12303 * @params - PN request params for peer 12304 * 12305 * Return: QDF_STATUS - success or error status 12306 */ 12307 static QDF_STATUS 12308 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 12309 struct peer_request_pn_param *params) 12310 { 12311 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 12312 wmi_buf_t buf; 12313 uint8_t *buf_ptr; 12314 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 12315 12316 buf = wmi_buf_alloc(wmi_handle, len); 12317 if (!buf) { 12318 wmi_err("wmi_buf_alloc failed"); 12319 return QDF_STATUS_E_FAILURE; 12320 } 12321 12322 buf_ptr = (uint8_t *)wmi_buf_data(buf); 12323 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 12324 12325 WMITLV_SET_HDR(&cmd->tlv_header, 12326 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 12327 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 12328 12329 cmd->vdev_id = params->vdev_id; 12330 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 12331 cmd->key_type = params->key_type; 12332 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12333 WMI_PEER_TX_PN_REQUEST_CMDID)) { 12334 wmi_err("Failed to send WMI command"); 12335 wmi_buf_free(buf); 12336 return QDF_STATUS_E_FAILURE; 12337 } 12338 return QDF_STATUS_SUCCESS; 12339 } 12340 12341 /** 12342 * extract_get_pn_data_tlv() - extract pn resp 12343 * @wmi_handle - wmi handle 12344 * @params - PN response params for peer 12345 * 12346 * Return: QDF_STATUS - success or error status 12347 */ 12348 static QDF_STATUS 12349 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12350 struct wmi_host_get_pn_event *param) 12351 { 12352 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 12353 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 12354 12355 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 12356 event = 12357 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 12358 12359 param->vdev_id = event->vdev_id; 12360 param->key_type = event->key_type; 12361 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 12362 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 12363 12364 return QDF_STATUS_SUCCESS; 12365 } 12366 12367 /** 12368 * extract_fips_event_data_tlv() - extract fips event data 12369 * @wmi_handle: wmi handle 12370 * @param evt_buf: pointer to event buffer 12371 * @param param: pointer FIPS event params 12372 * 12373 * Return: 0 for success or error code 12374 */ 12375 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 12376 void *evt_buf, struct wmi_host_fips_event_param *param) 12377 { 12378 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 12379 wmi_pdev_fips_event_fixed_param *event; 12380 12381 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 12382 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 12383 12384 if (event->data_len > param_buf->num_data) 12385 return QDF_STATUS_E_FAILURE; 12386 12387 if (fips_conv_data_be(event->data_len, param_buf->data) != 12388 QDF_STATUS_SUCCESS) 12389 return QDF_STATUS_E_FAILURE; 12390 12391 param->data = (uint32_t *)param_buf->data; 12392 param->data_len = event->data_len; 12393 param->error_status = event->error_status; 12394 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 12395 wmi_handle, 12396 event->pdev_id); 12397 12398 return QDF_STATUS_SUCCESS; 12399 } 12400 12401 #ifdef WLAN_FEATURE_DISA 12402 /** 12403 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 12404 * params from event 12405 * @wmi_handle: wmi handle 12406 * @evt_buf: pointer to event buffer 12407 * @resp: Pointer to hold resp parameters 12408 * 12409 * Return: QDF_STATUS_SUCCESS for success or error code 12410 */ 12411 static QDF_STATUS 12412 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 12413 void *evt_buf, 12414 struct disa_encrypt_decrypt_resp_params 12415 *resp) 12416 { 12417 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 12418 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 12419 12420 param_buf = evt_buf; 12421 if (!param_buf) { 12422 wmi_err("encrypt decrypt resp evt_buf is NULL"); 12423 return QDF_STATUS_E_INVAL; 12424 } 12425 12426 data_event = param_buf->fixed_param; 12427 12428 resp->vdev_id = data_event->vdev_id; 12429 resp->status = data_event->status; 12430 12431 if ((data_event->data_length > param_buf->num_enc80211_frame) || 12432 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 12433 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 12434 wmi_err("FW msg data_len %d more than TLV hdr %d", 12435 data_event->data_length, 12436 param_buf->num_enc80211_frame); 12437 return QDF_STATUS_E_INVAL; 12438 } 12439 12440 resp->data_len = data_event->data_length; 12441 12442 if (resp->data_len) 12443 resp->data = (uint8_t *)param_buf->enc80211_frame; 12444 12445 return QDF_STATUS_SUCCESS; 12446 } 12447 #endif /* WLAN_FEATURE_DISA */ 12448 12449 static bool is_management_record_tlv(uint32_t cmd_id) 12450 { 12451 switch (cmd_id) { 12452 case WMI_MGMT_TX_SEND_CMDID: 12453 case WMI_MGMT_TX_COMPLETION_EVENTID: 12454 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 12455 case WMI_MGMT_RX_EVENTID: 12456 return true; 12457 default: 12458 return false; 12459 } 12460 } 12461 12462 static bool is_diag_event_tlv(uint32_t event_id) 12463 { 12464 if (WMI_DIAG_EVENTID == event_id) 12465 return true; 12466 12467 return false; 12468 } 12469 12470 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 12471 { 12472 uint16_t tag = 0; 12473 12474 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 12475 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 12476 __func__); 12477 return tag; 12478 } 12479 12480 if (wmi_handle->tag_crash_inject) 12481 tag = HTC_TX_PACKET_TAG_AUTO_PM; 12482 12483 wmi_handle->tag_crash_inject = false; 12484 return tag; 12485 } 12486 12487 /** 12488 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 12489 * @wmi_handle: WMI handle 12490 * @buf: WMI buffer 12491 * @cmd_id: WMI command Id 12492 * 12493 * Return htc_tx_tag 12494 */ 12495 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 12496 wmi_buf_t buf, 12497 uint32_t cmd_id) 12498 { 12499 uint16_t htc_tx_tag = 0; 12500 12501 switch (cmd_id) { 12502 case WMI_WOW_ENABLE_CMDID: 12503 case WMI_PDEV_SUSPEND_CMDID: 12504 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 12505 case WMI_PDEV_RESUME_CMDID: 12506 case WMI_HB_SET_ENABLE_CMDID: 12507 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 12508 #ifdef FEATURE_WLAN_D0WOW 12509 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 12510 #endif 12511 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 12512 break; 12513 case WMI_FORCE_FW_HANG_CMDID: 12514 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 12515 break; 12516 default: 12517 break; 12518 } 12519 12520 return htc_tx_tag; 12521 } 12522 12523 #ifdef CONFIG_BAND_6GHZ 12524 static struct cur_reg_rule 12525 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 12526 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 12527 { 12528 struct cur_reg_rule *reg_rule_ptr; 12529 uint32_t count; 12530 12531 if (!num_reg_rules) 12532 return NULL; 12533 12534 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 12535 sizeof(*reg_rule_ptr)); 12536 12537 if (!reg_rule_ptr) 12538 return NULL; 12539 12540 for (count = 0; count < num_reg_rules; count++) { 12541 reg_rule_ptr[count].start_freq = 12542 WMI_REG_RULE_START_FREQ_GET( 12543 wmi_reg_rule[count].freq_info); 12544 reg_rule_ptr[count].end_freq = 12545 WMI_REG_RULE_END_FREQ_GET( 12546 wmi_reg_rule[count].freq_info); 12547 reg_rule_ptr[count].max_bw = 12548 WMI_REG_RULE_MAX_BW_GET( 12549 wmi_reg_rule[count].bw_pwr_info); 12550 reg_rule_ptr[count].reg_power = 12551 WMI_REG_RULE_REG_POWER_GET( 12552 wmi_reg_rule[count].bw_pwr_info); 12553 reg_rule_ptr[count].ant_gain = 12554 WMI_REG_RULE_ANTENNA_GAIN_GET( 12555 wmi_reg_rule[count].bw_pwr_info); 12556 reg_rule_ptr[count].flags = 12557 WMI_REG_RULE_FLAGS_GET( 12558 wmi_reg_rule[count].flag_info); 12559 reg_rule_ptr[count].psd_flag = 12560 WMI_REG_RULE_PSD_FLAG_GET( 12561 wmi_reg_rule[count].psd_power_info); 12562 reg_rule_ptr[count].psd_eirp = 12563 WMI_REG_RULE_PSD_EIRP_GET( 12564 wmi_reg_rule[count].psd_power_info); 12565 } 12566 12567 return reg_rule_ptr; 12568 } 12569 #endif 12570 12571 static struct cur_reg_rule 12572 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 12573 wmi_regulatory_rule_struct *wmi_reg_rule) 12574 { 12575 struct cur_reg_rule *reg_rule_ptr; 12576 uint32_t count; 12577 12578 if (!num_reg_rules) 12579 return NULL; 12580 12581 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 12582 sizeof(*reg_rule_ptr)); 12583 12584 if (!reg_rule_ptr) 12585 return NULL; 12586 12587 for (count = 0; count < num_reg_rules; count++) { 12588 reg_rule_ptr[count].start_freq = 12589 WMI_REG_RULE_START_FREQ_GET( 12590 wmi_reg_rule[count].freq_info); 12591 reg_rule_ptr[count].end_freq = 12592 WMI_REG_RULE_END_FREQ_GET( 12593 wmi_reg_rule[count].freq_info); 12594 reg_rule_ptr[count].max_bw = 12595 WMI_REG_RULE_MAX_BW_GET( 12596 wmi_reg_rule[count].bw_pwr_info); 12597 reg_rule_ptr[count].reg_power = 12598 WMI_REG_RULE_REG_POWER_GET( 12599 wmi_reg_rule[count].bw_pwr_info); 12600 reg_rule_ptr[count].ant_gain = 12601 WMI_REG_RULE_ANTENNA_GAIN_GET( 12602 wmi_reg_rule[count].bw_pwr_info); 12603 reg_rule_ptr[count].flags = 12604 WMI_REG_RULE_FLAGS_GET( 12605 wmi_reg_rule[count].flag_info); 12606 } 12607 12608 return reg_rule_ptr; 12609 } 12610 12611 static enum cc_setting_code wmi_reg_status_to_reg_status( 12612 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 12613 { 12614 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) 12615 return REG_SET_CC_STATUS_PASS; 12616 else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 12617 return REG_CURRENT_ALPHA2_NOT_FOUND; 12618 else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) 12619 return REG_INIT_ALPHA2_NOT_FOUND; 12620 else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 12621 return REG_SET_CC_CHANGE_NOT_ALLOWED; 12622 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) 12623 return REG_SET_CC_STATUS_NO_MEMORY; 12624 else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) 12625 return REG_SET_CC_STATUS_FAIL; 12626 12627 wmi_debug("Unknown reg status code from WMI"); 12628 return REG_SET_CC_STATUS_FAIL; 12629 } 12630 12631 #ifdef CONFIG_BAND_6GHZ 12632 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 12633 wmi_unified_t wmi_handle, uint8_t *evt_buf, 12634 struct cur_regulatory_info *reg_info, uint32_t len) 12635 { 12636 uint32_t i, j, k; 12637 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 12638 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 12639 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 12640 uint32_t num_2g_reg_rules, num_5g_reg_rules; 12641 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 12642 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 12643 uint32_t total_reg_rules = 0; 12644 12645 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 12646 if (!param_buf) { 12647 wmi_err("invalid channel list event buf"); 12648 return QDF_STATUS_E_FAILURE; 12649 } 12650 12651 ext_chan_list_event_hdr = param_buf->fixed_param; 12652 12653 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 12654 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 12655 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 12656 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 12657 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 12658 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 12659 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 12660 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 12661 12662 wmi_debug("num reg rules from fw"); 12663 wmi_debug("AP SP %d, LPI %d, VLP %d", 12664 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 12665 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 12666 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 12667 12668 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 12669 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 12670 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 12671 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 12672 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 12673 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 12674 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 12675 wmi_debug("client %d SP %d, LPI %d, VLP %d", i, 12676 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 12677 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 12678 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 12679 } 12680 12681 num_2g_reg_rules = reg_info->num_2g_reg_rules; 12682 total_reg_rules += num_2g_reg_rules; 12683 num_5g_reg_rules = reg_info->num_5g_reg_rules; 12684 total_reg_rules += num_5g_reg_rules; 12685 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 12686 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 12687 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 12688 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 12689 num_6g_reg_rules_ap[i]); 12690 return QDF_STATUS_E_FAILURE; 12691 } 12692 total_reg_rules += num_6g_reg_rules_ap[i]; 12693 num_6g_reg_rules_client[i] = 12694 reg_info->num_6g_reg_rules_client[i]; 12695 } 12696 12697 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 12698 total_reg_rules += 12699 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 12700 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 12701 total_reg_rules += 12702 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 12703 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 12704 MAX_6G_REG_RULES) || 12705 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 12706 MAX_6G_REG_RULES) || 12707 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 12708 MAX_6G_REG_RULES)) { 12709 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", 12710 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 12711 num_6g_reg_rules_client[REG_INDOOR_AP][i], 12712 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 12713 i); 12714 return QDF_STATUS_E_FAILURE; 12715 } 12716 } 12717 12718 if (total_reg_rules != param_buf->num_reg_rule_array) { 12719 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 12720 total_reg_rules, param_buf->num_reg_rule_array); 12721 return QDF_STATUS_E_FAILURE; 12722 } 12723 12724 if ((num_2g_reg_rules > MAX_REG_RULES) || 12725 (num_5g_reg_rules > MAX_REG_RULES)) { 12726 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 12727 num_2g_reg_rules, num_5g_reg_rules); 12728 return QDF_STATUS_E_FAILURE; 12729 } 12730 12731 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 12732 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 12733 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 12734 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", 12735 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 12736 num_6g_reg_rules_ap[REG_INDOOR_AP], 12737 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 12738 return QDF_STATUS_E_FAILURE; 12739 } 12740 12741 if (param_buf->num_reg_rule_array > 12742 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 12743 sizeof(*ext_wmi_reg_rule)) { 12744 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 12745 param_buf->num_reg_rule_array); 12746 return QDF_STATUS_E_FAILURE; 12747 } 12748 12749 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 12750 REG_ALPHA2_LEN); 12751 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 12752 reg_info->phybitmap = convert_phybitmap_tlv( 12753 ext_chan_list_event_hdr->phybitmap); 12754 reg_info->offload_enabled = true; 12755 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 12756 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 12757 wmi_handle, ext_chan_list_event_hdr->phy_id); 12758 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 12759 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 12760 12761 reg_info->status_code = 12762 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 12763 status_code); 12764 12765 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 12766 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 12767 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 12768 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 12769 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 12770 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 12771 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 12772 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 12773 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 12774 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 12775 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 12776 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 12777 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 12778 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 12779 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 12780 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 12781 12782 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 12783 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 12784 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 12785 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 12786 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 12787 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 12788 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 12789 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 12790 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 12791 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 12792 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 12793 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 12794 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 12795 } 12796 12797 wmi_debug("num_phys = %u and phy_id = %u", 12798 reg_info->num_phy, reg_info->phy_id); 12799 12800 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 12801 reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, 12802 reg_info->max_bw_2g, reg_info->min_bw_5g, 12803 reg_info->max_bw_5g); 12804 12805 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", 12806 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 12807 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 12808 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 12809 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 12810 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 12811 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 12812 12813 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", 12814 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 12815 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 12816 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 12817 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 12818 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 12819 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 12820 12821 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", 12822 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 12823 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 12824 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 12825 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 12826 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 12827 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 12828 12829 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 12830 num_2g_reg_rules, num_5g_reg_rules); 12831 12832 wmi_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 12833 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 12834 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 12835 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 12836 12837 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", 12838 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 12839 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 12840 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 12841 12842 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", 12843 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 12844 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 12845 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 12846 12847 ext_wmi_reg_rule = 12848 (wmi_regulatory_rule_ext_struct *) 12849 ((uint8_t *)ext_chan_list_event_hdr + 12850 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 12851 WMI_TLV_HDR_SIZE); 12852 reg_info->reg_rules_2g_ptr = 12853 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 12854 ext_wmi_reg_rule); 12855 ext_wmi_reg_rule += num_2g_reg_rules; 12856 for (i = 0; i < num_2g_reg_rules; i++) { 12857 if (!reg_info->reg_rules_2g_ptr) 12858 break; 12859 wmi_debug("2g rule %d start freq %d end freq %d flags %d", 12860 i, reg_info->reg_rules_2g_ptr[i].start_freq, 12861 reg_info->reg_rules_2g_ptr[i].end_freq, 12862 reg_info->reg_rules_2g_ptr[i].flags); 12863 } 12864 reg_info->reg_rules_5g_ptr = 12865 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 12866 ext_wmi_reg_rule); 12867 ext_wmi_reg_rule += num_5g_reg_rules; 12868 for (i = 0; i < num_5g_reg_rules; i++) { 12869 if (!reg_info->reg_rules_5g_ptr) 12870 break; 12871 wmi_debug("5g rule %d start freq %d end freq %d flags %d", 12872 i, reg_info->reg_rules_5g_ptr[i].start_freq, 12873 reg_info->reg_rules_5g_ptr[i].end_freq, 12874 reg_info->reg_rules_5g_ptr[i].flags); 12875 } 12876 12877 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 12878 reg_info->reg_rules_6g_ap_ptr[i] = 12879 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 12880 ext_wmi_reg_rule); 12881 12882 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 12883 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 12884 if (!reg_info->reg_rules_6g_ap_ptr[i]) 12885 break; 12886 wmi_debug("6g pwr type %d AP rule %d start freq %d end freq %d flags %d", 12887 i, j, 12888 reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 12889 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 12890 reg_info->reg_rules_6g_ap_ptr[i][j].flags); 12891 } 12892 } 12893 12894 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 12895 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 12896 reg_info->reg_rules_6g_client_ptr[j][i] = 12897 create_ext_reg_rules_from_wmi( 12898 num_6g_reg_rules_client[j][i], 12899 ext_wmi_reg_rule); 12900 12901 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 12902 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 12903 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 12904 break; 12905 wmi_debug("6g pwr type %d cli type %d CLI rule %d start freq %d end freq %d flags %d", 12906 j, i, k, 12907 reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 12908 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 12909 reg_info->reg_rules_6g_client_ptr[j][i][k].flags); 12910 } 12911 } 12912 } 12913 12914 reg_info->client_type = ext_chan_list_event_hdr->client_type; 12915 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 12916 reg_info->unspecified_ap_usable = 12917 ext_chan_list_event_hdr->unspecified_ap_usable; 12918 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 12919 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 12920 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 12921 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 12922 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 12923 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 12924 12925 wmi_debug("client type %d", reg_info->client_type); 12926 wmi_debug("RNR TPE usable %d", reg_info->rnr_tpe_usable); 12927 wmi_debug("unspecified AP usable %d", reg_info->unspecified_ap_usable); 12928 wmi_debug("domain code AP SP %d, LPI %d, VLP %d", 12929 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 12930 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 12931 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 12932 12933 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 12934 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 12935 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 12936 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 12937 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 12938 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 12939 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 12940 wmi_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 12941 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 12942 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 12943 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 12944 } 12945 12946 reg_info->domain_code_6g_super_id = 12947 ext_chan_list_event_hdr->domain_code_6g_super_id; 12948 12949 wmi_debug("processed regulatory extended channel list"); 12950 12951 return QDF_STATUS_SUCCESS; 12952 } 12953 12954 #ifdef CONFIG_AFC_SUPPORT 12955 /** 12956 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 12957 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 12958 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 12959 * an index pointer required to store the current index of 12960 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 12961 * @chan_eirp_info: pointer to chan_eirp_info 12962 * @num_chans: Number of channels 12963 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 12964 * @index: Pointer to index 12965 * 12966 * Return: void 12967 */ 12968 static void 12969 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 12970 uint8_t num_chans, 12971 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 12972 uint8_t *index) 12973 { 12974 uint8_t chan_idx; 12975 12976 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 12977 chan_eirp_info[chan_idx].cfi = 12978 chan_eirp_power_info_hdr[*index].channel_cfi; 12979 chan_eirp_info[chan_idx].eirp_power = 12980 chan_eirp_power_info_hdr[*index].eirp_pwr; 12981 } 12982 } 12983 12984 /** 12985 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 12986 * to the internal buffer afc_chan_info. 12987 * @afc_chan_info: pointer to afc_chan_info 12988 * @num_chan_objs: Number of channel objects 12989 * @channel_info_hdr: Pointer to channel_info_hdr 12990 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 12991 * 12992 * Return: void 12993 */ 12994 static void 12995 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 12996 uint8_t num_chan_objs, 12997 wmi_6g_afc_channel_info *channel_info_hdr, 12998 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 12999 { 13000 uint8_t count; 13001 uint8_t src_pwr_index = 0; 13002 13003 for (count = 0; count < num_chan_objs; count++) { 13004 afc_chan_info[count].global_opclass = 13005 channel_info_hdr[count].global_operating_class; 13006 afc_chan_info[count].num_chans = 13007 channel_info_hdr[count].num_channels; 13008 13009 if (afc_chan_info[count].num_chans > 0) { 13010 struct chan_eirp_obj *chan_eirp_info; 13011 13012 chan_eirp_info = 13013 qdf_mem_malloc(afc_chan_info[count].num_chans * 13014 sizeof(*chan_eirp_info)); 13015 13016 if (!chan_eirp_info) 13017 return; 13018 13019 copy_afc_chan_eirp_info(chan_eirp_info, 13020 afc_chan_info[count].num_chans, 13021 chan_eirp_power_info_hdr, 13022 &src_pwr_index); 13023 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 13024 } else { 13025 wmi_err("Number of channels is zero in object idx %d", 13026 count); 13027 } 13028 } 13029 } 13030 13031 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 13032 uint8_t num_freq_objs, 13033 wmi_6g_afc_frequency_info *freq_info_hdr) 13034 { 13035 uint8_t count; 13036 13037 for (count = 0; count < num_freq_objs; count++) { 13038 afc_freq_info[count].low_freq = 13039 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 13040 afc_freq_info[count].high_freq = 13041 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 13042 afc_freq_info[count].max_psd = 13043 freq_info_hdr[count].psd_power_info; 13044 } 13045 } 13046 13047 /** 13048 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 13049 * the power event info from the WMI AFC event buffer to the internal buffer 13050 * power_info. 13051 * @power_info: pointer to power_info 13052 * @afc_power_event_hdr: pointer to afc_power_event_hdr 13053 * 13054 * Return: void 13055 */ 13056 static void 13057 copy_afc_event_fixed_hdr_power_info( 13058 struct reg_fw_afc_power_event *power_info, 13059 wmi_afc_power_event_param *afc_power_event_hdr) 13060 { 13061 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 13062 power_info->resp_id = afc_power_event_hdr->resp_id; 13063 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 13064 power_info->afc_wfa_version = 13065 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 13066 power_info->afc_wfa_version |= 13067 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 13068 13069 power_info->avail_exp_time_d = 13070 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 13071 power_info->avail_exp_time_d |= 13072 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 13073 power_info->avail_exp_time_d |= 13074 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 13075 13076 power_info->avail_exp_time_t = 13077 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 13078 power_info->avail_exp_time_t |= 13079 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 13080 power_info->avail_exp_time_t |= 13081 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 13082 } 13083 13084 /** 13085 * copy_power_event() - Copy the power event parameters from the AFC event 13086 * buffer to the power_info within the afc_info. 13087 * @afc_info: pointer to afc_info 13088 * @param_buf: pointer to param_buf 13089 * 13090 * Return: void 13091 */ 13092 static void copy_power_event(struct afc_regulatory_info *afc_info, 13093 WMI_AFC_EVENTID_param_tlvs *param_buf) 13094 { 13095 struct reg_fw_afc_power_event *power_info; 13096 wmi_afc_power_event_param *afc_power_event_hdr; 13097 struct afc_freq_obj *afc_freq_info; 13098 13099 power_info = qdf_mem_malloc(sizeof(*power_info)); 13100 13101 if (!power_info) 13102 return; 13103 13104 afc_power_event_hdr = param_buf->afc_power_event_param; 13105 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 13106 afc_info->power_info = power_info; 13107 13108 power_info->num_freq_objs = param_buf->num_freq_info_array; 13109 if (power_info->num_freq_objs > 0) { 13110 wmi_6g_afc_frequency_info *freq_info_hdr; 13111 13112 freq_info_hdr = param_buf->freq_info_array; 13113 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 13114 sizeof(*afc_freq_info)); 13115 13116 if (!afc_freq_info) 13117 return; 13118 13119 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 13120 freq_info_hdr); 13121 power_info->afc_freq_info = afc_freq_info; 13122 } else { 13123 wmi_err("Number of frequency objects is zero"); 13124 } 13125 13126 power_info->num_chan_objs = param_buf->num_channel_info_array; 13127 if (power_info->num_chan_objs > 0) { 13128 struct afc_chan_obj *afc_chan_info; 13129 wmi_6g_afc_channel_info *channel_info_hdr; 13130 13131 channel_info_hdr = param_buf->channel_info_array; 13132 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 13133 sizeof(*afc_chan_info)); 13134 13135 if (!afc_chan_info) 13136 return; 13137 13138 copy_afc_chan_obj_info(afc_chan_info, 13139 power_info->num_chan_objs, 13140 channel_info_hdr, 13141 param_buf->chan_eirp_power_info_array); 13142 power_info->afc_chan_info = afc_chan_info; 13143 } else { 13144 wmi_err("Number of channel objects is zero"); 13145 } 13146 } 13147 13148 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 13149 WMI_AFC_EVENTID_param_tlvs *param_buf) 13150 { 13151 struct reg_afc_expiry_event *expiry_info; 13152 13153 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 13154 13155 if (!expiry_info) 13156 return; 13157 13158 expiry_info->request_id = 13159 param_buf->expiry_event_param->request_id; 13160 expiry_info->event_subtype = 13161 param_buf->expiry_event_param->event_subtype; 13162 afc_info->expiry_info = expiry_info; 13163 } 13164 13165 /** 13166 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 13167 * in the AFC event. 'Common' indicates that these parameters are common for 13168 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 13169 * @wmi_handle: wmi handle 13170 * @afc_info: pointer to afc_info 13171 * @event_fixed_hdr: pointer to event_fixed_hdr 13172 * 13173 * Return: void 13174 */ 13175 static void 13176 copy_afc_event_common_info(wmi_unified_t wmi_handle, 13177 struct afc_regulatory_info *afc_info, 13178 wmi_afc_event_fixed_param *event_fixed_hdr) 13179 { 13180 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 13181 wmi_handle, event_fixed_hdr->phy_id); 13182 afc_info->event_type = event_fixed_hdr->event_type; 13183 } 13184 13185 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 13186 uint8_t *evt_buf, 13187 struct afc_regulatory_info *afc_info, 13188 uint32_t len) 13189 { 13190 WMI_AFC_EVENTID_param_tlvs *param_buf; 13191 wmi_afc_event_fixed_param *event_fixed_hdr; 13192 13193 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 13194 if (!param_buf) { 13195 wmi_err("Invalid AFC event buf"); 13196 return QDF_STATUS_E_FAILURE; 13197 } 13198 13199 event_fixed_hdr = param_buf->fixed_param; 13200 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 13201 13202 switch (afc_info->event_type) { 13203 case WMI_AFC_EVENT_POWER_INFO: 13204 copy_power_event(afc_info, param_buf); 13205 break; 13206 case WMI_AFC_EVENT_TIMER_EXPIRY: 13207 copy_expiry_event(afc_info, param_buf); 13208 return QDF_STATUS_SUCCESS; 13209 default: 13210 wmi_err("Invalid event type"); 13211 return QDF_STATUS_E_FAILURE; 13212 } 13213 13214 return QDF_STATUS_SUCCESS; 13215 } 13216 #endif 13217 #endif 13218 13219 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 13220 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13221 struct cur_regulatory_info *reg_info, uint32_t len) 13222 { 13223 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 13224 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 13225 wmi_regulatory_rule_struct *wmi_reg_rule; 13226 uint32_t num_2g_reg_rules, num_5g_reg_rules; 13227 13228 wmi_debug("processing regulatory channel list"); 13229 13230 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 13231 if (!param_buf) { 13232 wmi_err("invalid channel list event buf"); 13233 return QDF_STATUS_E_FAILURE; 13234 } 13235 13236 chan_list_event_hdr = param_buf->fixed_param; 13237 13238 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 13239 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 13240 num_2g_reg_rules = reg_info->num_2g_reg_rules; 13241 num_5g_reg_rules = reg_info->num_5g_reg_rules; 13242 if ((num_2g_reg_rules > MAX_REG_RULES) || 13243 (num_5g_reg_rules > MAX_REG_RULES) || 13244 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 13245 (num_2g_reg_rules + num_5g_reg_rules != 13246 param_buf->num_reg_rule_array)) { 13247 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 13248 num_2g_reg_rules, num_5g_reg_rules); 13249 return QDF_STATUS_E_FAILURE; 13250 } 13251 if (param_buf->num_reg_rule_array > 13252 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 13253 sizeof(*wmi_reg_rule)) { 13254 wmi_err_rl("Invalid num_reg_rule_array: %u", 13255 param_buf->num_reg_rule_array); 13256 return QDF_STATUS_E_FAILURE; 13257 } 13258 13259 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 13260 REG_ALPHA2_LEN); 13261 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 13262 reg_info->phybitmap = convert_phybitmap_tlv( 13263 chan_list_event_hdr->phybitmap); 13264 reg_info->offload_enabled = true; 13265 reg_info->num_phy = chan_list_event_hdr->num_phy; 13266 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 13267 wmi_handle, chan_list_event_hdr->phy_id); 13268 reg_info->ctry_code = chan_list_event_hdr->country_id; 13269 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 13270 13271 reg_info->status_code = 13272 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 13273 13274 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 13275 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 13276 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 13277 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 13278 13279 wmi_debug("num_phys = %u and phy_id = %u", 13280 reg_info->num_phy, reg_info->phy_id); 13281 13282 wmi_debug("cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 13283 reg_info->alpha2, reg_info->dfs_region, 13284 reg_info->min_bw_2g, reg_info->max_bw_2g, 13285 reg_info->min_bw_5g, reg_info->max_bw_5g); 13286 13287 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 13288 num_2g_reg_rules, num_5g_reg_rules); 13289 wmi_reg_rule = 13290 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 13291 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 13292 + WMI_TLV_HDR_SIZE); 13293 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 13294 wmi_reg_rule); 13295 wmi_reg_rule += num_2g_reg_rules; 13296 13297 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 13298 wmi_reg_rule); 13299 13300 wmi_debug("processed regulatory channel list"); 13301 13302 return QDF_STATUS_SUCCESS; 13303 } 13304 13305 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 13306 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13307 struct reg_11d_new_country *reg_11d_country, uint32_t len) 13308 { 13309 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 13310 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 13311 13312 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 13313 if (!param_buf) { 13314 wmi_err("invalid 11d country event buf"); 13315 return QDF_STATUS_E_FAILURE; 13316 } 13317 13318 reg_11d_country_event = param_buf->fixed_param; 13319 13320 qdf_mem_copy(reg_11d_country->alpha2, 13321 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 13322 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 13323 13324 wmi_debug("processed 11d country event, new cc %s", 13325 reg_11d_country->alpha2); 13326 13327 return QDF_STATUS_SUCCESS; 13328 } 13329 13330 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 13331 wmi_unified_t wmi_handle, uint8_t *evt_buf, 13332 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 13333 { 13334 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 13335 wmi_avoid_freq_range_desc *afr_desc; 13336 uint32_t num_freq_ranges, freq_range_idx; 13337 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 13338 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 13339 13340 if (!param_buf) { 13341 wmi_err("Invalid channel avoid event buffer"); 13342 return QDF_STATUS_E_INVAL; 13343 } 13344 13345 afr_fixed_param = param_buf->fixed_param; 13346 if (!afr_fixed_param) { 13347 wmi_err("Invalid channel avoid event fixed param buffer"); 13348 return QDF_STATUS_E_INVAL; 13349 } 13350 13351 if (!ch_avoid_ind) { 13352 wmi_err("Invalid channel avoid indication buffer"); 13353 return QDF_STATUS_E_INVAL; 13354 } 13355 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 13356 wmi_err("no.of freq ranges exceeded the limit"); 13357 return QDF_STATUS_E_INVAL; 13358 } 13359 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 13360 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 13361 afr_fixed_param->num_freq_ranges; 13362 13363 wmi_debug("Channel avoid event received with %d ranges", 13364 num_freq_ranges); 13365 13366 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 13367 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 13368 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 13369 freq_range_idx++) { 13370 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 13371 afr_desc->start_freq; 13372 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 13373 afr_desc->end_freq; 13374 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 13375 freq_range_idx, afr_desc->tlv_header, 13376 afr_desc->start_freq, afr_desc->end_freq); 13377 afr_desc++; 13378 } 13379 13380 return QDF_STATUS_SUCCESS; 13381 } 13382 13383 #ifdef DFS_COMPONENT_ENABLE 13384 /** 13385 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 13386 * @wmi_handle: wma handle 13387 * @evt_buf: event buffer 13388 * @vdev_id: vdev id 13389 * @len: length of buffer 13390 * 13391 * Return: 0 for success or error code 13392 */ 13393 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 13394 uint8_t *evt_buf, 13395 uint32_t *vdev_id, 13396 uint32_t len) 13397 { 13398 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 13399 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 13400 13401 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 13402 if (!param_tlvs) { 13403 wmi_err("invalid cac complete event buf"); 13404 return QDF_STATUS_E_FAILURE; 13405 } 13406 13407 cac_event = param_tlvs->fixed_param; 13408 *vdev_id = cac_event->vdev_id; 13409 wmi_debug("processed cac complete event vdev %d", *vdev_id); 13410 13411 return QDF_STATUS_SUCCESS; 13412 } 13413 13414 /** 13415 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 13416 * @wmi_handle: wma handle 13417 * @evt_buf: event buffer 13418 * @vdev_id: vdev id 13419 * @len: length of buffer 13420 * 13421 * Return: 0 for success or error code 13422 */ 13423 static QDF_STATUS 13424 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 13425 uint8_t *evt_buf, 13426 struct vdev_adfs_complete_status *param) 13427 { 13428 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 13429 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 13430 13431 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 13432 if (!param_tlvs) { 13433 wmi_err("invalid ocac complete event buf"); 13434 return QDF_STATUS_E_FAILURE; 13435 } 13436 13437 if (!param_tlvs->fixed_param) { 13438 wmi_err("invalid param_tlvs->fixed_param"); 13439 return QDF_STATUS_E_FAILURE; 13440 } 13441 13442 ocac_complete_status = param_tlvs->fixed_param; 13443 param->vdev_id = ocac_complete_status->vdev_id; 13444 param->chan_freq = ocac_complete_status->chan_freq; 13445 param->center_freq1 = ocac_complete_status->center_freq1; 13446 param->center_freq2 = ocac_complete_status->center_freq2; 13447 param->ocac_status = ocac_complete_status->status; 13448 param->chan_width = ocac_complete_status->chan_width; 13449 wmi_debug("processed ocac complete event vdev %d" 13450 " agile chan %d %d width %d status %d", 13451 param->vdev_id, 13452 param->center_freq1, 13453 param->center_freq2, 13454 param->chan_width, 13455 param->ocac_status); 13456 13457 return QDF_STATUS_SUCCESS; 13458 } 13459 13460 /** 13461 * extract_dfs_radar_detection_event_tlv() - extract radar found event 13462 * @wmi_handle: wma handle 13463 * @evt_buf: event buffer 13464 * @radar_found: radar found event info 13465 * @len: length of buffer 13466 * 13467 * Return: 0 for success or error code 13468 */ 13469 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 13470 wmi_unified_t wmi_handle, 13471 uint8_t *evt_buf, 13472 struct radar_found_info *radar_found, 13473 uint32_t len) 13474 { 13475 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 13476 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 13477 13478 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 13479 if (!param_tlv) { 13480 wmi_err("invalid radar detection event buf"); 13481 return QDF_STATUS_E_FAILURE; 13482 } 13483 13484 radar_event = param_tlv->fixed_param; 13485 13486 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 13487 wmi_handle, 13488 radar_event->pdev_id); 13489 13490 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 13491 return QDF_STATUS_E_FAILURE; 13492 13493 radar_found->detection_mode = radar_event->detection_mode; 13494 radar_found->chan_freq = radar_event->chan_freq; 13495 radar_found->chan_width = radar_event->chan_width; 13496 radar_found->detector_id = radar_event->detector_id; 13497 radar_found->segment_id = radar_event->segment_id; 13498 radar_found->timestamp = radar_event->timestamp; 13499 radar_found->is_chirp = radar_event->is_chirp; 13500 radar_found->freq_offset = radar_event->freq_offset; 13501 radar_found->sidx = radar_event->sidx; 13502 13503 wmi_debug("processed radar found event pdev %d," 13504 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 13505 "chan_width (RSSI) %d,detector_id (false_radar) %d," 13506 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 13507 "is_chirp %d,detection mode %d", 13508 radar_event->pdev_id, radar_found->pdev_id, 13509 radar_event->timestamp, radar_event->chan_freq, 13510 radar_event->chan_width, radar_event->detector_id, 13511 radar_event->freq_offset, radar_event->segment_id, 13512 radar_event->sidx, radar_event->is_chirp, 13513 radar_event->detection_mode); 13514 13515 return QDF_STATUS_SUCCESS; 13516 } 13517 13518 #ifdef MOBILE_DFS_SUPPORT 13519 /** 13520 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 13521 * @wmi_handle: wma handle 13522 * @evt_buf: event buffer 13523 * @wlan_radar_event: Pointer to struct radar_event_info 13524 * @len: length of buffer 13525 * 13526 * Return: QDF_STATUS 13527 */ 13528 static QDF_STATUS extract_wlan_radar_event_info_tlv( 13529 wmi_unified_t wmi_handle, 13530 uint8_t *evt_buf, 13531 struct radar_event_info *wlan_radar_event, 13532 uint32_t len) 13533 { 13534 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 13535 wmi_dfs_radar_event_fixed_param *radar_event; 13536 13537 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 13538 if (!param_tlv) { 13539 wmi_err("invalid wlan radar event buf"); 13540 return QDF_STATUS_E_FAILURE; 13541 } 13542 13543 radar_event = param_tlv->fixed_param; 13544 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 13545 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 13546 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 13547 wlan_radar_event->rssi = radar_event->rssi; 13548 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 13549 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 13550 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 13551 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 13552 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 13553 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 13554 if (radar_event->pulse_flags & 13555 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 13556 wlan_radar_event->is_psidx_diff_valid = true; 13557 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 13558 } else { 13559 wlan_radar_event->is_psidx_diff_valid = false; 13560 } 13561 13562 wlan_radar_event->pdev_id = radar_event->pdev_id; 13563 13564 return QDF_STATUS_SUCCESS; 13565 } 13566 #else 13567 static QDF_STATUS extract_wlan_radar_event_info_tlv( 13568 wmi_unified_t wmi_handle, 13569 uint8_t *evt_buf, 13570 struct radar_event_info *wlan_radar_event, 13571 uint32_t len) 13572 { 13573 return QDF_STATUS_SUCCESS; 13574 } 13575 #endif 13576 #endif 13577 13578 /** 13579 * send_get_rcpi_cmd_tlv() - send request for rcpi value 13580 * @wmi_handle: wmi handle 13581 * @get_rcpi_param: rcpi params 13582 * 13583 * Return: QDF status 13584 */ 13585 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 13586 struct rcpi_req *get_rcpi_param) 13587 { 13588 wmi_buf_t buf; 13589 wmi_request_rcpi_cmd_fixed_param *cmd; 13590 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 13591 13592 buf = wmi_buf_alloc(wmi_handle, len); 13593 if (!buf) 13594 return QDF_STATUS_E_NOMEM; 13595 13596 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 13597 WMITLV_SET_HDR(&cmd->tlv_header, 13598 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 13599 WMITLV_GET_STRUCT_TLVLEN 13600 (wmi_request_rcpi_cmd_fixed_param)); 13601 13602 cmd->vdev_id = get_rcpi_param->vdev_id; 13603 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 13604 &cmd->peer_macaddr); 13605 13606 switch (get_rcpi_param->measurement_type) { 13607 13608 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 13609 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 13610 break; 13611 13612 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 13613 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 13614 break; 13615 13616 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 13617 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 13618 break; 13619 13620 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 13621 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 13622 break; 13623 13624 default: 13625 /* 13626 * invalid rcpi measurement type, fall back to 13627 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 13628 */ 13629 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 13630 break; 13631 } 13632 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 13633 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 13634 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13635 WMI_REQUEST_RCPI_CMDID)) { 13636 13637 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 13638 wmi_buf_free(buf); 13639 return QDF_STATUS_E_FAILURE; 13640 } 13641 13642 return QDF_STATUS_SUCCESS; 13643 } 13644 13645 /** 13646 * extract_rcpi_response_event_tlv() - Extract RCPI event params 13647 * @wmi_handle: wmi handle 13648 * @evt_buf: pointer to event buffer 13649 * @res: pointer to hold rcpi response from firmware 13650 * 13651 * Return: QDF_STATUS_SUCCESS for successful event parse 13652 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 13653 */ 13654 static QDF_STATUS 13655 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 13656 void *evt_buf, struct rcpi_res *res) 13657 { 13658 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 13659 wmi_update_rcpi_event_fixed_param *event; 13660 13661 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 13662 if (!param_buf) { 13663 wmi_err("Invalid rcpi event"); 13664 return QDF_STATUS_E_INVAL; 13665 } 13666 13667 event = param_buf->fixed_param; 13668 res->vdev_id = event->vdev_id; 13669 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 13670 13671 switch (event->measurement_type) { 13672 13673 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 13674 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 13675 break; 13676 13677 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 13678 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 13679 break; 13680 13681 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 13682 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 13683 break; 13684 13685 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 13686 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 13687 break; 13688 13689 default: 13690 wmi_err("Invalid rcpi measurement type from firmware"); 13691 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 13692 return QDF_STATUS_E_FAILURE; 13693 } 13694 13695 if (event->status) 13696 return QDF_STATUS_E_FAILURE; 13697 else 13698 return QDF_STATUS_SUCCESS; 13699 } 13700 13701 /** 13702 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 13703 * host to target defines. For legacy there is not conversion 13704 * required. Just return pdev_id as it is. 13705 * @param pdev_id: host pdev_id to be converted. 13706 * Return: target pdev_id after conversion. 13707 */ 13708 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 13709 wmi_unified_t wmi_handle, 13710 uint32_t pdev_id) 13711 { 13712 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 13713 return WMI_PDEV_ID_SOC; 13714 13715 /*No conversion required*/ 13716 return pdev_id; 13717 } 13718 13719 /** 13720 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 13721 * target to host defines. For legacy there is not conversion 13722 * required. Just return pdev_id as it is. 13723 * @param pdev_id: target pdev_id to be converted. 13724 * Return: host pdev_id after conversion. 13725 */ 13726 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 13727 wmi_unified_t wmi_handle, 13728 uint32_t pdev_id) 13729 { 13730 /*No conversion required*/ 13731 return pdev_id; 13732 } 13733 13734 /** 13735 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 13736 * host to target defines. For legacy there is not conversion 13737 * required. Just return phy_id as it is. 13738 * @param pdev_id: host phy_id to be converted. 13739 * Return: target phy_id after conversion. 13740 */ 13741 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 13742 wmi_unified_t wmi_handle, 13743 uint32_t phy_id) 13744 { 13745 /*No conversion required*/ 13746 return phy_id; 13747 } 13748 13749 /** 13750 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 13751 * target to host defines. For legacy there is not conversion 13752 * required. Just return phy_id as it is. 13753 * @param pdev_id: target phy_id to be converted. 13754 * Return: host phy_id after conversion. 13755 */ 13756 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 13757 wmi_unified_t wmi_handle, 13758 uint32_t phy_id) 13759 { 13760 /*No conversion required*/ 13761 return phy_id; 13762 } 13763 13764 /** 13765 * send_set_country_cmd_tlv() - WMI scan channel list function 13766 * @param wmi_handle : handle to WMI. 13767 * @param param : pointer to hold scan channel list parameter 13768 * 13769 * Return: 0 on success and -ve on failure. 13770 */ 13771 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 13772 struct set_country *params) 13773 { 13774 wmi_buf_t buf; 13775 QDF_STATUS qdf_status; 13776 wmi_set_current_country_cmd_fixed_param *cmd; 13777 uint16_t len = sizeof(*cmd); 13778 uint8_t pdev_id = params->pdev_id; 13779 13780 buf = wmi_buf_alloc(wmi_handle, len); 13781 if (!buf) { 13782 qdf_status = QDF_STATUS_E_NOMEM; 13783 goto end; 13784 } 13785 13786 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 13787 WMITLV_SET_HDR(&cmd->tlv_header, 13788 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 13789 WMITLV_GET_STRUCT_TLVLEN 13790 (wmi_set_current_country_cmd_fixed_param)); 13791 13792 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13793 wmi_handle, 13794 pdev_id); 13795 wmi_debug("setting current country to %s and target pdev_id = %u", 13796 params->country, cmd->pdev_id); 13797 13798 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 13799 13800 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 13801 qdf_status = wmi_unified_cmd_send(wmi_handle, 13802 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 13803 13804 if (QDF_IS_STATUS_ERROR(qdf_status)) { 13805 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 13806 wmi_buf_free(buf); 13807 } 13808 13809 end: 13810 return qdf_status; 13811 } 13812 13813 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 13814 WMI_SET_BITS(alpha, 0, 8, val0); \ 13815 WMI_SET_BITS(alpha, 8, 8, val1); \ 13816 WMI_SET_BITS(alpha, 16, 8, val2); \ 13817 } while (0) 13818 13819 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 13820 uint8_t pdev_id, struct cc_regdmn_s *rd) 13821 { 13822 wmi_set_init_country_cmd_fixed_param *cmd; 13823 uint16_t len; 13824 wmi_buf_t buf; 13825 int ret; 13826 13827 len = sizeof(wmi_set_init_country_cmd_fixed_param); 13828 buf = wmi_buf_alloc(wmi_handle, len); 13829 if (!buf) 13830 return QDF_STATUS_E_NOMEM; 13831 13832 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 13833 WMITLV_SET_HDR(&cmd->tlv_header, 13834 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 13835 WMITLV_GET_STRUCT_TLVLEN 13836 (wmi_set_init_country_cmd_fixed_param)); 13837 13838 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 13839 wmi_handle, 13840 pdev_id); 13841 13842 if (rd->flags == CC_IS_SET) { 13843 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 13844 cmd->country_code.country_id = rd->cc.country_code; 13845 } else if (rd->flags == ALPHA_IS_SET) { 13846 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 13847 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 13848 rd->cc.alpha[0], 13849 rd->cc.alpha[1], 13850 rd->cc.alpha[2]); 13851 } else if (rd->flags == REGDMN_IS_SET) { 13852 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 13853 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 13854 rd->cc.regdmn.reg_2g_5g_pair_id); 13855 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 13856 rd->cc.regdmn.sixg_superdmn_id); 13857 } 13858 13859 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 13860 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13861 WMI_SET_INIT_COUNTRY_CMDID); 13862 if (ret) { 13863 wmi_err("Failed to config wow wakeup event"); 13864 wmi_buf_free(buf); 13865 return QDF_STATUS_E_FAILURE; 13866 } 13867 13868 return QDF_STATUS_SUCCESS; 13869 } 13870 13871 /** 13872 * send_obss_detection_cfg_cmd_tlv() - send obss detection 13873 * configurations to firmware. 13874 * @wmi_handle: wmi handle 13875 * @obss_cfg_param: obss detection configurations 13876 * 13877 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 13878 * 13879 * Return: QDF_STATUS 13880 */ 13881 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 13882 struct wmi_obss_detection_cfg_param *obss_cfg_param) 13883 { 13884 wmi_buf_t buf; 13885 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 13886 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 13887 13888 buf = wmi_buf_alloc(wmi_handle, len); 13889 if (!buf) 13890 return QDF_STATUS_E_NOMEM; 13891 13892 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 13893 WMITLV_SET_HDR(&cmd->tlv_header, 13894 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 13895 WMITLV_GET_STRUCT_TLVLEN 13896 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 13897 13898 cmd->vdev_id = obss_cfg_param->vdev_id; 13899 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 13900 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 13901 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 13902 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 13903 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 13904 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 13905 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 13906 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 13907 13908 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 13909 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13910 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 13911 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 13912 wmi_buf_free(buf); 13913 return QDF_STATUS_E_FAILURE; 13914 } 13915 13916 return QDF_STATUS_SUCCESS; 13917 } 13918 13919 /** 13920 * extract_obss_detection_info_tlv() - Extract obss detection info 13921 * received from firmware. 13922 * @evt_buf: pointer to event buffer 13923 * @obss_detection: Pointer to hold obss detection info 13924 * 13925 * Return: QDF_STATUS 13926 */ 13927 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 13928 struct wmi_obss_detect_info 13929 *obss_detection) 13930 { 13931 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 13932 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 13933 13934 if (!obss_detection) { 13935 wmi_err("Invalid obss_detection event buffer"); 13936 return QDF_STATUS_E_INVAL; 13937 } 13938 13939 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 13940 if (!param_buf) { 13941 wmi_err("Invalid evt_buf"); 13942 return QDF_STATUS_E_INVAL; 13943 } 13944 13945 fix_param = param_buf->fixed_param; 13946 obss_detection->vdev_id = fix_param->vdev_id; 13947 obss_detection->matched_detection_masks = 13948 fix_param->matched_detection_masks; 13949 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 13950 &obss_detection->matched_bssid_addr[0]); 13951 switch (fix_param->reason) { 13952 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 13953 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 13954 break; 13955 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 13956 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 13957 break; 13958 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 13959 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 13960 break; 13961 default: 13962 wmi_err("Invalid reason: %d", fix_param->reason); 13963 return QDF_STATUS_E_INVAL; 13964 } 13965 13966 return QDF_STATUS_SUCCESS; 13967 } 13968 13969 /** 13970 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 13971 * @wmi_handle: wmi handle 13972 * @params: pointer to request structure 13973 * 13974 * Return: QDF_STATUS 13975 */ 13976 static QDF_STATUS 13977 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 13978 struct wmi_roam_scan_stats_req *params) 13979 { 13980 wmi_buf_t buf; 13981 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 13982 WMITLV_TAG_ID tag; 13983 uint32_t size; 13984 uint32_t len = sizeof(*cmd); 13985 13986 buf = wmi_buf_alloc(wmi_handle, len); 13987 if (!buf) 13988 return QDF_STATUS_E_FAILURE; 13989 13990 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 13991 13992 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 13993 size = WMITLV_GET_STRUCT_TLVLEN( 13994 wmi_request_roam_scan_stats_cmd_fixed_param); 13995 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 13996 13997 cmd->vdev_id = params->vdev_id; 13998 13999 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 14000 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14001 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 14002 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 14003 wmi_buf_free(buf); 14004 return QDF_STATUS_E_FAILURE; 14005 } 14006 14007 return QDF_STATUS_SUCCESS; 14008 } 14009 14010 /** 14011 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 14012 * channel list from firmware 14013 * @wmi_handle: wmi handler 14014 * @vdev_id: vdev id 14015 * 14016 * Return: QDF_STATUS 14017 */ 14018 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 14019 uint32_t vdev_id) 14020 { 14021 wmi_buf_t buf; 14022 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 14023 uint16_t len = sizeof(*cmd); 14024 int ret; 14025 14026 buf = wmi_buf_alloc(wmi_handle, len); 14027 if (!buf) { 14028 wmi_err("Failed to allocate wmi buffer"); 14029 return QDF_STATUS_E_NOMEM; 14030 } 14031 14032 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 14033 wmi_buf_data(buf); 14034 WMITLV_SET_HDR(&cmd->tlv_header, 14035 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 14036 WMITLV_GET_STRUCT_TLVLEN( 14037 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 14038 cmd->vdev_id = vdev_id; 14039 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 14040 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14041 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 14042 if (QDF_IS_STATUS_ERROR(ret)) { 14043 wmi_err("Failed to send get roam scan channels request = %d", 14044 ret); 14045 wmi_buf_free(buf); 14046 } 14047 return ret; 14048 } 14049 14050 /** 14051 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 14052 * @wmi_handle: wmi handle 14053 * @evt_buf: pointer to event buffer 14054 * @vdev_id: output pointer to hold vdev id 14055 * @res_param: output pointer to hold the allocated response 14056 * 14057 * Return: QDF_STATUS 14058 */ 14059 static QDF_STATUS 14060 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14061 uint32_t *vdev_id, 14062 struct wmi_roam_scan_stats_res **res_param) 14063 { 14064 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 14065 wmi_roam_scan_stats_event_fixed_param *fixed_param; 14066 uint32_t *client_id = NULL; 14067 wmi_roaming_timestamp *timestamp = NULL; 14068 uint32_t *num_channels = NULL; 14069 uint32_t *chan_info = NULL; 14070 wmi_mac_addr *old_bssid = NULL; 14071 uint32_t *is_roaming_success = NULL; 14072 wmi_mac_addr *new_bssid = NULL; 14073 uint32_t *num_roam_candidates = NULL; 14074 wmi_roam_scan_trigger_reason *roam_reason = NULL; 14075 wmi_mac_addr *bssid = NULL; 14076 uint32_t *score = NULL; 14077 uint32_t *channel = NULL; 14078 uint32_t *rssi = NULL; 14079 int chan_idx = 0, cand_idx = 0; 14080 uint32_t total_len; 14081 struct wmi_roam_scan_stats_res *res; 14082 uint32_t i, j; 14083 uint32_t num_scans, scan_param_size; 14084 14085 *res_param = NULL; 14086 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 14087 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 14088 if (!param_buf) { 14089 wmi_err("Invalid roam scan stats event"); 14090 return QDF_STATUS_E_INVAL; 14091 } 14092 14093 fixed_param = param_buf->fixed_param; 14094 14095 num_scans = fixed_param->num_roam_scans; 14096 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 14097 *vdev_id = fixed_param->vdev_id; 14098 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 14099 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 14100 num_scans, WMI_ROAM_SCAN_STATS_MAX); 14101 return QDF_STATUS_E_INVAL; 14102 } 14103 14104 total_len = sizeof(*res) + num_scans * scan_param_size; 14105 14106 res = qdf_mem_malloc(total_len); 14107 if (!res) 14108 return QDF_STATUS_E_NOMEM; 14109 14110 if (!num_scans) { 14111 *res_param = res; 14112 return QDF_STATUS_SUCCESS; 14113 } 14114 14115 if (param_buf->client_id && 14116 param_buf->num_client_id == num_scans) 14117 client_id = param_buf->client_id; 14118 14119 if (param_buf->timestamp && 14120 param_buf->num_timestamp == num_scans) 14121 timestamp = param_buf->timestamp; 14122 14123 if (param_buf->old_bssid && 14124 param_buf->num_old_bssid == num_scans) 14125 old_bssid = param_buf->old_bssid; 14126 14127 if (param_buf->new_bssid && 14128 param_buf->num_new_bssid == num_scans) 14129 new_bssid = param_buf->new_bssid; 14130 14131 if (param_buf->is_roaming_success && 14132 param_buf->num_is_roaming_success == num_scans) 14133 is_roaming_success = param_buf->is_roaming_success; 14134 14135 if (param_buf->roam_reason && 14136 param_buf->num_roam_reason == num_scans) 14137 roam_reason = param_buf->roam_reason; 14138 14139 if (param_buf->num_channels && 14140 param_buf->num_num_channels == num_scans) { 14141 uint32_t count, chan_info_sum = 0; 14142 14143 num_channels = param_buf->num_channels; 14144 for (count = 0; count < param_buf->num_num_channels; count++) { 14145 if (param_buf->num_channels[count] > 14146 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 14147 wmi_err_rl("%u exceeded max scan channels %u", 14148 param_buf->num_channels[count], 14149 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 14150 goto error; 14151 } 14152 chan_info_sum += param_buf->num_channels[count]; 14153 } 14154 14155 if (param_buf->chan_info && 14156 param_buf->num_chan_info == chan_info_sum) 14157 chan_info = param_buf->chan_info; 14158 } 14159 14160 if (param_buf->num_roam_candidates && 14161 param_buf->num_num_roam_candidates == num_scans) { 14162 uint32_t cnt, roam_cand_sum = 0; 14163 14164 num_roam_candidates = param_buf->num_roam_candidates; 14165 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 14166 if (param_buf->num_roam_candidates[cnt] > 14167 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 14168 wmi_err_rl("%u exceeded max scan cand %u", 14169 param_buf->num_roam_candidates[cnt], 14170 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 14171 goto error; 14172 } 14173 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 14174 } 14175 14176 if (param_buf->bssid && 14177 param_buf->num_bssid == roam_cand_sum) 14178 bssid = param_buf->bssid; 14179 14180 if (param_buf->score && 14181 param_buf->num_score == roam_cand_sum) 14182 score = param_buf->score; 14183 14184 if (param_buf->channel && 14185 param_buf->num_channel == roam_cand_sum) 14186 channel = param_buf->channel; 14187 14188 if (param_buf->rssi && 14189 param_buf->num_rssi == roam_cand_sum) 14190 rssi = param_buf->rssi; 14191 } 14192 14193 res->num_roam_scans = num_scans; 14194 for (i = 0; i < num_scans; i++) { 14195 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 14196 14197 if (timestamp) 14198 roam->time_stamp = timestamp[i].lower32bit | 14199 (timestamp[i].upper32bit << 31); 14200 14201 if (client_id) 14202 roam->client_id = client_id[i]; 14203 14204 if (num_channels) { 14205 roam->num_scan_chans = num_channels[i]; 14206 if (chan_info) { 14207 for (j = 0; j < num_channels[i]; j++) 14208 roam->scan_freqs[j] = 14209 chan_info[chan_idx++]; 14210 } 14211 } 14212 14213 if (is_roaming_success) 14214 roam->is_roam_successful = is_roaming_success[i]; 14215 14216 if (roam_reason) { 14217 roam->trigger_id = roam_reason[i].trigger_id; 14218 roam->trigger_value = roam_reason[i].trigger_value; 14219 } 14220 14221 if (num_roam_candidates) { 14222 roam->num_roam_candidates = num_roam_candidates[i]; 14223 14224 for (j = 0; j < num_roam_candidates[i]; j++) { 14225 if (score) 14226 roam->cand[j].score = score[cand_idx]; 14227 if (rssi) 14228 roam->cand[j].rssi = rssi[cand_idx]; 14229 if (channel) 14230 roam->cand[j].freq = 14231 channel[cand_idx]; 14232 14233 if (bssid) 14234 WMI_MAC_ADDR_TO_CHAR_ARRAY( 14235 &bssid[cand_idx], 14236 roam->cand[j].bssid); 14237 14238 cand_idx++; 14239 } 14240 } 14241 14242 if (old_bssid) 14243 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 14244 roam->old_bssid); 14245 14246 if (new_bssid) 14247 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 14248 roam->new_bssid); 14249 } 14250 14251 *res_param = res; 14252 14253 return QDF_STATUS_SUCCESS; 14254 error: 14255 qdf_mem_free(res); 14256 return QDF_STATUS_E_FAILURE; 14257 } 14258 14259 /** 14260 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 14261 * @wmi_handle: wmi handle 14262 * @evt_buf: pointer to event buffer 14263 * @vdev_id: output pointer to hold vdev id 14264 * @tx_status: output pointer to hold the tx_status 14265 * 14266 * Return: QDF_STATUS 14267 */ 14268 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 14269 void *evt_buf, 14270 uint32_t *vdev_id, 14271 uint32_t *tx_status) { 14272 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 14273 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 14274 14275 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 14276 if (!param_buf) { 14277 wmi_err("Invalid offload bcn tx status event buffer"); 14278 return QDF_STATUS_E_INVAL; 14279 } 14280 14281 bcn_tx_status_event = param_buf->fixed_param; 14282 *vdev_id = bcn_tx_status_event->vdev_id; 14283 *tx_status = bcn_tx_status_event->tx_status; 14284 14285 return QDF_STATUS_SUCCESS; 14286 } 14287 14288 #ifdef WLAN_SUPPORT_GREEN_AP 14289 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 14290 uint8_t *evt_buf, 14291 struct wlan_green_ap_egap_status_info *egap_status_info_params) 14292 { 14293 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 14294 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 14295 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 14296 14297 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 14298 if (!param_buf) { 14299 wmi_err("Invalid EGAP Info status event buffer"); 14300 return QDF_STATUS_E_INVAL; 14301 } 14302 14303 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 14304 param_buf->fixed_param; 14305 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 14306 param_buf->chainmask_list; 14307 14308 if (!egap_info_event || !chainmask_event) { 14309 wmi_err("Invalid EGAP Info event or chainmask event"); 14310 return QDF_STATUS_E_INVAL; 14311 } 14312 14313 egap_status_info_params->status = egap_info_event->status; 14314 egap_status_info_params->mac_id = chainmask_event->mac_id; 14315 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 14316 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 14317 14318 return QDF_STATUS_SUCCESS; 14319 } 14320 #endif 14321 14322 /* 14323 * extract_comb_phyerr_tlv() - extract comb phy error from event 14324 * @wmi_handle: wmi handle 14325 * @evt_buf: pointer to event buffer 14326 * @datalen: data length of event buffer 14327 * @buf_offset: Pointer to hold value of current event buffer offset 14328 * post extraction 14329 * @phyerr: Pointer to hold phyerr 14330 * 14331 * Return: QDF_STATUS 14332 */ 14333 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 14334 void *evt_buf, 14335 uint16_t datalen, 14336 uint16_t *buf_offset, 14337 wmi_host_phyerr_t *phyerr) 14338 { 14339 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 14340 wmi_comb_phyerr_rx_hdr *pe_hdr; 14341 14342 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 14343 if (!param_tlvs) { 14344 wmi_debug("Received null data from FW"); 14345 return QDF_STATUS_E_FAILURE; 14346 } 14347 14348 pe_hdr = param_tlvs->hdr; 14349 if (!pe_hdr) { 14350 wmi_debug("Received Data PE Header is NULL"); 14351 return QDF_STATUS_E_FAILURE; 14352 } 14353 14354 /* Ensure it's at least the size of the header */ 14355 if (datalen < sizeof(*pe_hdr)) { 14356 wmi_debug("Expected minimum size %zu, received %d", 14357 sizeof(*pe_hdr), datalen); 14358 return QDF_STATUS_E_FAILURE; 14359 } 14360 14361 phyerr->pdev_id = wmi_handle->ops-> 14362 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 14363 phyerr->tsf64 = pe_hdr->tsf_l32; 14364 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 14365 phyerr->bufp = param_tlvs->bufp; 14366 14367 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 14368 wmi_debug("Invalid buf_len %d, num_bufp %d", 14369 pe_hdr->buf_len, param_tlvs->num_bufp); 14370 return QDF_STATUS_E_FAILURE; 14371 } 14372 14373 phyerr->buf_len = pe_hdr->buf_len; 14374 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 14375 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 14376 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 14377 14378 return QDF_STATUS_SUCCESS; 14379 } 14380 14381 /** 14382 * extract_single_phyerr_tlv() - extract single phy error from event 14383 * @wmi_handle: wmi handle 14384 * @evt_buf: pointer to event buffer 14385 * @datalen: data length of event buffer 14386 * @buf_offset: Pointer to hold value of current event buffer offset 14387 * post extraction 14388 * @phyerr: Pointer to hold phyerr 14389 * 14390 * Return: QDF_STATUS 14391 */ 14392 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 14393 void *evt_buf, 14394 uint16_t datalen, 14395 uint16_t *buf_offset, 14396 wmi_host_phyerr_t *phyerr) 14397 { 14398 wmi_single_phyerr_rx_event *ev; 14399 uint16_t n = *buf_offset; 14400 uint8_t *data = (uint8_t *)evt_buf; 14401 14402 if (n < datalen) { 14403 if ((datalen - n) < sizeof(ev->hdr)) { 14404 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 14405 datalen, n, sizeof(ev->hdr)); 14406 return QDF_STATUS_E_FAILURE; 14407 } 14408 14409 /* 14410 * Obtain a pointer to the beginning of the current event. 14411 * data[0] is the beginning of the WMI payload. 14412 */ 14413 ev = (wmi_single_phyerr_rx_event *)&data[n]; 14414 14415 /* 14416 * Sanity check the buffer length of the event against 14417 * what we currently have. 14418 * 14419 * Since buf_len is 32 bits, we check if it overflows 14420 * a large 32 bit value. It's not 0x7fffffff because 14421 * we increase n by (buf_len + sizeof(hdr)), which would 14422 * in itself cause n to overflow. 14423 * 14424 * If "int" is 64 bits then this becomes a moot point. 14425 */ 14426 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 14427 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 14428 return QDF_STATUS_E_FAILURE; 14429 } 14430 14431 if ((n + ev->hdr.buf_len) > datalen) { 14432 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 14433 n, ev->hdr.buf_len, datalen); 14434 return QDF_STATUS_E_FAILURE; 14435 } 14436 14437 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 14438 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 14439 phyerr->bufp = &ev->bufp[0]; 14440 phyerr->buf_len = ev->hdr.buf_len; 14441 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 14442 14443 /* 14444 * Advance the buffer pointer to the next PHY error. 14445 * buflen is the length of this payload, so we need to 14446 * advance past the current header _AND_ the payload. 14447 */ 14448 n += sizeof(*ev) + ev->hdr.buf_len; 14449 } 14450 *buf_offset = n; 14451 14452 return QDF_STATUS_SUCCESS; 14453 } 14454 14455 /** 14456 * extract_esp_estimation_ev_param_tlv() - extract air time from event 14457 * @wmi_handle: wmi handle 14458 * @evt_buf: pointer to event buffer 14459 * @param: Pointer to hold esp event 14460 * 14461 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 14462 */ 14463 static QDF_STATUS 14464 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 14465 void *evt_buf, 14466 struct esp_estimation_event *param) 14467 { 14468 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 14469 wmi_esp_estimate_event_fixed_param *esp_event; 14470 14471 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 14472 if (!param_buf) { 14473 wmi_err("Invalid ESP Estimate Event buffer"); 14474 return QDF_STATUS_E_INVAL; 14475 } 14476 esp_event = param_buf->fixed_param; 14477 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 14478 14479 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 14480 wmi_handle, 14481 esp_event->pdev_id); 14482 14483 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 14484 return QDF_STATUS_E_FAILURE; 14485 14486 return QDF_STATUS_SUCCESS; 14487 } 14488 14489 /* 14490 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 14491 * updating bss color change within firmware when AP announces bss color change. 14492 * @wmi_handle: wmi handle 14493 * @vdev_id: vdev ID 14494 * @enable: enable bss color change within firmware 14495 * 14496 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 14497 * 14498 * Return: QDF_STATUS 14499 */ 14500 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 14501 uint32_t vdev_id, 14502 bool enable) 14503 { 14504 wmi_buf_t buf; 14505 wmi_bss_color_change_enable_fixed_param *cmd; 14506 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 14507 14508 buf = wmi_buf_alloc(wmi_handle, len); 14509 if (!buf) 14510 return QDF_STATUS_E_NOMEM; 14511 14512 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 14513 WMITLV_SET_HDR(&cmd->tlv_header, 14514 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 14515 WMITLV_GET_STRUCT_TLVLEN 14516 (wmi_bss_color_change_enable_fixed_param)); 14517 cmd->vdev_id = vdev_id; 14518 cmd->enable = enable; 14519 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 14520 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14521 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 14522 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 14523 wmi_buf_free(buf); 14524 return QDF_STATUS_E_FAILURE; 14525 } 14526 14527 return QDF_STATUS_SUCCESS; 14528 } 14529 14530 /** 14531 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 14532 * configurations to firmware. 14533 * @wmi_handle: wmi handle 14534 * @cfg_param: obss detection configurations 14535 * 14536 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 14537 * 14538 * Return: QDF_STATUS 14539 */ 14540 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 14541 wmi_unified_t wmi_handle, 14542 struct wmi_obss_color_collision_cfg_param *cfg_param) 14543 { 14544 wmi_buf_t buf; 14545 wmi_obss_color_collision_det_config_fixed_param *cmd; 14546 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 14547 14548 buf = wmi_buf_alloc(wmi_handle, len); 14549 if (!buf) 14550 return QDF_STATUS_E_NOMEM; 14551 14552 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 14553 buf); 14554 WMITLV_SET_HDR(&cmd->tlv_header, 14555 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 14556 WMITLV_GET_STRUCT_TLVLEN 14557 (wmi_obss_color_collision_det_config_fixed_param)); 14558 cmd->vdev_id = cfg_param->vdev_id; 14559 cmd->flags = cfg_param->flags; 14560 cmd->current_bss_color = cfg_param->current_bss_color; 14561 cmd->detection_period_ms = cfg_param->detection_period_ms; 14562 cmd->scan_period_ms = cfg_param->scan_period_ms; 14563 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 14564 14565 switch (cfg_param->evt_type) { 14566 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 14567 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 14568 break; 14569 case OBSS_COLOR_COLLISION_DETECTION: 14570 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 14571 break; 14572 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 14573 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 14574 break; 14575 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 14576 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 14577 break; 14578 default: 14579 wmi_err("Invalid event type: %d", cfg_param->evt_type); 14580 wmi_buf_free(buf); 14581 return QDF_STATUS_E_FAILURE; 14582 } 14583 14584 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 14585 "detection_period_ms: %d scan_period_ms: %d " 14586 "free_slot_expiry_timer_ms: %d", 14587 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 14588 cmd->detection_period_ms, cmd->scan_period_ms, 14589 cmd->free_slot_expiry_time_ms); 14590 14591 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 14592 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14593 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 14594 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 14595 cfg_param->vdev_id); 14596 wmi_buf_free(buf); 14597 return QDF_STATUS_E_FAILURE; 14598 } 14599 14600 return QDF_STATUS_SUCCESS; 14601 } 14602 14603 /** 14604 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 14605 * received from firmware. 14606 * @evt_buf: pointer to event buffer 14607 * @info: Pointer to hold bss collision info 14608 * 14609 * Return: QDF_STATUS 14610 */ 14611 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 14612 struct wmi_obss_color_collision_info *info) 14613 { 14614 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 14615 wmi_obss_color_collision_evt_fixed_param *fix_param; 14616 14617 if (!info) { 14618 wmi_err("Invalid obss color buffer"); 14619 return QDF_STATUS_E_INVAL; 14620 } 14621 14622 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 14623 evt_buf; 14624 if (!param_buf) { 14625 wmi_err("Invalid evt_buf"); 14626 return QDF_STATUS_E_INVAL; 14627 } 14628 14629 fix_param = param_buf->fixed_param; 14630 info->vdev_id = fix_param->vdev_id; 14631 info->obss_color_bitmap_bit0to31 = 14632 fix_param->bss_color_bitmap_bit0to31; 14633 info->obss_color_bitmap_bit32to63 = 14634 fix_param->bss_color_bitmap_bit32to63; 14635 14636 switch (fix_param->evt_type) { 14637 case WMI_BSS_COLOR_COLLISION_DISABLE: 14638 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 14639 break; 14640 case WMI_BSS_COLOR_COLLISION_DETECTION: 14641 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 14642 break; 14643 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 14644 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 14645 break; 14646 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 14647 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 14648 break; 14649 default: 14650 wmi_err("Invalid event type: %d, vdev_id: %d", 14651 fix_param->evt_type, fix_param->vdev_id); 14652 return QDF_STATUS_E_FAILURE; 14653 } 14654 14655 return QDF_STATUS_SUCCESS; 14656 } 14657 14658 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 14659 { 14660 struct wmi_ops *ops = wmi_handle->ops; 14661 14662 ops->send_obss_color_collision_cfg_cmd = 14663 send_obss_color_collision_cfg_cmd_tlv; 14664 ops->extract_obss_color_collision_info = 14665 extract_obss_color_collision_info_tlv; 14666 } 14667 14668 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 14669 static QDF_STATUS 14670 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 14671 struct config_fils_params *param) 14672 { 14673 wmi_buf_t buf; 14674 wmi_enable_fils_cmd_fixed_param *cmd; 14675 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 14676 14677 buf = wmi_buf_alloc(wmi_handle, len); 14678 if (!buf) 14679 return QDF_STATUS_E_NOMEM; 14680 14681 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 14682 buf); 14683 WMITLV_SET_HDR(&cmd->tlv_header, 14684 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 14685 WMITLV_GET_STRUCT_TLVLEN 14686 (wmi_enable_fils_cmd_fixed_param)); 14687 cmd->vdev_id = param->vdev_id; 14688 cmd->fd_period = param->fd_period; 14689 if (param->send_prb_rsp_frame) 14690 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 14691 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 14692 cmd->vdev_id, cmd->fd_period, cmd->flags); 14693 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 14694 if (wmi_unified_cmd_send(wmi_handle, buf, len, 14695 WMI_ENABLE_FILS_CMDID)) { 14696 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 14697 wmi_buf_free(buf); 14698 return QDF_STATUS_E_FAILURE; 14699 } 14700 14701 return QDF_STATUS_SUCCESS; 14702 } 14703 #endif 14704 14705 #ifdef WLAN_MWS_INFO_DEBUGFS 14706 /** 14707 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 14708 * 14709 * @wmi_handle: wmi handle 14710 * @vdev_id: vdev id 14711 * @cmd_id: Coex command id 14712 * 14713 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 14714 * 14715 * Return: QDF_STATUS 14716 */ 14717 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 14718 uint32_t vdev_id, 14719 uint32_t cmd_id) 14720 { 14721 wmi_buf_t buf; 14722 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 14723 uint16_t len = sizeof(*cmd); 14724 int ret; 14725 14726 buf = wmi_buf_alloc(wmi_handle, len); 14727 if (!buf) { 14728 wmi_err("Failed to allocate wmi buffer"); 14729 return QDF_STATUS_E_NOMEM; 14730 } 14731 14732 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 14733 WMITLV_SET_HDR(&cmd->tlv_header, 14734 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 14735 WMITLV_GET_STRUCT_TLVLEN 14736 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 14737 cmd->vdev_id = vdev_id; 14738 cmd->cmd_id = cmd_id; 14739 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 14740 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14741 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 14742 if (QDF_IS_STATUS_ERROR(ret)) { 14743 wmi_err("Failed to send set param command ret = %d", ret); 14744 wmi_buf_free(buf); 14745 } 14746 return ret; 14747 } 14748 #endif 14749 14750 #ifdef WIFI_POS_CONVERGED 14751 /** 14752 * extract_oem_response_param_tlv() - Extract oem response params 14753 * @wmi_handle: wmi handle 14754 * @resp_buf: response buffer 14755 * @oem_resp_param: pointer to hold oem response params 14756 * 14757 * Return: QDF_STATUS_SUCCESS on success or proper error code. 14758 */ 14759 static QDF_STATUS 14760 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 14761 struct wmi_oem_response_param *oem_resp_param) 14762 { 14763 uint64_t temp_addr; 14764 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 14765 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 14766 14767 if (!param_buf) { 14768 wmi_err("Invalid OEM response"); 14769 return QDF_STATUS_E_INVAL; 14770 } 14771 14772 if (param_buf->num_data) { 14773 oem_resp_param->num_data1 = param_buf->num_data; 14774 oem_resp_param->data_1 = param_buf->data; 14775 } 14776 14777 if (param_buf->num_data2) { 14778 oem_resp_param->num_data2 = param_buf->num_data2; 14779 oem_resp_param->data_2 = param_buf->data2; 14780 } 14781 14782 if (param_buf->indirect_data) { 14783 oem_resp_param->indirect_data.pdev_id = 14784 param_buf->indirect_data->pdev_id; 14785 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 14786 oem_resp_param->indirect_data.addr = 14787 param_buf->indirect_data->addr_lo + 14788 ((uint64_t)temp_addr << 32); 14789 oem_resp_param->indirect_data.len = 14790 param_buf->indirect_data->len; 14791 } 14792 14793 return QDF_STATUS_SUCCESS; 14794 } 14795 #endif /* WIFI_POS_CONVERGED */ 14796 14797 /** 14798 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 14799 * @wmi_handle: wmi handle 14800 * @event_buf: pointer to event buffer 14801 * @cmd_status: status of HW mode change command 14802 * 14803 * Return QDF_STATUS_SUCCESS on success or proper error code. 14804 */ 14805 static QDF_STATUS 14806 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 14807 uint32_t *cmd_status) 14808 { 14809 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 14810 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 14811 14812 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 14813 if (!param_buf) { 14814 wmi_err("Invalid mode change event buffer"); 14815 return QDF_STATUS_E_INVAL; 14816 } 14817 14818 fixed_param = param_buf->fixed_param; 14819 if (!fixed_param) { 14820 wmi_err("Invalid fixed param"); 14821 return QDF_STATUS_E_INVAL; 14822 } 14823 14824 *cmd_status = fixed_param->status; 14825 return QDF_STATUS_SUCCESS; 14826 } 14827 14828 #ifdef FEATURE_ANI_LEVEL_REQUEST 14829 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 14830 uint32_t *freqs, 14831 uint8_t num_freqs) 14832 { 14833 wmi_buf_t buf; 14834 wmi_get_channel_ani_cmd_fixed_param *cmd; 14835 QDF_STATUS ret; 14836 uint32_t len; 14837 A_UINT32 *chan_list; 14838 uint8_t i, *buf_ptr; 14839 14840 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 14841 WMI_TLV_HDR_SIZE + 14842 num_freqs * sizeof(A_UINT32); 14843 14844 buf = wmi_buf_alloc(wmi_handle, len); 14845 if (!buf) 14846 return QDF_STATUS_E_FAILURE; 14847 14848 buf_ptr = (uint8_t *)wmi_buf_data(buf); 14849 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 14850 WMITLV_SET_HDR(&cmd->tlv_header, 14851 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 14852 WMITLV_GET_STRUCT_TLVLEN( 14853 wmi_get_channel_ani_cmd_fixed_param)); 14854 14855 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 14856 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 14857 (num_freqs * sizeof(A_UINT32))); 14858 14859 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 14860 for (i = 0; i < num_freqs; i++) { 14861 chan_list[i] = freqs[i]; 14862 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 14863 } 14864 14865 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 14866 WMI_GET_CHANNEL_ANI_CMDID); 14867 14868 if (QDF_IS_STATUS_ERROR(ret)) { 14869 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 14870 wmi_buf_free(buf); 14871 } 14872 14873 return ret; 14874 } 14875 14876 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 14877 struct wmi_host_ani_level_event **info, 14878 uint32_t *num_freqs) 14879 { 14880 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 14881 wmi_get_channel_ani_event_fixed_param *fixed_param; 14882 wmi_channel_ani_info_tlv_param *tlv_params; 14883 uint8_t *buf_ptr, i; 14884 14885 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 14886 if (!param_buf) { 14887 wmi_err("Invalid ani level event buffer"); 14888 return QDF_STATUS_E_INVAL; 14889 } 14890 14891 fixed_param = 14892 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 14893 if (!fixed_param) { 14894 wmi_err("Invalid fixed param"); 14895 return QDF_STATUS_E_INVAL; 14896 } 14897 14898 buf_ptr = (uint8_t *)fixed_param; 14899 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 14900 buf_ptr += WMI_TLV_HDR_SIZE; 14901 14902 *num_freqs = param_buf->num_ani_info; 14903 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 14904 wmi_err("Invalid number of freqs received"); 14905 return QDF_STATUS_E_INVAL; 14906 } 14907 14908 *info = qdf_mem_malloc(*num_freqs * 14909 sizeof(struct wmi_host_ani_level_event)); 14910 if (!(*info)) 14911 return QDF_STATUS_E_NOMEM; 14912 14913 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 14914 for (i = 0; i < param_buf->num_ani_info; i++) { 14915 (*info)[i].ani_level = tlv_params->ani_level; 14916 (*info)[i].chan_freq = tlv_params->chan_freq; 14917 tlv_params++; 14918 } 14919 14920 return QDF_STATUS_SUCCESS; 14921 } 14922 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 14923 14924 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 14925 /** 14926 * convert_wtc_scan_mode() - Function to convert TLV specific 14927 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 14928 * @scan_mode: scan freq scheme coming from firmware 14929 * 14930 * Return: ROAM_TRIGGER_SCAN_MODE 14931 */ 14932 static enum roam_scan_freq_scheme 14933 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 14934 { 14935 switch (scan_mode) { 14936 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 14937 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 14938 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 14939 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 14940 case ROAM_TRIGGER_SCAN_MODE_FULL: 14941 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 14942 default: 14943 return ROAM_SCAN_FREQ_SCHEME_NONE; 14944 } 14945 } 14946 14947 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 14948 { 14949 switch (fw_trig_reason) { 14950 case WMI_ROAM_TRIGGER_REASON_NONE: 14951 return ROAM_TRIGGER_REASON_NONE; 14952 case WMI_ROAM_TRIGGER_REASON_PER: 14953 return ROAM_TRIGGER_REASON_PER; 14954 case WMI_ROAM_TRIGGER_REASON_BMISS: 14955 return ROAM_TRIGGER_REASON_BMISS; 14956 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 14957 return ROAM_TRIGGER_REASON_LOW_RSSI; 14958 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 14959 return ROAM_TRIGGER_REASON_HIGH_RSSI; 14960 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 14961 return ROAM_TRIGGER_REASON_PERIODIC; 14962 case WMI_ROAM_TRIGGER_REASON_MAWC: 14963 return ROAM_TRIGGER_REASON_MAWC; 14964 case WMI_ROAM_TRIGGER_REASON_DENSE: 14965 return ROAM_TRIGGER_REASON_DENSE; 14966 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 14967 return ROAM_TRIGGER_REASON_BACKGROUND; 14968 case WMI_ROAM_TRIGGER_REASON_FORCED: 14969 return ROAM_TRIGGER_REASON_FORCED; 14970 case WMI_ROAM_TRIGGER_REASON_BTM: 14971 return ROAM_TRIGGER_REASON_BTM; 14972 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 14973 return ROAM_TRIGGER_REASON_UNIT_TEST; 14974 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 14975 return ROAM_TRIGGER_REASON_BSS_LOAD; 14976 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 14977 return ROAM_TRIGGER_REASON_DEAUTH; 14978 case WMI_ROAM_TRIGGER_REASON_IDLE: 14979 return ROAM_TRIGGER_REASON_IDLE; 14980 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 14981 return ROAM_TRIGGER_REASON_STA_KICKOUT; 14982 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 14983 return ROAM_TRIGGER_REASON_ESS_RSSI; 14984 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 14985 return ROAM_TRIGGER_REASON_WTC_BTM; 14986 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 14987 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 14988 case WMI_ROAM_TRIGGER_REASON_BTC: 14989 return ROAM_TRIGGER_REASON_BTC; 14990 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 14991 return ROAM_TRIGGER_REASON_MAX; 14992 default: 14993 return ROAM_TRIGGER_REASON_NONE; 14994 } 14995 } 14996 14997 /** 14998 * extract_roam_11kv_candidate_info - Extract btm candidate info 14999 * @wmi_handle: wmi_handle 15000 * @evt_buf: Event buffer 15001 * @dst_info: Destination buffer 15002 * 15003 * Return: QDF_STATUS 15004 */ 15005 static QDF_STATUS 15006 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 15007 struct wmi_btm_req_candidate_info *dst_info, 15008 uint8_t btm_idx, uint16_t num_cand) 15009 { 15010 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15011 wmi_roam_btm_request_candidate_info *src_data; 15012 uint8_t i; 15013 15014 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15015 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 15016 !param_buf->num_roam_btm_request_candidate_info || 15017 (btm_idx + 15018 num_cand) >= param_buf->num_roam_btm_request_candidate_info) 15019 return QDF_STATUS_SUCCESS; 15020 15021 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 15022 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 15023 num_cand = WLAN_MAX_BTM_CANDIDATE; 15024 for (i = 0; i < num_cand; i++) { 15025 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 15026 dst_info->candidate_bssid.bytes); 15027 dst_info->preference = src_data->preference; 15028 src_data++; 15029 dst_info++; 15030 } 15031 15032 return QDF_STATUS_SUCCESS; 15033 } 15034 15035 static enum roam_trigger_sub_reason 15036 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 15037 { 15038 switch (subreason) { 15039 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 15040 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 15041 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 15042 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 15043 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 15044 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 15045 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 15046 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 15047 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 15048 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 15049 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 15050 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 15051 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 15052 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 15053 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 15054 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 15055 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 15056 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 15057 default: 15058 break; 15059 } 15060 15061 return 0; 15062 } 15063 15064 /** 15065 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 15066 * from the WMI_ROAM_STATS_EVENTID 15067 * @wmi_handle: wmi handle 15068 * @evt_buf: Pointer to the event buffer 15069 * @trig: Pointer to destination structure to fill data 15070 * @idx: TLV id 15071 */ 15072 static QDF_STATUS 15073 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15074 struct wmi_roam_trigger_info *trig, uint8_t idx, 15075 uint8_t btm_idx) 15076 { 15077 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15078 wmi_roam_trigger_reason *src_data = NULL; 15079 uint32_t trig_reason; 15080 15081 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15082 if (!param_buf || !param_buf->roam_trigger_reason) 15083 return QDF_STATUS_E_FAILURE; 15084 15085 src_data = ¶m_buf->roam_trigger_reason[idx]; 15086 15087 trig->present = true; 15088 trig_reason = src_data->trigger_reason; 15089 trig->trigger_reason = wmi_convert_fw_to_cm_trig_reason(trig_reason); 15090 trig->trigger_sub_reason = 15091 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 15092 trig->current_rssi = src_data->current_rssi; 15093 trig->timestamp = src_data->timestamp; 15094 15095 switch (trig_reason) { 15096 case WMI_ROAM_TRIGGER_REASON_PER: 15097 case WMI_ROAM_TRIGGER_REASON_BMISS: 15098 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 15099 case WMI_ROAM_TRIGGER_REASON_MAWC: 15100 case WMI_ROAM_TRIGGER_REASON_DENSE: 15101 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 15102 case WMI_ROAM_TRIGGER_REASON_IDLE: 15103 case WMI_ROAM_TRIGGER_REASON_FORCED: 15104 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 15105 case WMI_ROAM_TRIGGER_REASON_BTC: 15106 return QDF_STATUS_SUCCESS; 15107 15108 case WMI_ROAM_TRIGGER_REASON_BTM: 15109 trig->btm_trig_data.btm_request_mode = 15110 src_data->btm_request_mode; 15111 trig->btm_trig_data.disassoc_timer = 15112 src_data->disassoc_imminent_timer; 15113 trig->btm_trig_data.validity_interval = 15114 src_data->validity_internal; 15115 trig->btm_trig_data.candidate_list_count = 15116 src_data->candidate_list_count; 15117 trig->btm_trig_data.btm_resp_status = 15118 src_data->btm_response_status_code; 15119 trig->btm_trig_data.btm_bss_termination_timeout = 15120 src_data->btm_bss_termination_timeout; 15121 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 15122 src_data->btm_mbo_assoc_retry_timeout; 15123 if ((btm_idx + trig->btm_trig_data.candidate_list_count) < 15124 param_buf->num_roam_btm_request_candidate_info) 15125 extract_roam_11kv_candidate_info( 15126 wmi_handle, evt_buf, 15127 trig->btm_trig_data.btm_cand, 15128 btm_idx, 15129 src_data->candidate_list_count); 15130 15131 return QDF_STATUS_SUCCESS; 15132 15133 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 15134 trig->cu_trig_data.cu_load = src_data->cu_load; 15135 return QDF_STATUS_SUCCESS; 15136 15137 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 15138 trig->deauth_trig_data.type = src_data->deauth_type; 15139 trig->deauth_trig_data.reason = src_data->deauth_reason; 15140 return QDF_STATUS_SUCCESS; 15141 15142 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 15143 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 15144 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 15145 return QDF_STATUS_SUCCESS; 15146 15147 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 15148 trig->wtc_btm_trig_data.roaming_mode = 15149 src_data->vendor_specific1[0]; 15150 trig->wtc_btm_trig_data.vsie_trigger_reason = 15151 src_data->vendor_specific1[1]; 15152 trig->wtc_btm_trig_data.sub_code = 15153 src_data->vendor_specific1[2]; 15154 trig->wtc_btm_trig_data.wtc_mode = 15155 src_data->vendor_specific1[3]; 15156 trig->wtc_btm_trig_data.wtc_scan_mode = 15157 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 15158 trig->wtc_btm_trig_data.wtc_rssi_th = 15159 src_data->vendor_specific1[5]; 15160 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 15161 src_data->vendor_specific1[6]; 15162 15163 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 15164 src_data->vendor_specific2[0]; 15165 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 15166 src_data->vendor_specific2[1]; 15167 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 15168 src_data->vendor_specific2[2]; 15169 15170 return QDF_STATUS_SUCCESS; 15171 default: 15172 return QDF_STATUS_SUCCESS; 15173 } 15174 15175 return QDF_STATUS_SUCCESS; 15176 } 15177 15178 /** 15179 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 15180 * from the WMI_ROAM_STATS_EVENTID 15181 * @wmi_handle: wmi handle 15182 * @evt_buf: Pointer to the event buffer 15183 * @dst: Pointer to destination structure to fill data 15184 * @ap_idx: TLV index for this roam scan 15185 * @num_cand: number of candidates list in the roam scan 15186 */ 15187 static QDF_STATUS 15188 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15189 struct wmi_roam_candidate_info *dst, 15190 uint8_t ap_idx, uint16_t num_cand) 15191 { 15192 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15193 wmi_roam_ap_info *src = NULL; 15194 uint8_t i; 15195 15196 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15197 if (!param_buf) { 15198 wmi_err("Param buf is NULL"); 15199 return QDF_STATUS_E_FAILURE; 15200 } 15201 15202 if (ap_idx >= param_buf->num_roam_ap_info) { 15203 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 15204 ap_idx, param_buf->num_roam_ap_info); 15205 return QDF_STATUS_E_FAILURE; 15206 } 15207 15208 src = ¶m_buf->roam_ap_info[ap_idx]; 15209 15210 for (i = 0; i < num_cand; i++) { 15211 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 15212 dst->type = src->candidate_type; 15213 dst->freq = src->channel; 15214 dst->etp = src->etp; 15215 dst->rssi = src->rssi; 15216 dst->rssi_score = src->rssi_score; 15217 dst->cu_load = src->cu_load; 15218 dst->cu_score = src->cu_score; 15219 dst->total_score = src->total_score; 15220 dst->timestamp = src->timestamp; 15221 dst->bl_reason = src->bl_reason; 15222 dst->bl_source = src->bl_source; 15223 dst->bl_timestamp = src->bl_timestamp; 15224 dst->bl_original_timeout = src->bl_original_timeout; 15225 15226 src++; 15227 dst++; 15228 } 15229 15230 return QDF_STATUS_SUCCESS; 15231 } 15232 15233 /** 15234 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 15235 * from the WMI_ROAM_STATS_EVENTID 15236 * @wmi_handle: wmi handle 15237 * @evt_buf: Pointer to the event buffer 15238 * @dst: Pointer to destination structure to fill data 15239 * @idx: TLV id 15240 * @chan_idx: Index of the channel tlv for the current roam trigger 15241 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 15242 */ 15243 static QDF_STATUS 15244 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15245 struct wmi_roam_scan_data *dst, uint8_t idx, 15246 uint8_t chan_idx, uint8_t ap_idx) 15247 { 15248 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15249 wmi_roam_scan_info *src_data = NULL; 15250 wmi_roam_scan_channel_info *src_chan = NULL; 15251 QDF_STATUS status; 15252 uint8_t i; 15253 15254 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15255 if (!param_buf || !param_buf->roam_scan_info || 15256 idx >= param_buf->num_roam_scan_info) 15257 return QDF_STATUS_E_FAILURE; 15258 15259 src_data = ¶m_buf->roam_scan_info[idx]; 15260 15261 dst->present = true; 15262 dst->type = src_data->roam_scan_type; 15263 dst->num_chan = src_data->roam_scan_channel_count; 15264 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 15265 dst->frame_info_count = src_data->frame_info_count; 15266 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 15267 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 15268 15269 /* Read the channel data only for dst->type is 0 (partial scan) */ 15270 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 15271 chan_idx < param_buf->num_roam_scan_chan_info) { 15272 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 15273 dst->num_chan = MAX_ROAM_SCAN_CHAN; 15274 15275 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 15276 for (i = 0; i < dst->num_chan; i++) { 15277 dst->chan_freq[i] = src_chan->channel; 15278 src_chan++; 15279 } 15280 } 15281 15282 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 15283 return QDF_STATUS_SUCCESS; 15284 15285 dst->num_ap = src_data->roam_ap_count; 15286 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 15287 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 15288 15289 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 15290 ap_idx, dst->num_ap); 15291 if (QDF_IS_STATUS_ERROR(status)) { 15292 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 15293 return status; 15294 } 15295 15296 return QDF_STATUS_SUCCESS; 15297 } 15298 15299 /** 15300 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 15301 * from the WMI_ROAM_STATS_EVENTID 15302 * @wmi_handle: wmi handle 15303 * @evt_buf: Pointer to the event buffer 15304 * @dst: Pointer to destination structure to fill data 15305 * @idx: TLV id 15306 */ 15307 static QDF_STATUS 15308 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15309 struct wmi_roam_result *dst, uint8_t idx) 15310 { 15311 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15312 wmi_roam_result *src_data = NULL; 15313 15314 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15315 if (!param_buf || !param_buf->roam_result || 15316 idx >= param_buf->num_roam_result) 15317 return QDF_STATUS_E_FAILURE; 15318 15319 src_data = ¶m_buf->roam_result[idx]; 15320 15321 dst->present = true; 15322 dst->status = src_data->roam_status; 15323 dst->timestamp = src_data->timestamp; 15324 dst->fail_reason = src_data->roam_fail_reason; 15325 15326 return QDF_STATUS_SUCCESS; 15327 } 15328 15329 /** 15330 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 15331 * from the WMI_ROAM_STATS_EVENTID 15332 * @wmi_handle: wmi handle 15333 * @evt_buf: Pointer to the event buffer 15334 * @dst: Pointer to destination structure to fill data 15335 * @idx: TLV id 15336 * @rpt_idx: Neighbor report Channel index 15337 */ 15338 static QDF_STATUS 15339 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15340 struct wmi_neighbor_report_data *dst, 15341 uint8_t idx, uint8_t rpt_idx) 15342 { 15343 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 15344 wmi_roam_neighbor_report_info *src_data = NULL; 15345 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 15346 uint8_t i; 15347 15348 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 15349 if (!param_buf || !param_buf->roam_neighbor_report_info || 15350 !param_buf->num_roam_neighbor_report_info || 15351 idx >= param_buf->num_roam_neighbor_report_info) { 15352 wmi_debug("Invalid 1kv param buf"); 15353 return QDF_STATUS_E_FAILURE; 15354 } 15355 15356 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 15357 15358 dst->present = true; 15359 dst->req_type = src_data->request_type; 15360 dst->num_freq = src_data->neighbor_report_channel_count; 15361 dst->req_time = src_data->neighbor_report_request_timestamp; 15362 dst->resp_time = src_data->neighbor_report_response_timestamp; 15363 dst->btm_query_token = src_data->btm_query_token; 15364 dst->btm_query_reason = src_data->btm_query_reason_code; 15365 15366 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 15367 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 15368 return QDF_STATUS_SUCCESS; 15369 15370 if (!param_buf->roam_neighbor_report_chan_info) { 15371 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 15372 dst->num_freq); 15373 dst->num_freq = 0; 15374 /* return success as its optional tlv and we can print neighbor 15375 * report received info 15376 */ 15377 return QDF_STATUS_SUCCESS; 15378 } 15379 15380 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 15381 15382 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 15383 dst->num_freq = MAX_ROAM_SCAN_CHAN; 15384 15385 for (i = 0; i < dst->num_freq; i++) { 15386 dst->freq[i] = src_freq->channel; 15387 src_freq++; 15388 } 15389 15390 return QDF_STATUS_SUCCESS; 15391 } 15392 #else 15393 static inline QDF_STATUS 15394 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15395 struct wmi_roam_trigger_info *trig, uint8_t idx, 15396 uint8_t btm_idx) 15397 { 15398 return QDF_STATUS_E_NOSUPPORT; 15399 } 15400 15401 static inline QDF_STATUS 15402 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15403 struct wmi_roam_result *dst, uint8_t idx) 15404 { 15405 return QDF_STATUS_E_NOSUPPORT; 15406 } 15407 15408 static QDF_STATUS 15409 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15410 struct wmi_neighbor_report_data *dst, 15411 uint8_t idx, uint8_t rpt_idx) 15412 { 15413 return QDF_STATUS_E_NOSUPPORT; 15414 } 15415 15416 static QDF_STATUS 15417 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15418 struct wmi_roam_scan_data *dst, uint8_t idx, 15419 uint8_t chan_idx, uint8_t ap_idx) 15420 { 15421 return QDF_STATUS_E_NOSUPPORT; 15422 } 15423 #endif 15424 15425 #ifdef WLAN_FEATURE_PKT_CAPTURE 15426 static QDF_STATUS 15427 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 15428 struct mgmt_offload_event_params *params) 15429 { 15430 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 15431 wmi_mgmt_hdr *hdr; 15432 15433 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 15434 if (!param_tlvs) 15435 return QDF_STATUS_E_INVAL; 15436 15437 hdr = param_tlvs->fixed_param; 15438 if (!hdr) 15439 return QDF_STATUS_E_INVAL; 15440 15441 if (hdr->buf_len > param_tlvs->num_bufp) 15442 return QDF_STATUS_E_INVAL; 15443 15444 params->tsf_l32 = hdr->tsf_l32; 15445 params->chan_freq = hdr->chan_freq; 15446 params->rate_kbps = hdr->rate_kbps; 15447 params->rssi = hdr->rssi; 15448 params->buf_len = hdr->buf_len; 15449 params->tx_status = hdr->tx_status; 15450 params->buf = param_tlvs->bufp; 15451 params->tx_retry_cnt = hdr->tx_retry_cnt; 15452 return QDF_STATUS_SUCCESS; 15453 } 15454 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 15455 15456 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 15457 static QDF_STATUS 15458 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 15459 struct smu_event_params *params) 15460 { 15461 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 15462 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 15463 15464 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 15465 if (!param_buf) { 15466 wmi_err("Invalid smart monitor event"); 15467 return QDF_STATUS_E_INVAL; 15468 } 15469 15470 smu_event = param_buf->fixed_param; 15471 if (!smu_event) { 15472 wmi_err("smart monitor event fixed param is NULL"); 15473 return QDF_STATUS_E_INVAL; 15474 } 15475 15476 params->vdev_id = smu_event->vdev_id; 15477 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 15478 return QDF_STATUS_E_INVAL; 15479 15480 params->rx_avg_rssi = smu_event->avg_rssi_data_dbm; 15481 15482 return QDF_STATUS_SUCCESS; 15483 } 15484 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 15485 15486 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 15487 /** 15488 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 15489 * 15490 * @wmi: wmi handle 15491 * @vdev_id: vdev id 15492 * @burst_mode: Indicates whether relation derived using FTM is needed for 15493 * each FTM frame or only aggregated result is required. 15494 * 15495 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 15496 * 15497 * Return: QDF_STATUS 15498 */ 15499 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 15500 uint32_t vdev_id, 15501 bool burst_mode) 15502 { 15503 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 15504 wmi_buf_t buf; 15505 int32_t len = sizeof(*cmd); 15506 15507 buf = wmi_buf_alloc(wmi, len); 15508 if (!buf) { 15509 wmi_err("wmi_buf_alloc failed"); 15510 return QDF_STATUS_E_NOMEM; 15511 } 15512 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 15513 WMITLV_SET_HDR(&cmd->tlv_header, 15514 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 15515 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 15516 cmd->vdev_id = vdev_id; 15517 cmd->agg_relation = burst_mode ? false : true; 15518 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 15519 wmi_err("Failed to send audio sync trigger cmd"); 15520 wmi_buf_free(buf); 15521 return QDF_STATUS_E_FAILURE; 15522 } 15523 15524 return QDF_STATUS_SUCCESS; 15525 } 15526 15527 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 15528 uint32_t vdev_id, 15529 uint64_t lpass_ts) 15530 { 15531 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 15532 wmi_buf_t buf; 15533 int32_t len = sizeof(*cmd); 15534 15535 buf = wmi_buf_alloc(wmi, len); 15536 if (!buf) { 15537 wmi_err("wmi_buf_alloc failed"); 15538 return QDF_STATUS_E_NOMEM; 15539 } 15540 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 15541 WMITLV_SET_HDR(&cmd->tlv_header, 15542 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 15543 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 15544 cmd->vdev_id = vdev_id; 15545 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 15546 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 15547 15548 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 15549 wmi_err("Failed to send audio qtime command"); 15550 wmi_buf_free(buf); 15551 return QDF_STATUS_E_FAILURE; 15552 } 15553 15554 return QDF_STATUS_SUCCESS; 15555 } 15556 15557 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 15558 wmi_unified_t wmi, void *buf, 15559 struct ftm_time_sync_start_stop_params *param) 15560 { 15561 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 15562 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 15563 15564 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 15565 if (!param_buf) { 15566 wmi_err("Invalid audio sync start stop event buffer"); 15567 return QDF_STATUS_E_FAILURE; 15568 } 15569 15570 resp_event = param_buf->fixed_param; 15571 if (!resp_event) { 15572 wmi_err("Invalid audio sync start stop fixed param buffer"); 15573 return QDF_STATUS_E_FAILURE; 15574 } 15575 15576 param->vdev_id = resp_event->vdev_id; 15577 param->timer_interval = resp_event->periodicity; 15578 param->num_reads = resp_event->reads_needed; 15579 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 15580 resp_event->qtimer_l32; 15581 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 15582 resp_event->mac_timer_l32; 15583 15584 wmi_debug("FTM time sync time_interval %d, num_reads %d", 15585 param->timer_interval, param->num_reads); 15586 15587 return QDF_STATUS_SUCCESS; 15588 } 15589 15590 static QDF_STATUS 15591 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 15592 struct ftm_time_sync_offset *param) 15593 { 15594 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 15595 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 15596 wmi_audio_sync_q_master_slave_times *q_pair; 15597 int iter; 15598 15599 param_buf = 15600 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 15601 if (!param_buf) { 15602 wmi_err("Invalid timesync ftm offset event buffer"); 15603 return QDF_STATUS_E_FAILURE; 15604 } 15605 15606 resp_event = param_buf->fixed_param; 15607 if (!resp_event) { 15608 wmi_err("Invalid timesync ftm offset fixed param buffer"); 15609 return QDF_STATUS_E_FAILURE; 15610 } 15611 15612 param->vdev_id = resp_event->vdev_id; 15613 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 15614 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 15615 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 15616 15617 q_pair = param_buf->audio_sync_q_master_slave_times; 15618 if (!q_pair) { 15619 wmi_err("Invalid q_master_slave_times buffer"); 15620 return QDF_STATUS_E_FAILURE; 15621 } 15622 15623 for (iter = 0; iter < param->num_qtime; iter++) { 15624 param->pairs[iter].qtime_master = ( 15625 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 15626 q_pair[iter].qmaster_l32; 15627 param->pairs[iter].qtime_slave = ( 15628 (uint64_t)q_pair[iter].qslave_u32 << 32) | 15629 q_pair[iter].qslave_l32; 15630 } 15631 return QDF_STATUS_SUCCESS; 15632 } 15633 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 15634 15635 /** 15636 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 15637 * @wmi: wmi handle 15638 * @vdev_id: vdev id 15639 * 15640 * TSF_TSTAMP_READ_VALUE is the only operation supported 15641 * Return: QDF_STATUS_SUCCESS for success or erro code 15642 */ 15643 static QDF_STATUS 15644 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 15645 { 15646 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 15647 wmi_buf_t buf; 15648 int32_t len = sizeof(*cmd); 15649 15650 buf = wmi_buf_alloc(wmi, len); 15651 if (!buf) 15652 return QDF_STATUS_E_NOMEM; 15653 15654 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 15655 WMITLV_SET_HDR(&cmd->tlv_header, 15656 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 15657 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 15658 cmd->vdev_id = vdev_id; 15659 cmd->tsf_action = TSF_TSTAMP_READ_VALUE; 15660 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 15661 if (wmi_unified_cmd_send(wmi, buf, len, 15662 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 15663 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 15664 __func__); 15665 wmi_buf_free(buf); 15666 return QDF_STATUS_E_FAILURE; 15667 } 15668 15669 return QDF_STATUS_SUCCESS; 15670 } 15671 15672 /** 15673 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 15674 * @wmi_handle: wmi handle 15675 * @param evt_buf: pointer to event buffer 15676 * @wmi_host_tsf_event param: Pointer to struct to hold event info 15677 * 15678 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 15679 */ 15680 static QDF_STATUS 15681 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 15682 struct wmi_host_tsf_event *param) 15683 { 15684 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 15685 wmi_vdev_tsf_report_event_fixed_param *evt; 15686 15687 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 15688 if (!param_buf) { 15689 wmi_err("Invalid tsf report event buffer"); 15690 return QDF_STATUS_E_INVAL; 15691 } 15692 15693 evt = param_buf->fixed_param; 15694 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 15695 param->vdev_id = evt->vdev_id; 15696 15697 return QDF_STATUS_SUCCESS; 15698 } 15699 15700 /** 15701 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 15702 * status tlv 15703 * @wmi_handle: wmi handle 15704 * @param evt_buf: pointer to event buffer 15705 * @param param: Pointer to hold csa switch count status event param 15706 * 15707 * Return: QDF_STATUS_SUCCESS for success or error code 15708 */ 15709 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 15710 wmi_unified_t wmi_handle, 15711 void *evt_buf, 15712 struct pdev_csa_switch_count_status *param) 15713 { 15714 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 15715 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 15716 15717 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 15718 evt_buf; 15719 if (!param_buf) { 15720 wmi_err("Invalid CSA status event"); 15721 return QDF_STATUS_E_INVAL; 15722 } 15723 15724 csa_status = param_buf->fixed_param; 15725 15726 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15727 wmi_handle, 15728 csa_status->pdev_id); 15729 param->current_switch_count = csa_status->current_switch_count; 15730 param->num_vdevs = csa_status->num_vdevs; 15731 param->vdev_ids = param_buf->vdev_ids; 15732 15733 return QDF_STATUS_SUCCESS; 15734 } 15735 15736 #ifdef CONFIG_AFC_SUPPORT 15737 /** 15738 * send_afc_cmd_tlv() - Sends the AFC indication to FW 15739 * @wmi_handle: wmi handle 15740 * @pdev_id: Pdev id 15741 * @param: Pointer to hold AFC indication. 15742 * 15743 * Return: QDF_STATUS_SUCCESS for success or error code 15744 */ 15745 static 15746 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 15747 uint8_t pdev_id, 15748 struct reg_afc_resp_rx_ind_info *param) 15749 { 15750 wmi_buf_t buf; 15751 wmi_afc_cmd_fixed_param *cmd; 15752 uint32_t len; 15753 uint8_t *buf_ptr; 15754 QDF_STATUS ret; 15755 15756 len = sizeof(wmi_afc_cmd_fixed_param); 15757 buf = wmi_buf_alloc(wmi_handle, len); 15758 if (!buf) 15759 return QDF_STATUS_E_NOMEM; 15760 15761 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15762 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 15763 15764 WMITLV_SET_HDR(&cmd->tlv_header, 15765 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 15766 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 15767 15768 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 15769 wmi_handle, 15770 pdev_id); 15771 cmd->cmd_type = param->cmd_type; 15772 cmd->serv_resp_format = param->serv_resp_format; 15773 15774 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 15775 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 15776 if (QDF_IS_STATUS_ERROR(ret)) { 15777 wmi_err("Failed to send WMI_AFC_CMDID"); 15778 wmi_buf_free(buf); 15779 return QDF_STATUS_E_FAILURE; 15780 } 15781 15782 return QDF_STATUS_SUCCESS; 15783 } 15784 #endif 15785 15786 /** 15787 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 15788 * @wmi_handle: wmi handle 15789 * @param: Pointer to hold TX power info 15790 * 15791 * Return: QDF_STATUS_SUCCESS for success or error code 15792 */ 15793 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 15794 uint8_t vdev_id, 15795 struct reg_tpc_power_info *param) 15796 { 15797 wmi_buf_t buf; 15798 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 15799 wmi_vdev_ch_power_info *ch_power_info; 15800 uint8_t *buf_ptr; 15801 uint16_t idx; 15802 uint32_t len; 15803 QDF_STATUS ret; 15804 15805 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 15806 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 15807 15808 buf = wmi_buf_alloc(wmi_handle, len); 15809 if (!buf) 15810 return QDF_STATUS_E_NOMEM; 15811 15812 buf_ptr = (uint8_t *)wmi_buf_data(buf); 15813 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 15814 15815 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 15816 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 15817 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 15818 15819 tpc_power_info_param->vdev_id = vdev_id; 15820 tpc_power_info_param->psd_power = param->is_psd_power; 15821 tpc_power_info_param->eirp_power = param->eirp_power; 15822 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 15823 15824 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 15825 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 15826 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 15827 15828 buf_ptr += WMI_TLV_HDR_SIZE; 15829 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 15830 15831 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 15832 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 15833 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 15834 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 15835 ch_power_info[idx].chan_cfreq = 15836 param->chan_power_info[idx].chan_cfreq; 15837 ch_power_info[idx].tx_power = 15838 param->chan_power_info[idx].tx_power; 15839 buf_ptr += sizeof(wmi_vdev_ch_power_info); 15840 } 15841 15842 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 15843 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 15844 WMI_VDEV_SET_TPC_POWER_CMDID); 15845 if (QDF_IS_STATUS_ERROR(ret)) 15846 wmi_buf_free(buf); 15847 15848 15849 return ret; 15850 } 15851 15852 /** 15853 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 15854 * @wmi_handle: wmi handle 15855 * @evt_buf: event buffer 15856 * @param: dpd status info 15857 * 15858 * Return: QDF_STATUS_SUCCESS for success or error code 15859 */ 15860 static QDF_STATUS 15861 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 15862 void *evt_buf, 15863 struct wmi_host_pdev_get_dpd_status_event *param) 15864 { 15865 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 15866 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 15867 15868 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 15869 if (!param_buf) { 15870 wmi_err("Invalid get dpd_status event"); 15871 return QDF_STATUS_E_INVAL; 15872 } 15873 15874 dpd_status = param_buf->fixed_param; 15875 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 15876 (wmi_handle, dpd_status->pdev_id); 15877 param->dpd_status = dpd_status->dpd_status; 15878 15879 return QDF_STATUS_SUCCESS; 15880 } 15881 15882 static int 15883 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 15884 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 15885 { 15886 if (status->halphy_cal_valid_bmap && valid_bit) 15887 return (status->halphy_cal_status && valid_bit); 15888 15889 return 0; 15890 } 15891 15892 static QDF_STATUS 15893 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 15894 void *evt_buf, 15895 struct wmi_host_pdev_get_halphy_cal_status_event *param) 15896 { 15897 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 15898 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 15899 15900 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 15901 if (!param_buf) { 15902 wmi_err("Invalid get halphy cal status event"); 15903 return QDF_STATUS_E_INVAL; 15904 } 15905 15906 halphy_cal_status = param_buf->fixed_param; 15907 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 15908 (wmi_handle, halphy_cal_status->pdev_id); 15909 param->halphy_cal_adc_status = 15910 convert_halphy_status(halphy_cal_status, 15911 WMI_HALPHY_CAL_ADC_BMAP); 15912 param->halphy_cal_bwfilter_status = 15913 convert_halphy_status(halphy_cal_status, 15914 WMI_HALPHY_CAL_BWFILTER_BMAP); 15915 param->halphy_cal_pdet_and_pal_status = 15916 convert_halphy_status(halphy_cal_status, 15917 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 15918 param->halphy_cal_rxdco_status = 15919 convert_halphy_status(halphy_cal_status, 15920 WMI_HALPHY_CAL_RXDCO_BMAP); 15921 param->halphy_cal_comb_txiq_rxiq_status = 15922 convert_halphy_status(halphy_cal_status, 15923 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 15924 param->halphy_cal_ibf_status = 15925 convert_halphy_status(halphy_cal_status, 15926 WMI_HALPHY_CAL_IBF_BMAP); 15927 param->halphy_cal_pa_droop_status = 15928 convert_halphy_status(halphy_cal_status, 15929 WMI_HALPHY_CAL_PA_DROOP_BMAP); 15930 param->halphy_cal_dac_status = 15931 convert_halphy_status(halphy_cal_status, 15932 WMI_HALPHY_CAL_DAC_BMAP); 15933 param->halphy_cal_ani_status = 15934 convert_halphy_status(halphy_cal_status, 15935 WMI_HALPHY_CAL_ANI_BMAP); 15936 param->halphy_cal_noise_floor_status = 15937 convert_halphy_status(halphy_cal_status, 15938 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 15939 15940 return QDF_STATUS_SUCCESS; 15941 } 15942 15943 /** 15944 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 15945 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 15946 * 15947 * Return: host_set_halphy_cal_status 15948 */ 15949 static enum wmi_host_set_halphy_cal_status 15950 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 15951 { 15952 if (fw_status == 0) 15953 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 15954 else if (fw_status == 1) 15955 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 15956 15957 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 15958 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 15959 } 15960 15961 /** 15962 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 15963 * @wmi_handle: wmi handle 15964 * @evt_buf: event buffer 15965 * @param: set halphy cal status info 15966 * 15967 * Return: QDF_STATUS_SUCCESS for success or error code 15968 */ 15969 static QDF_STATUS 15970 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 15971 void *evt_buf, 15972 struct wmi_host_pdev_set_halphy_cal_event *param) 15973 { 15974 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 15975 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 15976 15977 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 15978 if (!param_buf) { 15979 wmi_err("Invalid set halphy_status event"); 15980 return QDF_STATUS_E_INVAL; 15981 } 15982 15983 set_halphy_status = param_buf->fixed_param; 15984 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 15985 (wmi_handle, set_halphy_status->pdev_id); 15986 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 15987 15988 return QDF_STATUS_SUCCESS; 15989 } 15990 15991 /** 15992 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 15993 * @wmi_handle: wmi handle 15994 * @evt_buf: pointer to event buffer 15995 * @len: length of the event buffer 15996 * @param: Pointer to hold install key complete event param 15997 * 15998 * Return: QDF_STATUS_SUCCESS for success or error code 15999 */ 16000 static QDF_STATUS 16001 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 16002 void *evt_buf, uint32_t len, 16003 struct wmi_install_key_comp_event *param) 16004 { 16005 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 16006 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 16007 16008 if (len < sizeof(*param_buf)) { 16009 wmi_err("invalid event buf len %d", len); 16010 return QDF_STATUS_E_INVAL; 16011 } 16012 16013 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 16014 if (!param_buf) { 16015 wmi_err("received null buf from target"); 16016 return QDF_STATUS_E_INVAL; 16017 } 16018 16019 key_fp = param_buf->fixed_param; 16020 if (!key_fp) { 16021 wmi_err("received null event data from target"); 16022 return QDF_STATUS_E_INVAL; 16023 } 16024 16025 param->vdev_id = key_fp->vdev_id; 16026 param->key_ix = key_fp->key_ix; 16027 param->key_flags = key_fp->key_flags; 16028 param->status = key_fp->status; 16029 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 16030 param->peer_macaddr); 16031 16032 return QDF_STATUS_SUCCESS; 16033 } 16034 16035 static QDF_STATUS 16036 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 16037 struct wmi_host_send_set_halphy_cal_info *param) 16038 { 16039 wmi_buf_t buf; 16040 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 16041 QDF_STATUS ret; 16042 uint32_t len; 16043 16044 len = sizeof(*cmd); 16045 16046 buf = wmi_buf_alloc(wmi_handle, len); 16047 if (!buf) 16048 return QDF_STATUS_E_FAILURE; 16049 16050 cmd = (void *)wmi_buf_data(buf); 16051 16052 WMITLV_SET_HDR(&cmd->tlv_header, 16053 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 16054 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 16055 16056 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 16057 param->pdev_id); 16058 cmd->online_halphy_cals_bmap = param->value; 16059 cmd->home_scan_channel = param->chan_sel; 16060 16061 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 16062 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 16063 if (QDF_IS_STATUS_ERROR(ret)) { 16064 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 16065 wmi_buf_free(buf); 16066 } 16067 16068 return ret; 16069 } 16070 16071 struct wmi_ops tlv_ops = { 16072 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 16073 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 16074 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 16075 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 16076 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 16077 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 16078 .send_peer_param_cmd = send_peer_param_cmd_tlv, 16079 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 16080 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 16081 .send_peer_create_cmd = send_peer_create_cmd_tlv, 16082 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 16083 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 16084 .send_peer_rx_reorder_queue_setup_cmd = 16085 send_peer_rx_reorder_queue_setup_cmd_tlv, 16086 .send_peer_rx_reorder_queue_remove_cmd = 16087 send_peer_rx_reorder_queue_remove_cmd_tlv, 16088 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 16089 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 16090 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 16091 .send_suspend_cmd = send_suspend_cmd_tlv, 16092 .send_resume_cmd = send_resume_cmd_tlv, 16093 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 16094 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 16095 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 16096 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 16097 .send_dbglog_cmd = send_dbglog_cmd_tlv, 16098 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 16099 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 16100 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 16101 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 16102 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 16103 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 16104 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 16105 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 16106 .send_scan_start_cmd = send_scan_start_cmd_tlv, 16107 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 16108 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 16109 .send_mgmt_cmd = send_mgmt_cmd_tlv, 16110 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 16111 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 16112 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 16113 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 16114 .send_set_sta_uapsd_auto_trig_cmd = 16115 send_set_sta_uapsd_auto_trig_cmd_tlv, 16116 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 16117 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 16118 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 16119 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 16120 .send_lro_config_cmd = send_lro_config_cmd_tlv, 16121 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 16122 .send_probe_rsp_tmpl_send_cmd = 16123 send_probe_rsp_tmpl_send_cmd_tlv, 16124 .send_p2p_go_set_beacon_ie_cmd = 16125 send_p2p_go_set_beacon_ie_cmd_tlv, 16126 .send_setup_install_key_cmd = 16127 send_setup_install_key_cmd_tlv, 16128 .send_scan_probe_setoui_cmd = 16129 send_scan_probe_setoui_cmd_tlv, 16130 #ifdef IPA_OFFLOAD 16131 .send_ipa_offload_control_cmd = 16132 send_ipa_offload_control_cmd_tlv, 16133 #endif 16134 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 16135 .send_pno_start_cmd = send_pno_start_cmd_tlv, 16136 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 16137 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 16138 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 16139 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 16140 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 16141 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 16142 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 16143 .send_unified_ll_stats_get_sta_cmd = 16144 send_unified_ll_stats_get_sta_cmd_tlv, 16145 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 16146 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 16147 .send_congestion_cmd = send_congestion_cmd_tlv, 16148 .send_snr_request_cmd = send_snr_request_cmd_tlv, 16149 .send_snr_cmd = send_snr_cmd_tlv, 16150 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 16151 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 16152 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 16153 #endif 16154 #ifdef WLAN_SUPPORT_GREEN_AP 16155 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 16156 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 16157 .extract_green_ap_egap_status_info = 16158 extract_green_ap_egap_status_info_tlv, 16159 #endif 16160 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 16161 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 16162 #ifdef FEATURE_OEM_DATA 16163 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 16164 #endif 16165 #ifdef WLAN_FEATURE_CIF_CFR 16166 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 16167 #endif 16168 .send_dfs_phyerr_filter_offload_en_cmd = 16169 send_dfs_phyerr_filter_offload_en_cmd_tlv, 16170 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 16171 .send_process_dhcpserver_offload_cmd = 16172 send_process_dhcpserver_offload_cmd_tlv, 16173 .send_pdev_set_regdomain_cmd = 16174 send_pdev_set_regdomain_cmd_tlv, 16175 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 16176 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 16177 .save_fw_version_cmd = save_fw_version_cmd_tlv, 16178 .check_and_update_fw_version = 16179 check_and_update_fw_version_cmd_tlv, 16180 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 16181 .send_enable_specific_fw_logs_cmd = 16182 send_enable_specific_fw_logs_cmd_tlv, 16183 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 16184 .send_unit_test_cmd = send_unit_test_cmd_tlv, 16185 #ifdef FEATURE_WLAN_APF 16186 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 16187 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 16188 .send_apf_write_work_memory_cmd = 16189 wmi_send_apf_write_work_memory_cmd_tlv, 16190 .send_apf_read_work_memory_cmd = 16191 wmi_send_apf_read_work_memory_cmd_tlv, 16192 .extract_apf_read_memory_resp_event = 16193 wmi_extract_apf_read_memory_resp_event_tlv, 16194 #endif /* FEATURE_WLAN_APF */ 16195 .init_cmd_send = init_cmd_send_tlv, 16196 .send_vdev_set_custom_aggr_size_cmd = 16197 send_vdev_set_custom_aggr_size_cmd_tlv, 16198 .send_vdev_set_qdepth_thresh_cmd = 16199 send_vdev_set_qdepth_thresh_cmd_tlv, 16200 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 16201 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 16202 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 16203 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 16204 .send_periodic_chan_stats_config_cmd = 16205 send_periodic_chan_stats_config_cmd_tlv, 16206 #ifdef WLAN_IOT_SIM_SUPPORT 16207 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 16208 #endif 16209 .send_vdev_spectral_configure_cmd = 16210 send_vdev_spectral_configure_cmd_tlv, 16211 .send_vdev_spectral_enable_cmd = 16212 send_vdev_spectral_enable_cmd_tlv, 16213 #ifdef WLAN_CONV_SPECTRAL_ENABLE 16214 .extract_pdev_sscan_fw_cmd_fixed_param = 16215 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 16216 .extract_pdev_sscan_fft_bin_index = 16217 extract_pdev_sscan_fft_bin_index_tlv, 16218 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 16219 .send_thermal_mitigation_param_cmd = 16220 send_thermal_mitigation_param_cmd_tlv, 16221 .send_process_update_edca_param_cmd = 16222 send_process_update_edca_param_cmd_tlv, 16223 .send_bss_color_change_enable_cmd = 16224 send_bss_color_change_enable_cmd_tlv, 16225 .send_coex_config_cmd = send_coex_config_cmd_tlv, 16226 .send_set_country_cmd = send_set_country_cmd_tlv, 16227 .send_addba_send_cmd = send_addba_send_cmd_tlv, 16228 .send_delba_send_cmd = send_delba_send_cmd_tlv, 16229 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 16230 .get_target_cap_from_service_ready = extract_service_ready_tlv, 16231 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 16232 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 16233 .extract_host_mem_req = extract_host_mem_req_tlv, 16234 .save_service_bitmap = save_service_bitmap_tlv, 16235 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 16236 .is_service_enabled = is_service_enabled_tlv, 16237 .save_fw_version = save_fw_version_in_service_ready_tlv, 16238 .ready_extract_init_status = ready_extract_init_status_tlv, 16239 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 16240 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 16241 .extract_ready_event_params = extract_ready_event_params_tlv, 16242 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 16243 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 16244 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 16245 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 16246 #ifdef FEATURE_WLAN_SCAN_PNO 16247 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 16248 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 16249 #endif 16250 .extract_unit_test = extract_unit_test_tlv, 16251 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 16252 .extract_bcn_stats = extract_bcn_stats_tlv, 16253 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 16254 .extract_chan_stats = extract_chan_stats_tlv, 16255 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 16256 .extract_profile_ctx = extract_profile_ctx_tlv, 16257 .extract_profile_data = extract_profile_data_tlv, 16258 .send_fw_test_cmd = send_fw_test_cmd_tlv, 16259 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 16260 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 16261 .extract_service_ready_ext = extract_service_ready_ext_tlv, 16262 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 16263 .extract_hw_mode_cap_service_ready_ext = 16264 extract_hw_mode_cap_service_ready_ext_tlv, 16265 .extract_mac_phy_cap_service_ready_ext = 16266 extract_mac_phy_cap_service_ready_ext_tlv, 16267 .extract_mac_phy_cap_service_ready_ext2 = 16268 extract_mac_phy_cap_service_ready_ext2_tlv, 16269 .extract_reg_cap_service_ready_ext = 16270 extract_reg_cap_service_ready_ext_tlv, 16271 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 16272 .extract_dbr_ring_cap_service_ready_ext = 16273 extract_dbr_ring_cap_service_ready_ext_tlv, 16274 .extract_dbr_ring_cap_service_ready_ext2 = 16275 extract_dbr_ring_cap_service_ready_ext2_tlv, 16276 .extract_scan_radio_cap_service_ready_ext2 = 16277 extract_scan_radio_cap_service_ready_ext2_tlv, 16278 .extract_sar_cap_service_ready_ext = 16279 extract_sar_cap_service_ready_ext_tlv, 16280 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 16281 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 16282 .extract_fips_event_data = extract_fips_event_data_tlv, 16283 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 16284 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 16285 #endif 16286 #ifdef WLAN_FEATURE_DISA 16287 .extract_encrypt_decrypt_resp_event = 16288 extract_encrypt_decrypt_resp_event_tlv, 16289 #endif 16290 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 16291 .extract_get_pn_data = extract_get_pn_data_tlv, 16292 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 16293 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 16294 #ifdef WLAN_FEATURE_DISA 16295 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 16296 #endif 16297 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 16298 .send_wlan_profile_hist_intvl_cmd = 16299 send_wlan_profile_hist_intvl_cmd_tlv, 16300 .is_management_record = is_management_record_tlv, 16301 .is_diag_event = is_diag_event_tlv, 16302 #ifdef WLAN_FEATURE_ACTION_OUI 16303 .send_action_oui_cmd = send_action_oui_cmd_tlv, 16304 #endif 16305 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 16306 #ifdef QCA_SUPPORT_AGILE_DFS 16307 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 16308 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 16309 #endif 16310 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 16311 .extract_reg_chan_list_update_event = 16312 extract_reg_chan_list_update_event_tlv, 16313 #ifdef CONFIG_BAND_6GHZ 16314 .extract_reg_chan_list_ext_update_event = 16315 extract_reg_chan_list_ext_update_event_tlv, 16316 #ifdef CONFIG_AFC_SUPPORT 16317 .extract_afc_event = extract_afc_event_tlv, 16318 #endif 16319 #endif 16320 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 16321 .extract_num_rf_characterization_entries = 16322 extract_num_rf_characterization_entries_tlv, 16323 .extract_rf_characterization_entries = 16324 extract_rf_characterization_entries_tlv, 16325 #endif 16326 .extract_chainmask_tables = 16327 extract_chainmask_tables_tlv, 16328 .extract_thermal_stats = extract_thermal_stats_tlv, 16329 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 16330 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 16331 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 16332 #ifdef DFS_COMPONENT_ENABLE 16333 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 16334 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 16335 .extract_dfs_radar_detection_event = 16336 extract_dfs_radar_detection_event_tlv, 16337 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 16338 #endif 16339 .convert_pdev_id_host_to_target = 16340 convert_host_pdev_id_to_target_pdev_id_legacy, 16341 .convert_pdev_id_target_to_host = 16342 convert_target_pdev_id_to_host_pdev_id_legacy, 16343 16344 .convert_host_pdev_id_to_target = 16345 convert_host_pdev_id_to_target_pdev_id, 16346 .convert_target_pdev_id_to_host = 16347 convert_target_pdev_id_to_host_pdev_id, 16348 16349 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 16350 16351 .convert_phy_id_host_to_target = 16352 convert_host_phy_id_to_target_phy_id_legacy, 16353 .convert_phy_id_target_to_host = 16354 convert_target_phy_id_to_host_phy_id_legacy, 16355 16356 .convert_host_phy_id_to_target = 16357 convert_host_phy_id_to_target_phy_id, 16358 .convert_target_phy_id_to_host = 16359 convert_target_phy_id_to_host_phy_id, 16360 16361 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 16362 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 16363 .extract_reg_11d_new_country_event = 16364 extract_reg_11d_new_country_event_tlv, 16365 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 16366 .extract_reg_ch_avoid_event = 16367 extract_reg_ch_avoid_event_tlv, 16368 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 16369 .extract_obss_detection_info = extract_obss_detection_info_tlv, 16370 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 16371 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 16372 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 16373 .wmi_check_command_params = wmitlv_check_command_tlv_params, 16374 .extract_comb_phyerr = extract_comb_phyerr_tlv, 16375 .extract_single_phyerr = extract_single_phyerr_tlv, 16376 #ifdef QCA_SUPPORT_CP_STATS 16377 .extract_cca_stats = extract_cca_stats_tlv, 16378 #endif 16379 .extract_esp_estimation_ev_param = 16380 extract_esp_estimation_ev_param_tlv, 16381 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 16382 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 16383 #ifdef OBSS_PD 16384 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 16385 .send_obss_spatial_reuse_set_def_thresh = 16386 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 16387 .send_self_srg_bss_color_bitmap_set = 16388 send_self_srg_bss_color_bitmap_set_cmd_tlv, 16389 .send_self_srg_partial_bssid_bitmap_set = 16390 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 16391 .send_self_srg_obss_color_enable_bitmap = 16392 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 16393 .send_self_srg_obss_bssid_enable_bitmap = 16394 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 16395 .send_self_non_srg_obss_color_enable_bitmap = 16396 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 16397 .send_self_non_srg_obss_bssid_enable_bitmap = 16398 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 16399 #endif 16400 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 16401 .extract_ctl_failsafe_check_ev_param = 16402 extract_ctl_failsafe_check_ev_param_tlv, 16403 #ifdef WIFI_POS_CONVERGED 16404 .extract_oem_response_param = extract_oem_response_param_tlv, 16405 #endif /* WIFI_POS_CONVERGED */ 16406 #ifdef WLAN_MWS_INFO_DEBUGFS 16407 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 16408 #endif 16409 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 16410 #ifdef FEATURE_ANI_LEVEL_REQUEST 16411 .send_ani_level_cmd = send_ani_level_cmd_tlv, 16412 .extract_ani_level = extract_ani_level_tlv, 16413 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 16414 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 16415 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 16416 .extract_roam_result_stats = extract_roam_result_stats_tlv, 16417 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 16418 #ifdef WLAN_FEATURE_PKT_CAPTURE 16419 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 16420 #endif 16421 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 16422 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 16423 #endif 16424 16425 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 16426 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 16427 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 16428 .extract_time_sync_ftm_start_stop_event = 16429 extract_time_sync_ftm_start_stop_event_tlv, 16430 .extract_time_sync_ftm_offset_event = 16431 extract_time_sync_ftm_offset_event_tlv, 16432 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 16433 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 16434 .send_injector_config_cmd = send_injector_config_cmd_tlv, 16435 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 16436 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 16437 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 16438 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 16439 .extract_cp_stats_more_pending = 16440 extract_cp_stats_more_pending_tlv, 16441 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 16442 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 16443 .extract_pdev_csa_switch_count_status = 16444 extract_pdev_csa_switch_count_status_tlv, 16445 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 16446 #ifdef CONFIG_AFC_SUPPORT 16447 .send_afc_cmd = send_afc_cmd_tlv, 16448 #endif 16449 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 16450 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 16451 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 16452 .send_set_halphy_cal = send_set_halphy_cal_tlv, 16453 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 16454 #ifdef WLAN_MGMT_RX_REO_SUPPORT 16455 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 16456 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 16457 .send_mgmt_rx_reo_filter_config_cmd = 16458 send_mgmt_rx_reo_filter_config_cmd_tlv, 16459 #endif 16460 }; 16461 16462 /** 16463 * populate_tlv_event_id() - populates wmi event ids 16464 * 16465 * @param event_ids: Pointer to hold event ids 16466 * Return: None 16467 */ 16468 static void populate_tlv_events_id(uint32_t *event_ids) 16469 { 16470 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 16471 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 16472 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 16473 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 16474 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 16475 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 16476 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 16477 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 16478 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 16479 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 16480 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 16481 event_ids[wmi_service_ready_ext_event_id] = 16482 WMI_SERVICE_READY_EXT_EVENTID; 16483 event_ids[wmi_service_ready_ext2_event_id] = 16484 WMI_SERVICE_READY_EXT2_EVENTID; 16485 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 16486 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 16487 event_ids[wmi_vdev_install_key_complete_event_id] = 16488 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 16489 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 16490 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 16491 16492 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 16493 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 16494 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 16495 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 16496 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 16497 event_ids[wmi_peer_estimated_linkspeed_event_id] = 16498 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 16499 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 16500 event_ids[wmi_peer_create_conf_event_id] = 16501 WMI_PEER_CREATE_CONF_EVENTID; 16502 event_ids[wmi_peer_delete_response_event_id] = 16503 WMI_PEER_DELETE_RESP_EVENTID; 16504 event_ids[wmi_peer_delete_all_response_event_id] = 16505 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 16506 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 16507 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 16508 event_ids[wmi_tbttoffset_update_event_id] = 16509 WMI_TBTTOFFSET_UPDATE_EVENTID; 16510 event_ids[wmi_ext_tbttoffset_update_event_id] = 16511 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 16512 event_ids[wmi_offload_bcn_tx_status_event_id] = 16513 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 16514 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 16515 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 16516 event_ids[wmi_mgmt_tx_completion_event_id] = 16517 WMI_MGMT_TX_COMPLETION_EVENTID; 16518 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 16519 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 16520 event_ids[wmi_tx_delba_complete_event_id] = 16521 WMI_TX_DELBA_COMPLETE_EVENTID; 16522 event_ids[wmi_tx_addba_complete_event_id] = 16523 WMI_TX_ADDBA_COMPLETE_EVENTID; 16524 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 16525 16526 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 16527 16528 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 16529 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 16530 16531 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 16532 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 16533 16534 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 16535 16536 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 16537 event_ids[wmi_p2p_lo_stop_event_id] = 16538 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 16539 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 16540 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 16541 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 16542 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 16543 event_ids[wmi_d0_wow_disable_ack_event_id] = 16544 WMI_D0_WOW_DISABLE_ACK_EVENTID; 16545 event_ids[wmi_wow_initial_wakeup_event_id] = 16546 WMI_WOW_INITIAL_WAKEUP_EVENTID; 16547 16548 event_ids[wmi_rtt_meas_report_event_id] = 16549 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 16550 event_ids[wmi_tsf_meas_report_event_id] = 16551 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 16552 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 16553 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 16554 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 16555 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 16556 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 16557 event_ids[wmi_diag_event_id_log_supported_event_id] = 16558 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 16559 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 16560 event_ids[wmi_nlo_scan_complete_event_id] = 16561 WMI_NLO_SCAN_COMPLETE_EVENTID; 16562 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 16563 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 16564 16565 event_ids[wmi_gtk_offload_status_event_id] = 16566 WMI_GTK_OFFLOAD_STATUS_EVENTID; 16567 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 16568 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 16569 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 16570 16571 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 16572 16573 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 16574 16575 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 16576 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 16577 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 16578 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 16579 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 16580 event_ids[wmi_wlan_profile_data_event_id] = 16581 WMI_WLAN_PROFILE_DATA_EVENTID; 16582 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 16583 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 16584 event_ids[wmi_vdev_get_keepalive_event_id] = 16585 WMI_VDEV_GET_KEEPALIVE_EVENTID; 16586 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 16587 16588 event_ids[wmi_diag_container_event_id] = 16589 WMI_DIAG_DATA_CONTAINER_EVENTID; 16590 16591 event_ids[wmi_host_auto_shutdown_event_id] = 16592 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 16593 16594 event_ids[wmi_update_whal_mib_stats_event_id] = 16595 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 16596 16597 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 16598 event_ids[wmi_update_vdev_rate_stats_event_id] = 16599 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 16600 16601 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 16602 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 16603 16604 /** Set OCB Sched Response, deprecated */ 16605 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 16606 16607 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 16608 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 16609 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 16610 16611 /* GPIO Event */ 16612 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 16613 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 16614 16615 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 16616 event_ids[wmi_rfkill_state_change_event_id] = 16617 WMI_RFKILL_STATE_CHANGE_EVENTID; 16618 16619 /* TDLS Event */ 16620 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 16621 16622 event_ids[wmi_batch_scan_enabled_event_id] = 16623 WMI_BATCH_SCAN_ENABLED_EVENTID; 16624 event_ids[wmi_batch_scan_result_event_id] = 16625 WMI_BATCH_SCAN_RESULT_EVENTID; 16626 /* OEM Event */ 16627 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 16628 event_ids[wmi_oem_meas_report_event_id] = 16629 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 16630 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 16631 16632 /* NAN Event */ 16633 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 16634 16635 /* LPI Event */ 16636 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 16637 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 16638 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 16639 16640 /* ExtScan events */ 16641 event_ids[wmi_extscan_start_stop_event_id] = 16642 WMI_EXTSCAN_START_STOP_EVENTID; 16643 event_ids[wmi_extscan_operation_event_id] = 16644 WMI_EXTSCAN_OPERATION_EVENTID; 16645 event_ids[wmi_extscan_table_usage_event_id] = 16646 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 16647 event_ids[wmi_extscan_cached_results_event_id] = 16648 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 16649 event_ids[wmi_extscan_wlan_change_results_event_id] = 16650 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 16651 event_ids[wmi_extscan_hotlist_match_event_id] = 16652 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 16653 event_ids[wmi_extscan_capabilities_event_id] = 16654 WMI_EXTSCAN_CAPABILITIES_EVENTID; 16655 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 16656 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 16657 16658 /* mDNS offload events */ 16659 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 16660 16661 /* SAP Authentication offload events */ 16662 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 16663 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 16664 16665 /** Out-of-context-of-bss (OCB) events */ 16666 event_ids[wmi_ocb_set_config_resp_event_id] = 16667 WMI_OCB_SET_CONFIG_RESP_EVENTID; 16668 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 16669 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 16670 event_ids[wmi_dcc_get_stats_resp_event_id] = 16671 WMI_DCC_GET_STATS_RESP_EVENTID; 16672 event_ids[wmi_dcc_update_ndl_resp_event_id] = 16673 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 16674 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 16675 /* System-On-Chip events */ 16676 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 16677 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 16678 event_ids[wmi_soc_hw_mode_transition_event_id] = 16679 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 16680 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 16681 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 16682 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 16683 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 16684 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 16685 event_ids[wmi_vdev_ocac_complete_event_id] = 16686 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 16687 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 16688 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 16689 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 16690 #ifdef CONFIG_AFC_SUPPORT 16691 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 16692 #endif 16693 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 16694 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 16695 event_ids[wmi_peer_sta_ps_statechg_event_id] = 16696 WMI_PEER_STA_PS_STATECHG_EVENTID; 16697 event_ids[wmi_pdev_channel_hopping_event_id] = 16698 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 16699 event_ids[wmi_offchan_data_tx_completion_event] = 16700 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 16701 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 16702 event_ids[wmi_dfs_radar_detection_event_id] = 16703 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 16704 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 16705 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 16706 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 16707 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 16708 event_ids[wmi_service_available_event_id] = 16709 WMI_SERVICE_AVAILABLE_EVENTID; 16710 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 16711 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 16712 /* NDP events */ 16713 event_ids[wmi_ndp_initiator_rsp_event_id] = 16714 WMI_NDP_INITIATOR_RSP_EVENTID; 16715 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 16716 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 16717 event_ids[wmi_ndp_responder_rsp_event_id] = 16718 WMI_NDP_RESPONDER_RSP_EVENTID; 16719 event_ids[wmi_ndp_end_indication_event_id] = 16720 WMI_NDP_END_INDICATION_EVENTID; 16721 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 16722 event_ids[wmi_ndl_schedule_update_event_id] = 16723 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 16724 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 16725 16726 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 16727 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 16728 event_ids[wmi_pdev_chip_power_stats_event_id] = 16729 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 16730 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 16731 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 16732 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 16733 event_ids[wmi_apf_capability_info_event_id] = 16734 WMI_BPF_CAPABILIY_INFO_EVENTID; 16735 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 16736 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 16737 event_ids[wmi_report_rx_aggr_failure_event_id] = 16738 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 16739 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 16740 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 16741 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 16742 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 16743 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 16744 event_ids[wmi_pdev_hw_mode_transition_event_id] = 16745 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 16746 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 16747 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 16748 event_ids[wmi_coex_bt_activity_event_id] = 16749 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 16750 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 16751 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 16752 event_ids[wmi_radio_tx_power_level_stats_event_id] = 16753 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 16754 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 16755 event_ids[wmi_dma_buf_release_event_id] = 16756 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 16757 event_ids[wmi_sap_obss_detection_report_event_id] = 16758 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 16759 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 16760 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 16761 event_ids[wmi_obss_color_collision_report_event_id] = 16762 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 16763 event_ids[wmi_pdev_div_rssi_antid_event_id] = 16764 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 16765 #ifdef WLAN_SUPPORT_TWT 16766 event_ids[wmi_twt_enable_complete_event_id] = 16767 WMI_TWT_ENABLE_COMPLETE_EVENTID; 16768 event_ids[wmi_twt_disable_complete_event_id] = 16769 WMI_TWT_DISABLE_COMPLETE_EVENTID; 16770 event_ids[wmi_twt_add_dialog_complete_event_id] = 16771 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 16772 event_ids[wmi_twt_del_dialog_complete_event_id] = 16773 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 16774 event_ids[wmi_twt_pause_dialog_complete_event_id] = 16775 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 16776 event_ids[wmi_twt_resume_dialog_complete_event_id] = 16777 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 16778 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 16779 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 16780 event_ids[wmi_twt_session_stats_event_id] = 16781 WMI_TWT_SESSION_STATS_EVENTID; 16782 event_ids[wmi_twt_notify_event_id] = 16783 WMI_TWT_NOTIFY_EVENTID; 16784 event_ids[wmi_twt_ack_complete_event_id] = 16785 WMI_TWT_ACK_EVENTID; 16786 #endif 16787 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 16788 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 16789 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 16790 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 16791 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 16792 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 16793 event_ids[wmi_pdev_interop_issues_ap_event_id] = 16794 WMI_PDEV_RAP_INFO_EVENTID; 16795 #endif 16796 #ifdef AST_HKV1_WORKAROUND 16797 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 16798 #endif 16799 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 16800 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 16801 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 16802 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 16803 event_ids[wmi_roam_blacklist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 16804 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 16805 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 16806 event_ids[wmi_pdev_cold_boot_cal_event_id] = 16807 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 16808 #ifdef WLAN_MWS_INFO_DEBUGFS 16809 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 16810 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 16811 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 16812 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 16813 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 16814 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 16815 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 16816 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 16817 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 16818 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 16819 #endif 16820 event_ids[wmi_coex_report_antenna_isolation_event_id] = 16821 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 16822 event_ids[wmi_peer_ratecode_list_event_id] = 16823 WMI_PEER_RATECODE_LIST_EVENTID; 16824 event_ids[wmi_chan_rf_characterization_info_event_id] = 16825 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 16826 event_ids[wmi_roam_auth_offload_event_id] = 16827 WMI_ROAM_PREAUTH_START_EVENTID; 16828 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 16829 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 16830 event_ids[wmi_motion_det_base_line_host_eventid] = 16831 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 16832 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 16833 event_ids[wmi_peer_tx_pn_response_event_id] = 16834 WMI_PEER_TX_PN_RESPONSE_EVENTID; 16835 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 16836 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 16837 event_ids[wmi_mgmt_offload_data_event_id] = 16838 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 16839 event_ids[wmi_nan_dmesg_event_id] = 16840 WMI_NAN_DMESG_EVENTID; 16841 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 16842 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 16843 event_ids[wmi_roam_pmkid_request_event_id] = 16844 WMI_ROAM_PMKID_REQUEST_EVENTID; 16845 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 16846 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 16847 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 16848 event_ids[wmi_wlan_time_sync_q_master_slave_offset_eventid] = 16849 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 16850 #endif 16851 event_ids[wmi_roam_scan_chan_list_id] = 16852 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 16853 event_ids[wmi_muedca_params_config_eventid] = 16854 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 16855 event_ids[wmi_pdev_sscan_fw_param_eventid] = 16856 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 16857 event_ids[wmi_roam_cap_report_event_id] = 16858 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 16859 event_ids[wmi_vdev_bcn_latency_event_id] = 16860 WMI_VDEV_BCN_LATENCY_EVENTID; 16861 event_ids[wmi_vdev_disconnect_event_id] = 16862 WMI_VDEV_DISCONNECT_EVENTID; 16863 event_ids[wmi_peer_create_conf_event_id] = 16864 WMI_PEER_CREATE_CONF_EVENTID; 16865 event_ids[wmi_pdev_cp_fwstats_eventid] = 16866 WMI_CTRL_PATH_STATS_EVENTID; 16867 event_ids[wmi_vdev_send_big_data_p2_eventid] = 16868 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 16869 event_ids[wmi_pdev_get_dpd_status_event_id] = 16870 WMI_PDEV_GET_DPD_STATUS_EVENTID; 16871 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 16872 event_ids[wmi_vdev_smart_monitor_event_id] = 16873 WMI_VDEV_SMART_MONITOR_EVENTID; 16874 #endif 16875 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 16876 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 16877 event_ids[wmi_pdev_set_halphy_cal_event_id] = 16878 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 16879 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 16880 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 16881 #ifdef WLAN_MGMT_RX_REO_SUPPORT 16882 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 16883 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 16884 #endif 16885 #ifdef WLAN_FEATURE_11BE_MLO 16886 event_ids[wmi_mlo_setup_complete_event_id] = 16887 WMI_MLO_SETUP_COMPLETE_EVENTID; 16888 event_ids[wmi_mlo_teardown_complete_event_id] = 16889 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 16890 #endif 16891 } 16892 16893 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 16894 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 16895 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 16896 { 16897 wmi_service[wmi_service_get_station_in_ll_stats_req] = 16898 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 16899 } 16900 #else 16901 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 16902 { 16903 } 16904 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 16905 #else 16906 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 16907 { 16908 } 16909 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 16910 16911 /** 16912 * populate_tlv_service() - populates wmi services 16913 * 16914 * @param wmi_service: Pointer to hold wmi_service 16915 * Return: None 16916 */ 16917 static void populate_tlv_service(uint32_t *wmi_service) 16918 { 16919 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 16920 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 16921 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 16922 wmi_service[wmi_service_roam_scan_offload] = 16923 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 16924 wmi_service[wmi_service_bcn_miss_offload] = 16925 WMI_SERVICE_BCN_MISS_OFFLOAD; 16926 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 16927 wmi_service[wmi_service_sta_advanced_pwrsave] = 16928 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 16929 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 16930 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 16931 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 16932 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 16933 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 16934 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 16935 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 16936 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 16937 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 16938 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 16939 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 16940 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 16941 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 16942 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 16943 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 16944 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 16945 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 16946 wmi_service[wmi_service_packet_power_save] = 16947 WMI_SERVICE_PACKET_POWER_SAVE; 16948 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 16949 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 16950 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 16951 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 16952 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 16953 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 16954 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 16955 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 16956 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 16957 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 16958 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 16959 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 16960 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 16961 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 16962 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 16963 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 16964 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 16965 wmi_service[wmi_service_mcc_bcn_interval_change] = 16966 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 16967 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 16968 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 16969 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 16970 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 16971 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 16972 wmi_service[wmi_service_lte_ant_share_support] = 16973 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 16974 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 16975 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 16976 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 16977 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 16978 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 16979 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 16980 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 16981 wmi_service[wmi_service_bcn_txrate_override] = 16982 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 16983 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 16984 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 16985 wmi_service[wmi_service_estimate_linkspeed] = 16986 WMI_SERVICE_ESTIMATE_LINKSPEED; 16987 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 16988 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 16989 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 16990 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 16991 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 16992 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 16993 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 16994 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 16995 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 16996 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 16997 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 16998 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 16999 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 17000 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 17001 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 17002 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 17003 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 17004 wmi_service[wmi_service_sap_auth_offload] = 17005 WMI_SERVICE_SAP_AUTH_OFFLOAD; 17006 wmi_service[wmi_service_dual_band_simultaneous_support] = 17007 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 17008 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 17009 wmi_service[wmi_service_ap_arpns_offload] = 17010 WMI_SERVICE_AP_ARPNS_OFFLOAD; 17011 wmi_service[wmi_service_per_band_chainmask_support] = 17012 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 17013 wmi_service[wmi_service_packet_filter_offload] = 17014 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 17015 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 17016 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 17017 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 17018 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 17019 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 17020 wmi_service[wmi_service_multiple_vdev_restart] = 17021 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 17022 wmi_service[wmi_service_smart_antenna_sw_support] = 17023 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 17024 wmi_service[wmi_service_smart_antenna_hw_support] = 17025 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 17026 17027 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 17028 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 17029 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 17030 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 17031 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 17032 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 17033 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 17034 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 17035 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 17036 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 17037 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 17038 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 17039 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 17040 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 17041 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 17042 wmi_service[wmi_service_periodic_chan_stat_support] = 17043 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 17044 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 17045 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 17046 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 17047 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 17048 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 17049 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 17050 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 17051 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 17052 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 17053 wmi_service[wmi_service_unified_wow_capability] = 17054 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 17055 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 17056 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 17057 wmi_service[wmi_service_sync_delete_cmds] = 17058 WMI_SERVICE_SYNC_DELETE_CMDS; 17059 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 17060 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 17061 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 17062 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 17063 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 17064 wmi_service[wmi_service_deprecated_replace] = 17065 WMI_SERVICE_DEPRECATED_REPLACE; 17066 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 17067 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 17068 wmi_service[wmi_service_enhanced_mcast_filter] = 17069 WMI_SERVICE_ENHANCED_MCAST_FILTER; 17070 wmi_service[wmi_service_half_rate_quarter_rate_support] = 17071 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 17072 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 17073 wmi_service[wmi_service_p2p_listen_offload_support] = 17074 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 17075 wmi_service[wmi_service_mark_first_wakeup_packet] = 17076 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 17077 wmi_service[wmi_service_multiple_mcast_filter_set] = 17078 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 17079 wmi_service[wmi_service_host_managed_rx_reorder] = 17080 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 17081 wmi_service[wmi_service_flash_rdwr_support] = 17082 WMI_SERVICE_FLASH_RDWR_SUPPORT; 17083 wmi_service[wmi_service_wlan_stats_report] = 17084 WMI_SERVICE_WLAN_STATS_REPORT; 17085 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 17086 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 17087 wmi_service[wmi_service_dfs_phyerr_offload] = 17088 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 17089 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 17090 wmi_service[wmi_service_fw_mem_dump_support] = 17091 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 17092 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 17093 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 17094 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 17095 wmi_service[wmi_service_hw_data_filtering] = 17096 WMI_SERVICE_HW_DATA_FILTERING; 17097 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 17098 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 17099 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 17100 wmi_service[wmi_service_extended_nss_support] = 17101 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 17102 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 17103 wmi_service[wmi_service_bcn_offload_start_stop_support] = 17104 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 17105 wmi_service[wmi_service_offchan_data_tid_support] = 17106 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 17107 wmi_service[wmi_service_support_dma] = 17108 WMI_SERVICE_SUPPORT_DIRECT_DMA; 17109 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 17110 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 17111 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 17112 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 17113 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 17114 wmi_service[wmi_service_11k_neighbour_report_support] = 17115 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 17116 wmi_service[wmi_service_ap_obss_detection_offload] = 17117 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 17118 wmi_service[wmi_service_bss_color_offload] = 17119 WMI_SERVICE_BSS_COLOR_OFFLOAD; 17120 wmi_service[wmi_service_gmac_offload_support] = 17121 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 17122 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 17123 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 17124 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 17125 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 17126 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 17127 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 17128 wmi_service[wmi_service_listen_interval_offload_support] = 17129 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 17130 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 17131 wmi_service[wmi_service_obss_spatial_reuse] = 17132 WMI_SERVICE_OBSS_SPATIAL_REUSE; 17133 wmi_service[wmi_service_per_vdev_chain_support] = 17134 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 17135 wmi_service[wmi_service_new_htt_msg_format] = 17136 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 17137 wmi_service[wmi_service_peer_unmap_cnf_support] = 17138 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 17139 wmi_service[wmi_service_beacon_reception_stats] = 17140 WMI_SERVICE_BEACON_RECEPTION_STATS; 17141 wmi_service[wmi_service_vdev_latency_config] = 17142 WMI_SERVICE_VDEV_LATENCY_CONFIG; 17143 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 17144 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 17145 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 17146 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 17147 wmi_service[wmi_service_nan_disable_support] = 17148 WMI_SERVICE_NAN_DISABLE_SUPPORT; 17149 wmi_service[wmi_service_sta_plus_sta_support] = 17150 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 17151 wmi_service[wmi_service_hw_db2dbm_support] = 17152 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 17153 wmi_service[wmi_service_wlm_stats_support] = 17154 WMI_SERVICE_WLM_STATS_REQUEST; 17155 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 17156 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 17157 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 17158 wmi_service[wmi_service_cfr_capture_support] = 17159 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 17160 wmi_service[wmi_service_bcast_twt_support] = 17161 WMI_SERVICE_BROADCAST_TWT; 17162 wmi_service[wmi_service_wpa3_ft_sae_support] = 17163 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 17164 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 17165 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 17166 wmi_service[wmi_service_ft_fils] = 17167 WMI_SERVICE_WPA3_FT_FILS; 17168 wmi_service[wmi_service_adaptive_11r_support] = 17169 WMI_SERVICE_ADAPTIVE_11R_ROAM; 17170 wmi_service[wmi_service_tx_compl_tsf64] = 17171 WMI_SERVICE_TX_COMPL_TSF64; 17172 wmi_service[wmi_service_data_stall_recovery_support] = 17173 WMI_SERVICE_DSM_ROAM_FILTER; 17174 wmi_service[wmi_service_vdev_delete_all_peer] = 17175 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 17176 wmi_service[wmi_service_three_way_coex_config_legacy] = 17177 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 17178 wmi_service[wmi_service_rx_fse_support] = 17179 WMI_SERVICE_RX_FSE_SUPPORT; 17180 wmi_service[wmi_service_sae_roam_support] = 17181 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 17182 wmi_service[wmi_service_owe_roam_support] = 17183 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 17184 wmi_service[wmi_service_6ghz_support] = 17185 WMI_SERVICE_6GHZ_SUPPORT; 17186 wmi_service[wmi_service_bw_165mhz_support] = 17187 WMI_SERVICE_BW_165MHZ_SUPPORT; 17188 wmi_service[wmi_service_bw_restricted_80p80_support] = 17189 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 17190 wmi_service[wmi_service_packet_capture_support] = 17191 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 17192 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 17193 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 17194 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 17195 wmi_service[wmi_service_multiple_vdev_restart_ext] = 17196 WMI_SERVICE_UNAVAILABLE; 17197 wmi_service[wmi_service_time_sync_ftm] = 17198 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 17199 wmi_service[wmi_service_nss_ratio_to_host_support] = 17200 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 17201 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 17202 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 17203 wmi_service[wmi_beacon_protection_support] = 17204 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 17205 wmi_service[wmi_service_sta_nan_ndi_four_port] = 17206 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 17207 wmi_service[wmi_service_host_scan_stop_vdev_all] = 17208 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 17209 wmi_service[wmi_support_extend_address] = 17210 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 17211 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 17212 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 17213 wmi_service[wmi_service_suiteb_roam_support] = 17214 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 17215 wmi_service[wmi_service_no_interband_mcc_support] = 17216 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 17217 wmi_service[wmi_service_dual_sta_roam_support] = 17218 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 17219 wmi_service[wmi_service_peer_create_conf] = 17220 WMI_SERVICE_PEER_CREATE_CONF; 17221 wmi_service[wmi_service_configure_roam_trigger_param_support] = 17222 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 17223 wmi_service[wmi_service_5dot9_ghz_support] = 17224 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 17225 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 17226 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 17227 wmi_service[wmi_service_cfr_capture_count_support] = 17228 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 17229 wmi_service[wmi_service_ocv_support] = 17230 WMI_SERVICE_OCV_SUPPORT; 17231 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 17232 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 17233 wmi_service[wmi_service_thermal_multi_client_support] = 17234 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 17235 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 17236 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 17237 wmi_service[wmi_service_fse_cmem_alloc_support] = 17238 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 17239 wmi_service[wmi_service_scan_conf_per_ch_support] = 17240 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 17241 wmi_service[wmi_service_csa_beacon_template] = 17242 WMI_SERVICE_CSA_BEACON_TEMPLATE; 17243 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 17244 wmi_service[wmi_service_igmp_offload_support] = 17245 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 17246 #endif 17247 #ifdef WLAN_FEATURE_11AX 17248 #ifdef FEATURE_WLAN_TDLS 17249 wmi_service[wmi_service_tdls_ax_support] = 17250 WMI_SERVICE_11AX_TDLS_SUPPORT; 17251 #endif 17252 #endif 17253 #ifdef WLAN_SUPPORT_TWT 17254 wmi_service[wmi_service_twt_bcast_req_support] = 17255 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 17256 wmi_service[wmi_service_twt_bcast_resp_support] = 17257 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 17258 wmi_service[wmi_service_twt_nudge] = 17259 WMI_SERVICE_TWT_NUDGE; 17260 wmi_service[wmi_service_all_twt] = 17261 WMI_SERVICE_TWT_ALL_DIALOG_ID; 17262 wmi_service[wmi_service_twt_statistics] = 17263 WMI_SERVICE_TWT_STATS; 17264 #endif 17265 wmi_service[wmi_service_spectral_scan_disabled] = 17266 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 17267 wmi_service[wmi_service_sae_eapol_offload_support] = 17268 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 17269 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 17270 17271 wmi_service[wmi_service_wapi_concurrency_supported] = 17272 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 17273 wmi_service[wmi_service_sap_connected_d3_wow] = 17274 WMI_SERVICE_SAP_CONNECTED_D3WOW; 17275 wmi_service[wmi_service_go_connected_d3_wow] = 17276 WMI_SERVICE_SAP_CONNECTED_D3WOW; 17277 wmi_service[wmi_service_ext_tpc_reg_support] = 17278 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 17279 wmi_service[wmi_service_ndi_txbf_support] = 17280 WMI_SERVICE_NDI_TXBF_SUPPORT; 17281 wmi_service[wmi_service_reg_cc_ext_event_support] = 17282 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 17283 #if defined(CONFIG_BAND_6GHZ) 17284 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 17285 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 17286 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 17287 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 17288 #endif 17289 wmi_service[wmi_service_dcs_awgn_int_support] = 17290 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 17291 wmi_populate_service_11be(wmi_service); 17292 17293 #ifdef WLAN_FEATURE_BIG_DATA_STATS 17294 wmi_service[wmi_service_big_data_support] = 17295 WMI_SERVICE_BIG_DATA_SUPPORT; 17296 #endif 17297 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 17298 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 17299 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 17300 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 17301 wmi_service[wmi_service_halphy_cal_status] = 17302 WMI_SERVICE_HALPHY_CAL_STATUS; 17303 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 17304 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 17305 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 17306 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 17307 wmi_service[wmi_service_ema_multiple_group_supported] = 17308 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 17309 wmi_service[wmi_service_large_beacon_supported] = 17310 WMI_SERVICE_LARGE_BEACON_SUPPORT; 17311 wmi_service[wmi_service_aoa_for_rcc_supported] = 17312 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 17313 #ifdef WLAN_FEATURE_P2P_P2P_STA 17314 wmi_service[wmi_service_p2p_p2p_cc_support] = 17315 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 17316 #endif 17317 #ifdef THERMAL_STATS_SUPPORT 17318 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 17319 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 17320 #endif 17321 wmi_service[wmi_service_hw_mode_policy_offload_support] = 17322 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 17323 } 17324 17325 /** 17326 * wmi_ocb_ut_attach() - Attach OCB test framework 17327 * @wmi_handle: wmi handle 17328 * 17329 * Return: None 17330 */ 17331 #ifdef WLAN_OCB_UT 17332 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 17333 #else 17334 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 17335 { 17336 return; 17337 } 17338 #endif 17339 17340 /** 17341 * wmi_tlv_attach() - Attach TLV APIs 17342 * 17343 * Return: None 17344 */ 17345 void wmi_tlv_attach(wmi_unified_t wmi_handle) 17346 { 17347 wmi_handle->ops = &tlv_ops; 17348 wmi_ocb_ut_attach(wmi_handle); 17349 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 17350 #ifdef WMI_INTERFACE_EVENT_LOGGING 17351 /* Skip saving WMI_CMD_HDR and TLV HDR */ 17352 wmi_handle->soc->buf_offset_command = 8; 17353 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 17354 wmi_handle->soc->buf_offset_event = 4; 17355 #endif 17356 populate_tlv_events_id(wmi_handle->wmi_events); 17357 populate_tlv_service(wmi_handle->services); 17358 wmi_wds_attach_tlv(wmi_handle); 17359 wmi_twt_attach_tlv(wmi_handle); 17360 wmi_extscan_attach_tlv(wmi_handle); 17361 wmi_smart_ant_attach_tlv(wmi_handle); 17362 wmi_dbr_attach_tlv(wmi_handle); 17363 wmi_atf_attach_tlv(wmi_handle); 17364 wmi_ap_attach_tlv(wmi_handle); 17365 wmi_bcn_attach_tlv(wmi_handle); 17366 wmi_ocb_attach_tlv(wmi_handle); 17367 wmi_nan_attach_tlv(wmi_handle); 17368 wmi_p2p_attach_tlv(wmi_handle); 17369 wmi_interop_issues_ap_attach_tlv(wmi_handle); 17370 wmi_dcs_attach_tlv(wmi_handle); 17371 wmi_roam_attach_tlv(wmi_handle); 17372 wmi_concurrency_attach_tlv(wmi_handle); 17373 wmi_pmo_attach_tlv(wmi_handle); 17374 wmi_sta_attach_tlv(wmi_handle); 17375 wmi_11ax_bss_color_attach_tlv(wmi_handle); 17376 wmi_fwol_attach_tlv(wmi_handle); 17377 wmi_vdev_attach_tlv(wmi_handle); 17378 wmi_cfr_attach_tlv(wmi_handle); 17379 wmi_cp_stats_attach_tlv(wmi_handle); 17380 wmi_gpio_attach_tlv(wmi_handle); 17381 wmi_11be_attach_tlv(wmi_handle); 17382 } 17383 qdf_export_symbol(wmi_tlv_attach); 17384 17385 /** 17386 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 17387 * 17388 * Return: None 17389 */ 17390 void wmi_tlv_init(void) 17391 { 17392 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 17393 } 17394