1 /* 2 * Copyright (c) 2016-2020 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 44 #ifdef WLAN_POLICY_MGR_ENABLE 45 #include "wlan_policy_mgr_public_struct.h" 46 #endif 47 48 #ifdef WMI_SMART_ANT_SUPPORT 49 #include "wmi_unified_smart_ant_api.h" 50 #endif 51 52 #ifdef WMI_DBR_SUPPORT 53 #include "wmi_unified_dbr_api.h" 54 #endif 55 56 #ifdef WMI_ATF_SUPPORT 57 #include "wmi_unified_atf_api.h" 58 #endif 59 60 #ifdef WMI_AP_SUPPORT 61 #include "wmi_unified_ap_api.h" 62 #endif 63 64 #include <wmi_unified_vdev_api.h> 65 #include <wmi_unified_vdev_tlv.h> 66 67 /* HTC service ids for WMI for multi-radio */ 68 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 69 WMI_CONTROL_SVC_WMAC1, 70 WMI_CONTROL_SVC_WMAC2}; 71 72 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 73 /*Populate peer_param array whose index as host id and 74 *value as target id 75 */ 76 static const uint32_t peer_param_tlv[] = { 77 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 78 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 79 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 80 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 81 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 82 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 83 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 84 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 85 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 86 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 87 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 88 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 89 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 90 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 91 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 92 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 93 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 94 [WMI_HOST_PEER_SET_MU_WHITELIST] = WMI_PEER_SET_MU_WHITELIST, 95 [WMI_HOST_PEER_SET_MAC_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 96 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 97 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 98 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 99 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 100 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 101 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 102 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 103 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 104 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 105 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 106 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 107 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 108 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 109 }; 110 111 /** 112 * Populate pdev_param_value whose index is host param and value is target 113 * param 114 */ 115 static const uint32_t pdev_param_tlv[] = { 116 [wmi_pdev_param_tx_chain_mask] = WMI_PDEV_PARAM_TX_CHAIN_MASK, 117 [wmi_pdev_param_rx_chain_mask] = WMI_PDEV_PARAM_RX_CHAIN_MASK, 118 [wmi_pdev_param_txpower_limit2g] = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, 119 [wmi_pdev_param_txpower_limit5g] = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, 120 [wmi_pdev_param_txpower_scale] = WMI_PDEV_PARAM_TXPOWER_SCALE, 121 [wmi_pdev_param_beacon_gen_mode] = WMI_PDEV_PARAM_BEACON_GEN_MODE, 122 [wmi_pdev_param_beacon_tx_mode] = WMI_PDEV_PARAM_BEACON_TX_MODE, 123 [wmi_pdev_param_resmgr_offchan_mode] = 124 WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, 125 [wmi_pdev_param_protection_mode] = WMI_PDEV_PARAM_PROTECTION_MODE, 126 [wmi_pdev_param_dynamic_bw] = WMI_PDEV_PARAM_DYNAMIC_BW, 127 [wmi_pdev_param_non_agg_sw_retry_th] = 128 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 129 [wmi_pdev_param_agg_sw_retry_th] = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, 130 [wmi_pdev_param_sta_kickout_th] = WMI_PDEV_PARAM_STA_KICKOUT_TH, 131 [wmi_pdev_param_ac_aggrsize_scaling] = 132 WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, 133 [wmi_pdev_param_ltr_enable] = WMI_PDEV_PARAM_LTR_ENABLE, 134 [wmi_pdev_param_ltr_ac_latency_be] = 135 WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, 136 [wmi_pdev_param_ltr_ac_latency_bk] = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, 137 [wmi_pdev_param_ltr_ac_latency_vi] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, 138 [wmi_pdev_param_ltr_ac_latency_vo] = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, 139 [wmi_pdev_param_ltr_ac_latency_timeout] = 140 WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, 141 [wmi_pdev_param_ltr_sleep_override] = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, 142 [wmi_pdev_param_ltr_rx_override] = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, 143 [wmi_pdev_param_ltr_tx_activity_timeout] = 144 WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, 145 [wmi_pdev_param_l1ss_enable] = WMI_PDEV_PARAM_L1SS_ENABLE, 146 [wmi_pdev_param_dsleep_enable] = WMI_PDEV_PARAM_DSLEEP_ENABLE, 147 [wmi_pdev_param_pcielp_txbuf_flush] = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, 148 [wmi_pdev_param_pcielp_txbuf_watermark] = 149 WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, 150 [wmi_pdev_param_pcielp_txbuf_tmo_en] = 151 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, 152 [wmi_pdev_param_pcielp_txbuf_tmo_value] = 153 WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, 154 [wmi_pdev_param_pdev_stats_update_period] = 155 WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, 156 [wmi_pdev_param_vdev_stats_update_period] = 157 WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, 158 [wmi_pdev_param_peer_stats_update_period] = 159 WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, 160 [wmi_pdev_param_bcnflt_stats_update_period] = 161 WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 162 [wmi_pdev_param_pmf_qos] = WMI_PDEV_PARAM_PMF_QOS, 163 [wmi_pdev_param_arp_ac_override] = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 164 [wmi_pdev_param_dcs] = WMI_PDEV_PARAM_DCS, 165 [wmi_pdev_param_ani_enable] = WMI_PDEV_PARAM_ANI_ENABLE, 166 [wmi_pdev_param_ani_poll_period] = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 167 [wmi_pdev_param_ani_listen_period] = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, 168 [wmi_pdev_param_ani_ofdm_level] = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, 169 [wmi_pdev_param_ani_cck_level] = WMI_PDEV_PARAM_ANI_CCK_LEVEL, 170 [wmi_pdev_param_dyntxchain] = WMI_PDEV_PARAM_DYNTXCHAIN, 171 [wmi_pdev_param_proxy_sta] = WMI_PDEV_PARAM_PROXY_STA, 172 [wmi_pdev_param_idle_ps_config] = WMI_PDEV_PARAM_IDLE_PS_CONFIG, 173 [wmi_pdev_param_power_gating_sleep] = WMI_PDEV_PARAM_POWER_GATING_SLEEP, 174 [wmi_pdev_param_rfkill_enable] = WMI_PDEV_PARAM_RFKILL_ENABLE, 175 [wmi_pdev_param_burst_dur] = WMI_PDEV_PARAM_BURST_DUR, 176 [wmi_pdev_param_burst_enable] = WMI_PDEV_PARAM_BURST_ENABLE, 177 [wmi_pdev_param_hw_rfkill_config] = WMI_PDEV_PARAM_HW_RFKILL_CONFIG, 178 [wmi_pdev_param_low_power_rf_enable] = 179 WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, 180 [wmi_pdev_param_l1ss_track] = WMI_PDEV_PARAM_L1SS_TRACK, 181 [wmi_pdev_param_hyst_en] = WMI_PDEV_PARAM_HYST_EN, 182 [wmi_pdev_param_power_collapse_enable] = 183 WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, 184 [wmi_pdev_param_led_sys_state] = WMI_PDEV_PARAM_LED_SYS_STATE, 185 [wmi_pdev_param_led_enable] = WMI_PDEV_PARAM_LED_ENABLE, 186 [wmi_pdev_param_audio_over_wlan_latency] = 187 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, 188 [wmi_pdev_param_audio_over_wlan_enable] = 189 WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, 190 [wmi_pdev_param_whal_mib_stats_update_enable] = 191 WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, 192 [wmi_pdev_param_vdev_rate_stats_update_period] = 193 WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, 194 [wmi_pdev_param_cts_cbw] = WMI_PDEV_PARAM_CTS_CBW, 195 [wmi_pdev_param_wnts_config] = WMI_PDEV_PARAM_WNTS_CONFIG, 196 [wmi_pdev_param_adaptive_early_rx_enable] = 197 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, 198 [wmi_pdev_param_adaptive_early_rx_min_sleep_slop] = 199 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, 200 [wmi_pdev_param_adaptive_early_rx_inc_dec_step] = 201 WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, 202 [wmi_pdev_param_early_rx_fix_sleep_slop] = 203 WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, 204 [wmi_pdev_param_bmiss_based_adaptive_bto_enable] = 205 WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, 206 [wmi_pdev_param_bmiss_bto_min_bcn_timeout] = 207 WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, 208 [wmi_pdev_param_bmiss_bto_inc_dec_step] = 209 WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, 210 [wmi_pdev_param_bto_fix_bcn_timeout] = 211 WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, 212 [wmi_pdev_param_ce_based_adaptive_bto_enable] = 213 WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, 214 [wmi_pdev_param_ce_bto_combo_ce_value] = 215 WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, 216 [wmi_pdev_param_tx_chain_mask_2g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_2G, 217 [wmi_pdev_param_rx_chain_mask_2g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_2G, 218 [wmi_pdev_param_tx_chain_mask_5g] = WMI_PDEV_PARAM_TX_CHAIN_MASK_5G, 219 [wmi_pdev_param_rx_chain_mask_5g] = WMI_PDEV_PARAM_RX_CHAIN_MASK_5G, 220 [wmi_pdev_param_tx_chain_mask_cck] = WMI_PDEV_PARAM_TX_CHAIN_MASK_CCK, 221 [wmi_pdev_param_tx_chain_mask_1ss] = WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, 222 [wmi_pdev_param_rx_filter] = WMI_PDEV_PARAM_RX_FILTER, 223 [wmi_pdev_set_mcast_to_ucast_tid] = WMI_PDEV_SET_MCAST_TO_UCAST_TID, 224 [wmi_pdev_param_mgmt_retry_limit] = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT, 225 [wmi_pdev_param_aggr_burst] = WMI_PDEV_PARAM_AGGR_BURST, 226 [wmi_pdev_peer_sta_ps_statechg_enable] = 227 WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE, 228 [wmi_pdev_param_proxy_sta_mode] = WMI_PDEV_PARAM_PROXY_STA_MODE, 229 [wmi_pdev_param_mu_group_policy] = WMI_PDEV_PARAM_MU_GROUP_POLICY, 230 [wmi_pdev_param_noise_detection] = WMI_PDEV_PARAM_NOISE_DETECTION, 231 [wmi_pdev_param_noise_threshold] = WMI_PDEV_PARAM_NOISE_THRESHOLD, 232 [wmi_pdev_param_dpd_enable] = WMI_PDEV_PARAM_DPD_ENABLE, 233 [wmi_pdev_param_set_mcast_bcast_echo] = 234 WMI_PDEV_PARAM_SET_MCAST_BCAST_ECHO, 235 [wmi_pdev_param_atf_strict_sch] = WMI_PDEV_PARAM_ATF_STRICT_SCH, 236 [wmi_pdev_param_atf_sched_duration] = WMI_PDEV_PARAM_ATF_SCHED_DURATION, 237 [wmi_pdev_param_ant_plzn] = WMI_PDEV_PARAM_ANT_PLZN, 238 [wmi_pdev_param_sensitivity_level] = WMI_PDEV_PARAM_SENSITIVITY_LEVEL, 239 [wmi_pdev_param_signed_txpower_2g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_2G, 240 [wmi_pdev_param_signed_txpower_5g] = WMI_PDEV_PARAM_SIGNED_TXPOWER_5G, 241 [wmi_pdev_param_enable_per_tid_amsdu] = 242 WMI_PDEV_PARAM_ENABLE_PER_TID_AMSDU, 243 [wmi_pdev_param_enable_per_tid_ampdu] = 244 WMI_PDEV_PARAM_ENABLE_PER_TID_AMPDU, 245 [wmi_pdev_param_cca_threshold] = WMI_PDEV_PARAM_CCA_THRESHOLD, 246 [wmi_pdev_param_rts_fixed_rate] = WMI_PDEV_PARAM_RTS_FIXED_RATE, 247 [wmi_pdev_param_cal_period] = WMI_UNAVAILABLE_PARAM, 248 [wmi_pdev_param_pdev_reset] = WMI_PDEV_PARAM_PDEV_RESET, 249 [wmi_pdev_param_wapi_mbssid_offset] = WMI_PDEV_PARAM_WAPI_MBSSID_OFFSET, 250 [wmi_pdev_param_arp_srcaddr] = WMI_PDEV_PARAM_ARP_DBG_SRCADDR, 251 [wmi_pdev_param_arp_dstaddr] = WMI_PDEV_PARAM_ARP_DBG_DSTADDR, 252 [wmi_pdev_param_txpower_decr_db] = WMI_PDEV_PARAM_TXPOWER_DECR_DB, 253 [wmi_pdev_param_rx_batchmode] = WMI_UNAVAILABLE_PARAM, 254 [wmi_pdev_param_packet_aggr_delay] = WMI_UNAVAILABLE_PARAM, 255 [wmi_pdev_param_atf_obss_noise_sch] = 256 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCH, 257 [wmi_pdev_param_atf_obss_noise_scaling_factor] = 258 WMI_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR, 259 [wmi_pdev_param_cust_txpower_scale] = WMI_PDEV_PARAM_CUST_TXPOWER_SCALE, 260 [wmi_pdev_param_atf_dynamic_enable] = WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE, 261 [wmi_pdev_param_atf_ssid_group_policy] = WMI_UNAVAILABLE_PARAM, 262 [wmi_pdev_param_igmpmld_override] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 263 [wmi_pdev_param_igmpmld_tid] = WMI_PDEV_PARAM_IGMPMLD_AC_OVERRIDE, 264 [wmi_pdev_param_antenna_gain] = WMI_PDEV_PARAM_ANTENNA_GAIN, 265 [wmi_pdev_param_block_interbss] = WMI_PDEV_PARAM_BLOCK_INTERBSS, 266 [wmi_pdev_param_set_disable_reset_cmdid] = 267 WMI_PDEV_PARAM_SET_DISABLE_RESET_CMDID, 268 [wmi_pdev_param_set_msdu_ttl_cmdid] = WMI_PDEV_PARAM_SET_MSDU_TTL_CMDID, 269 [wmi_pdev_param_txbf_sound_period_cmdid] = 270 WMI_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID, 271 [wmi_pdev_param_set_burst_mode_cmdid] = 272 WMI_PDEV_PARAM_SET_BURST_MODE_CMDID, 273 [wmi_pdev_param_en_stats] = WMI_PDEV_PARAM_EN_STATS, 274 [wmi_pdev_param_mesh_mcast_enable] = WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 275 [wmi_pdev_param_set_promisc_mode_cmdid] = 276 WMI_PDEV_PARAM_SET_PROMISC_MODE_CMDID, 277 [wmi_pdev_param_set_ppdu_duration_cmdid] = 278 WMI_PDEV_PARAM_SET_PPDU_DURATION_CMDID, 279 [wmi_pdev_param_remove_mcast2ucast_buffer] = 280 WMI_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 281 [wmi_pdev_param_set_mcast2ucast_buffer] = 282 WMI_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 283 [wmi_pdev_param_set_mcast2ucast_mode] = 284 WMI_PDEV_PARAM_SET_MCAST2UCAST_MODE, 285 [wmi_pdev_param_smart_antenna_default_antenna] = 286 WMI_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, 287 [wmi_pdev_param_fast_channel_reset] = 288 WMI_PDEV_PARAM_FAST_CHANNEL_RESET, 289 [wmi_pdev_param_rx_decap_mode] = WMI_PDEV_PARAM_RX_DECAP_MODE, 290 [wmi_pdev_param_tx_ack_timeout] = WMI_PDEV_PARAM_ACK_TIMEOUT, 291 [wmi_pdev_param_cck_tx_enable] = WMI_PDEV_PARAM_CCK_TX_ENABLE, 292 [wmi_pdev_param_antenna_gain_half_db] = 293 WMI_PDEV_PARAM_ANTENNA_GAIN_HALF_DB, 294 [wmi_pdev_param_esp_indication_period] = 295 WMI_PDEV_PARAM_ESP_INDICATION_PERIOD, 296 [wmi_pdev_param_esp_ba_window] = WMI_PDEV_PARAM_ESP_BA_WINDOW, 297 [wmi_pdev_param_esp_airtime_fraction] = 298 WMI_PDEV_PARAM_ESP_AIRTIME_FRACTION, 299 [wmi_pdev_param_esp_ppdu_duration] = WMI_PDEV_PARAM_ESP_PPDU_DURATION, 300 [wmi_pdev_param_ru26_allowed] = WMI_PDEV_PARAM_UL_RU26_ALLOWED, 301 [wmi_pdev_param_use_nol] = WMI_PDEV_PARAM_USE_NOL, 302 /* Trigger interval for all trigger types. */ 303 [wmi_pdev_param_ul_trig_int] = WMI_PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL, 304 [wmi_pdev_param_sub_channel_marking] = 305 WMI_PDEV_PARAM_SUB_CHANNEL_MARKING, 306 [wmi_pdev_param_ul_ppdu_duration] = WMI_PDEV_PARAM_SET_UL_PPDU_DURATION, 307 [wmi_pdev_param_equal_ru_allocation_enable] = 308 WMI_PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE, 309 [wmi_pdev_param_per_peer_prd_cfr_enable] = 310 WMI_PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE, 311 [wmi_pdev_param_nav_override_config] = 312 WMI_PDEV_PARAM_NAV_OVERRIDE_CONFIG, 313 [wmi_pdev_param_set_mgmt_ttl] = WMI_PDEV_PARAM_SET_MGMT_TTL, 314 [wmi_pdev_param_set_prb_rsp_ttl] = 315 WMI_PDEV_PARAM_SET_PROBE_RESP_TTL, 316 [wmi_pdev_param_set_mu_ppdu_duration] = 317 WMI_PDEV_PARAM_SET_MU_PPDU_DURATION, 318 [wmi_pdev_param_set_tbtt_ctrl] = 319 WMI_PDEV_PARAM_SET_TBTT_CTRL, 320 [wmi_pdev_param_set_cmd_obss_pd_threshold] = 321 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 322 [wmi_pdev_param_set_cmd_obss_pd_per_ac] = 323 WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 324 [wmi_pdev_param_set_cong_ctrl_max_msdus] = 325 WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS, 326 [wmi_pdev_param_enable_fw_dynamic_he_edca] = 327 WMI_PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA, 328 [wmi_pdev_param_enable_srp] = WMI_PDEV_PARAM_ENABLE_SRP, 329 [wmi_pdev_param_enable_sr_prohibit] = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT, 330 }; 331 332 /** 333 * Populate vdev_param_value_tlv array whose index is host param 334 * and value is target param 335 */ 336 static const uint32_t vdev_param_tlv[] = { 337 [wmi_vdev_param_rts_threshold] = WMI_VDEV_PARAM_RTS_THRESHOLD, 338 [wmi_vdev_param_fragmentation_threshold] = 339 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, 340 [wmi_vdev_param_beacon_interval] = WMI_VDEV_PARAM_BEACON_INTERVAL, 341 [wmi_vdev_param_listen_interval] = WMI_VDEV_PARAM_LISTEN_INTERVAL, 342 [wmi_vdev_param_multicast_rate] = WMI_VDEV_PARAM_MULTICAST_RATE, 343 [wmi_vdev_param_mgmt_tx_rate] = WMI_VDEV_PARAM_MGMT_TX_RATE, 344 [wmi_vdev_param_slot_time] = WMI_VDEV_PARAM_SLOT_TIME, 345 [wmi_vdev_param_preamble] = WMI_VDEV_PARAM_PREAMBLE, 346 [wmi_vdev_param_swba_time] = WMI_VDEV_PARAM_SWBA_TIME, 347 [wmi_vdev_stats_update_period] = WMI_VDEV_STATS_UPDATE_PERIOD, 348 [wmi_vdev_pwrsave_ageout_time] = WMI_VDEV_PWRSAVE_AGEOUT_TIME, 349 [wmi_vdev_host_swba_interval] = WMI_VDEV_HOST_SWBA_INTERVAL, 350 [wmi_vdev_param_dtim_period] = WMI_VDEV_PARAM_DTIM_PERIOD, 351 [wmi_vdev_oc_scheduler_air_time_limit] = 352 WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, 353 [wmi_vdev_param_wds] = WMI_VDEV_PARAM_WDS, 354 [wmi_vdev_param_atim_window] = WMI_VDEV_PARAM_ATIM_WINDOW, 355 [wmi_vdev_param_bmiss_count_max] = WMI_VDEV_PARAM_BMISS_COUNT_MAX, 356 [wmi_vdev_param_bmiss_first_bcnt] = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, 357 [wmi_vdev_param_bmiss_final_bcnt] = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, 358 [wmi_vdev_param_feature_wmm] = WMI_VDEV_PARAM_FEATURE_WMM, 359 [wmi_vdev_param_chwidth] = WMI_VDEV_PARAM_CHWIDTH, 360 [wmi_vdev_param_chextoffset] = WMI_VDEV_PARAM_CHEXTOFFSET, 361 [wmi_vdev_param_disable_htprotection] = 362 WMI_VDEV_PARAM_DISABLE_HTPROTECTION, 363 [wmi_vdev_param_sta_quickkickout] = WMI_VDEV_PARAM_STA_QUICKKICKOUT, 364 [wmi_vdev_param_mgmt_rate] = WMI_VDEV_PARAM_MGMT_RATE, 365 [wmi_vdev_param_protection_mode] = WMI_VDEV_PARAM_PROTECTION_MODE, 366 [wmi_vdev_param_fixed_rate] = WMI_VDEV_PARAM_FIXED_RATE, 367 [wmi_vdev_param_sgi] = WMI_VDEV_PARAM_SGI, 368 [wmi_vdev_param_ldpc] = WMI_VDEV_PARAM_LDPC, 369 [wmi_vdev_param_tx_stbc] = WMI_VDEV_PARAM_TX_STBC, 370 [wmi_vdev_param_rx_stbc] = WMI_VDEV_PARAM_RX_STBC, 371 [wmi_vdev_param_intra_bss_fwd] = WMI_VDEV_PARAM_INTRA_BSS_FWD, 372 [wmi_vdev_param_def_keyid] = WMI_VDEV_PARAM_DEF_KEYID, 373 [wmi_vdev_param_nss] = WMI_VDEV_PARAM_NSS, 374 [wmi_vdev_param_bcast_data_rate] = WMI_VDEV_PARAM_BCAST_DATA_RATE, 375 [wmi_vdev_param_mcast_data_rate] = WMI_VDEV_PARAM_MCAST_DATA_RATE, 376 [wmi_vdev_param_mcast_indicate] = WMI_VDEV_PARAM_MCAST_INDICATE, 377 [wmi_vdev_param_dhcp_indicate] = WMI_VDEV_PARAM_DHCP_INDICATE, 378 [wmi_vdev_param_unknown_dest_indicate] = 379 WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, 380 [wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs] = 381 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, 382 [wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs] = 383 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, 384 [wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs] = 385 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, 386 [wmi_vdev_param_ap_enable_nawds] = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, 387 [wmi_vdev_param_enable_rtscts] = WMI_VDEV_PARAM_ENABLE_RTSCTS, 388 [wmi_vdev_param_txbf] = WMI_VDEV_PARAM_TXBF, 389 [wmi_vdev_param_packet_powersave] = WMI_VDEV_PARAM_PACKET_POWERSAVE, 390 [wmi_vdev_param_drop_unencry] = WMI_VDEV_PARAM_DROP_UNENCRY, 391 [wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE, 392 [wmi_vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs] = 393 WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 394 [wmi_vdev_param_early_rx_adjust_enable] = 395 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, 396 [wmi_vdev_param_early_rx_tgt_bmiss_num] = 397 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, 398 [wmi_vdev_param_early_rx_bmiss_sample_cycle] = 399 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, 400 [wmi_vdev_param_early_rx_slop_step] = WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, 401 [wmi_vdev_param_early_rx_init_slop] = WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, 402 [wmi_vdev_param_early_rx_adjust_pause] = 403 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, 404 [wmi_vdev_param_tx_pwrlimit] = WMI_VDEV_PARAM_TX_PWRLIMIT, 405 [wmi_vdev_param_snr_num_for_cal] = WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, 406 [wmi_vdev_param_roam_fw_offload] = WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 407 [wmi_vdev_param_enable_rmc] = WMI_VDEV_PARAM_ENABLE_RMC, 408 [wmi_vdev_param_ibss_max_bcn_lost_ms] = 409 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, 410 [wmi_vdev_param_max_rate] = WMI_VDEV_PARAM_MAX_RATE, 411 [wmi_vdev_param_early_rx_drift_sample] = 412 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, 413 [wmi_vdev_param_set_ibss_tx_fail_cnt_thr] = 414 WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, 415 [wmi_vdev_param_ebt_resync_timeout] = 416 WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, 417 [wmi_vdev_param_aggr_trig_event_enable] = 418 WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, 419 [wmi_vdev_param_is_ibss_power_save_allowed] = 420 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, 421 [wmi_vdev_param_is_power_collapse_allowed] = 422 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, 423 [wmi_vdev_param_is_awake_on_txrx_enabled] = 424 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, 425 [wmi_vdev_param_inactivity_cnt] = WMI_VDEV_PARAM_INACTIVITY_CNT, 426 [wmi_vdev_param_txsp_end_inactivity_time_ms] = 427 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, 428 [wmi_vdev_param_dtim_policy] = WMI_VDEV_PARAM_DTIM_POLICY, 429 [wmi_vdev_param_ibss_ps_warmup_time_secs] = 430 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, 431 [wmi_vdev_param_ibss_ps_1rx_chain_in_atim_window_enable] = 432 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, 433 [wmi_vdev_param_rx_leak_window] = WMI_VDEV_PARAM_RX_LEAK_WINDOW, 434 [wmi_vdev_param_stats_avg_factor] = 435 WMI_VDEV_PARAM_STATS_AVG_FACTOR, 436 [wmi_vdev_param_disconnect_th] = WMI_VDEV_PARAM_DISCONNECT_TH, 437 [wmi_vdev_param_rtscts_rate] = WMI_VDEV_PARAM_RTSCTS_RATE, 438 [wmi_vdev_param_mcc_rtscts_protection_enable] = 439 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, 440 [wmi_vdev_param_mcc_broadcast_probe_enable] = 441 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, 442 [wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER, 443 [wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE, 444 [wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE, 445 [wmi_vdev_param_he_dcm_enable] = WMI_VDEV_PARAM_HE_DCM, 446 [wmi_vdev_param_he_range_ext_enable] = WMI_VDEV_PARAM_HE_RANGE_EXT, 447 [wmi_vdev_param_he_bss_color] = WMI_VDEV_PARAM_BSS_COLOR, 448 [wmi_vdev_param_set_hemu_mode] = WMI_VDEV_PARAM_SET_HEMU_MODE, 449 [wmi_vdev_param_set_he_sounding_mode] = 450 WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE, 451 [wmi_vdev_param_set_heop] = WMI_VDEV_PARAM_HEOPS_0_31, 452 [wmi_vdev_param_sensor_ap] = WMI_VDEV_PARAM_SENSOR_AP, 453 [wmi_vdev_param_dtim_enable_cts] = WMI_VDEV_PARAM_DTIM_ENABLE_CTS, 454 [wmi_vdev_param_atf_ssid_sched_policy] = 455 WMI_VDEV_PARAM_ATF_SSID_SCHED_POLICY, 456 [wmi_vdev_param_disable_dyn_bw_rts] = WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS, 457 [wmi_vdev_param_mcast2ucast_set] = WMI_VDEV_PARAM_MCAST2UCAST_SET, 458 [wmi_vdev_param_rc_num_retries] = WMI_VDEV_PARAM_RC_NUM_RETRIES, 459 [wmi_vdev_param_cabq_maxdur] = WMI_VDEV_PARAM_CABQ_MAXDUR, 460 [wmi_vdev_param_mfptest_set] = WMI_VDEV_PARAM_MFPTEST_SET, 461 [wmi_vdev_param_rts_fixed_rate] = WMI_VDEV_PARAM_RTS_FIXED_RATE, 462 [wmi_vdev_param_vht_sgimask] = WMI_VDEV_PARAM_VHT_SGIMASK, 463 [wmi_vdev_param_vht80_ratemask] = WMI_VDEV_PARAM_VHT80_RATEMASK, 464 [wmi_vdev_param_proxy_sta] = WMI_VDEV_PARAM_PROXY_STA, 465 [wmi_vdev_param_bw_nss_ratemask] = WMI_VDEV_PARAM_BW_NSS_RATEMASK, 466 [wmi_vdev_param_set_he_ltf] = WMI_VDEV_PARAM_HE_LTF, 467 [wmi_vdev_param_disable_cabq] = WMI_VDEV_PARAM_DISABLE_CABQ, 468 [wmi_vdev_param_rate_dropdown_bmap] = WMI_VDEV_PARAM_RATE_DROPDOWN_BMAP, 469 [wmi_vdev_param_set_ba_mode] = WMI_VDEV_PARAM_BA_MODE, 470 [wmi_vdev_param_capabilities] = WMI_VDEV_PARAM_CAPABILITIES, 471 [wmi_vdev_param_autorate_misc_cfg] = WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 472 [wmi_vdev_param_ul_shortgi] = WMI_VDEV_PARAM_UL_GI, 473 [wmi_vdev_param_ul_he_ltf] = WMI_VDEV_PARAM_UL_HE_LTF, 474 [wmi_vdev_param_ul_nss] = WMI_VDEV_PARAM_UL_NSS, 475 [wmi_vdev_param_ul_ppdu_bw] = WMI_VDEV_PARAM_UL_PPDU_BW, 476 [wmi_vdev_param_ul_ldpc] = WMI_VDEV_PARAM_UL_LDPC, 477 [wmi_vdev_param_ul_stbc] = WMI_VDEV_PARAM_UL_STBC, 478 [wmi_vdev_param_ul_fixed_rate] = WMI_VDEV_PARAM_UL_FIXED_RATE, 479 [wmi_vdev_param_rawmode_open_war] = WMI_VDEV_PARAM_RAW_IS_ENCRYPTED, 480 [wmi_vdev_param_max_mtu_size] = WMI_VDEV_PARAM_MAX_MTU_SIZE, 481 [wmi_vdev_param_mcast_rc_stale_period] = 482 WMI_VDEV_PARAM_MCAST_RC_STALE_PERIOD, 483 [wmi_vdev_param_enable_multi_group_key] = 484 WMI_VDEV_PARAM_ENABLE_MULTI_GROUP_KEY, 485 [wmi_vdev_param_max_group_keys] = WMI_VDEV_PARAM_NUM_GROUP_KEYS, 486 [wmi_vdev_param_enable_mcast_rc] = WMI_VDEV_PARAM_ENABLE_MCAST_RC, 487 [wmi_vdev_param_6ghz_params] = WMI_VDEV_PARAM_6GHZ_PARAMS, 488 [wmi_vdev_param_enable_disable_roam_reason_vsie] = 489 WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, 490 [wmi_vdev_param_set_cmd_obss_pd_threshold] = 491 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD, 492 [wmi_vdev_param_set_cmd_obss_pd_per_ac] = 493 WMI_VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC, 494 [wmi_vdev_param_enable_srp] = WMI_VDEV_PARAM_ENABLE_SRP, 495 }; 496 #endif 497 498 /** 499 * Populate the pktlog event tlv array, where 500 * the values are the FW WMI events, which host 501 * uses to communicate with FW for pktlog 502 */ 503 504 static const uint32_t pktlog_event_tlv[] = { 505 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 506 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 507 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 508 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 509 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 510 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 511 WMI_PKTLOG_EVENT_SMART_ANTENNA, 512 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 513 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 514 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 515 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 516 }; 517 518 /** 519 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 520 * host to target defines. 521 * @wmi_handle: pointer to wmi_handle 522 * @param pdev_id: host pdev_id to be converted. 523 * Return: target pdev_id after conversion. 524 */ 525 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 526 uint32_t pdev_id) 527 { 528 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 529 if (!wmi_handle->soc->is_pdev_is_map_enable) { 530 switch (pdev_id) { 531 case WMI_HOST_PDEV_ID_0: 532 return WMI_PDEV_ID_1ST; 533 case WMI_HOST_PDEV_ID_1: 534 return WMI_PDEV_ID_2ND; 535 case WMI_HOST_PDEV_ID_2: 536 return WMI_PDEV_ID_3RD; 537 } 538 } else { 539 return wmi_handle->cmd_pdev_id_map[pdev_id]; 540 } 541 } else { 542 return WMI_PDEV_ID_SOC; 543 } 544 545 QDF_ASSERT(0); 546 547 return WMI_PDEV_ID_SOC; 548 } 549 550 /** 551 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 552 * target to host defines. 553 * @wmi_handle: pointer to wmi_handle 554 * @param pdev_id: target pdev_id to be converted. 555 * Return: host pdev_id after conversion. 556 */ 557 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 558 uint32_t pdev_id) 559 { 560 561 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 562 if (!wmi_handle->soc->is_pdev_is_map_enable) { 563 switch (pdev_id) { 564 case WMI_PDEV_ID_1ST: 565 return WMI_HOST_PDEV_ID_0; 566 case WMI_PDEV_ID_2ND: 567 return WMI_HOST_PDEV_ID_1; 568 case WMI_PDEV_ID_3RD: 569 return WMI_HOST_PDEV_ID_2; 570 } 571 } else { 572 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 573 } 574 } else if (pdev_id == WMI_PDEV_ID_SOC) { 575 return WMI_HOST_PDEV_ID_SOC; 576 } else { 577 WMI_LOGE("Invalid pdev_id"); 578 } 579 580 return WMI_HOST_PDEV_ID_INVALID; 581 } 582 583 /** 584 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 585 * host to target defines. 586 * @wmi_handle: pointer to wmi_handle 587 * @param phy_id: host pdev_id to be converted. 588 * Return: target phy_id after conversion. 589 */ 590 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 591 uint32_t phy_id) 592 { 593 if (!wmi_handle->soc->is_phy_id_map_enable || 594 phy_id >= WMI_MAX_RADIOS) { 595 return phy_id; 596 } 597 598 return wmi_handle->cmd_phy_id_map[phy_id]; 599 } 600 601 /** 602 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 603 * target to host defines. 604 * @wmi_handle: pointer to wmi_handle 605 * @param phy_id: target phy_id to be converted. 606 * Return: host phy_id after conversion. 607 */ 608 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 609 uint32_t phy_id) 610 { 611 if (!wmi_handle->soc->is_phy_id_map_enable || 612 phy_id >= WMI_MAX_RADIOS) { 613 return phy_id; 614 } 615 616 return wmi_handle->evt_phy_id_map[phy_id]; 617 } 618 619 /** 620 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 621 * 622 * Return None. 623 */ 624 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 625 uint32_t *pdev_id_map, 626 uint8_t size) 627 { 628 int i = 0; 629 630 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 631 for (i = 0; i < size; i++) { 632 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 633 wmi_handle->evt_pdev_id_map[i] = 634 WMI_HOST_PDEV_ID_INVALID; 635 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 636 wmi_handle->evt_phy_id_map[i] = 637 WMI_HOST_PDEV_ID_INVALID; 638 } 639 640 for (i = 0; i < size; i++) { 641 if (wmi_handle->cmd_pdev_id_map[i] != 642 WMI_HOST_PDEV_ID_INVALID) { 643 wmi_handle->evt_pdev_id_map 644 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 645 } 646 if (wmi_handle->cmd_phy_id_map[i] != 647 WMI_HOST_PDEV_ID_INVALID) { 648 wmi_handle->evt_phy_id_map 649 [wmi_handle->cmd_phy_id_map[i]] = i; 650 } 651 } 652 wmi_handle->soc->is_pdev_is_map_enable = true; 653 wmi_handle->soc->is_phy_id_map_enable = true; 654 } else { 655 wmi_handle->soc->is_pdev_is_map_enable = false; 656 wmi_handle->soc->is_phy_id_map_enable = false; 657 } 658 659 wmi_handle->ops->convert_pdev_id_host_to_target = 660 convert_host_pdev_id_to_target_pdev_id; 661 wmi_handle->ops->convert_pdev_id_target_to_host = 662 convert_target_pdev_id_to_host_pdev_id; 663 664 /* phy_id convert function assignments */ 665 wmi_handle->ops->convert_phy_id_host_to_target = 666 convert_host_phy_id_to_target_phy_id; 667 wmi_handle->ops->convert_phy_id_target_to_host = 668 convert_target_phy_id_to_host_phy_id; 669 } 670 671 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 672 * buffer. 673 * @wmi_handle: pointer to wmi_handle 674 * @cmd: pointer target vdev create command buffer 675 * @param: pointer host params for vdev create 676 * 677 * Return: None 678 */ 679 static inline void copy_vdev_create_pdev_id( 680 struct wmi_unified *wmi_handle, 681 wmi_vdev_create_cmd_fixed_param * cmd, 682 struct vdev_create_params *param) 683 { 684 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 685 wmi_handle, 686 param->pdev_id); 687 } 688 689 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 690 { 691 uint16_t mtrace_message_id; 692 693 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 694 (QDF_WMI_MTRACE_GRP_ID(message_id) << 695 QDF_WMI_MTRACE_CMD_NUM_BITS); 696 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 697 mtrace_message_id, vdev_id, data); 698 } 699 qdf_export_symbol(wmi_mtrace); 700 701 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 702 static QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 703 wmi_buf_t buf, 704 uint32_t buflen, uint32_t cmd_id) 705 { 706 if (wmi_is_target_suspended(wmi_handle)) { 707 if (QDF_IS_STATUS_SUCCESS( 708 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 709 buflen, cmd_id))) 710 return QDF_STATUS_SUCCESS; 711 } 712 713 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 714 715 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 716 } 717 #else 718 static inline 719 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 720 wmi_buf_t buf, 721 uint32_t buflen, uint32_t cmd_id) 722 { 723 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 724 } 725 #endif 726 727 /** 728 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 729 * @wmi_handle: wmi handle 730 * @param: pointer to hold vdev create parameter 731 * @macaddr: vdev mac address 732 * 733 * Return: QDF_STATUS_SUCCESS for success or error code 734 */ 735 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 736 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 737 struct vdev_create_params *param) 738 { 739 wmi_vdev_create_cmd_fixed_param *cmd; 740 wmi_buf_t buf; 741 int32_t len = sizeof(*cmd); 742 QDF_STATUS ret; 743 int num_bands = 2; 744 uint8_t *buf_ptr; 745 wmi_vdev_txrx_streams *txrx_streams; 746 747 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 748 buf = wmi_buf_alloc(wmi_handle, len); 749 if (!buf) 750 return QDF_STATUS_E_NOMEM; 751 752 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 753 WMITLV_SET_HDR(&cmd->tlv_header, 754 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 755 WMITLV_GET_STRUCT_TLVLEN 756 (wmi_vdev_create_cmd_fixed_param)); 757 cmd->vdev_id = param->vdev_id; 758 cmd->vdev_type = param->type; 759 cmd->vdev_subtype = param->subtype; 760 cmd->flags = param->mbssid_flags; 761 cmd->vdevid_trans = param->vdevid_trans; 762 cmd->num_cfg_txrx_streams = num_bands; 763 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 764 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 765 WMI_LOGD("%s: ID = %d[pdev:%d] VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", 766 __func__, param->vdev_id, cmd->pdev_id, 767 macaddr[0], macaddr[1], macaddr[2], 768 macaddr[3], macaddr[4], macaddr[5]); 769 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 770 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 771 (num_bands * sizeof(wmi_vdev_txrx_streams))); 772 buf_ptr += WMI_TLV_HDR_SIZE; 773 774 WMI_LOGD("%s: type %d, subtype %d, nss_2g %d, nss_5g %d", __func__, 775 param->type, param->subtype, 776 param->nss_2g, param->nss_5g); 777 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 778 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 779 txrx_streams->supported_tx_streams = param->nss_2g; 780 txrx_streams->supported_rx_streams = param->nss_2g; 781 WMITLV_SET_HDR(&txrx_streams->tlv_header, 782 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 783 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 784 785 txrx_streams++; 786 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 787 txrx_streams->supported_tx_streams = param->nss_5g; 788 txrx_streams->supported_rx_streams = param->nss_5g; 789 WMITLV_SET_HDR(&txrx_streams->tlv_header, 790 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 791 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 792 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 793 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 794 if (QDF_IS_STATUS_ERROR(ret)) { 795 WMI_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); 796 wmi_buf_free(buf); 797 } 798 799 return ret; 800 } 801 802 /** 803 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 804 * @wmi_handle: wmi handle 805 * @if_id: vdev id 806 * 807 * Return: QDF_STATUS_SUCCESS for success or error code 808 */ 809 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 810 uint8_t if_id) 811 { 812 wmi_vdev_delete_cmd_fixed_param *cmd; 813 wmi_buf_t buf; 814 QDF_STATUS ret; 815 816 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 817 if (!buf) 818 return QDF_STATUS_E_NOMEM; 819 820 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 821 WMITLV_SET_HDR(&cmd->tlv_header, 822 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 823 WMITLV_GET_STRUCT_TLVLEN 824 (wmi_vdev_delete_cmd_fixed_param)); 825 cmd->vdev_id = if_id; 826 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 827 ret = wmi_unified_cmd_send(wmi_handle, buf, 828 sizeof(wmi_vdev_delete_cmd_fixed_param), 829 WMI_VDEV_DELETE_CMDID); 830 if (QDF_IS_STATUS_ERROR(ret)) { 831 WMI_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); 832 wmi_buf_free(buf); 833 } 834 WMI_LOGD("%s:vdev id = %d", __func__, if_id); 835 836 return ret; 837 } 838 839 /** 840 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 841 * @wmi_handle: wmi handle 842 * @vdev_id: vdev id 843 * @nss_chains_user_cfg: user configured nss chain params 844 * 845 * Return: QDF_STATUS_SUCCESS for success or error code 846 */ 847 static QDF_STATUS 848 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 849 uint8_t vdev_id, 850 struct vdev_nss_chains *user_cfg) 851 { 852 wmi_vdev_chainmask_config_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_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 861 WMITLV_SET_HDR(&cmd->tlv_header, 862 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 863 WMITLV_GET_STRUCT_TLVLEN 864 (wmi_vdev_chainmask_config_cmd_fixed_param)); 865 cmd->vdev_id = vdev_id; 866 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 867 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 868 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 869 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 870 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 871 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 872 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 873 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 874 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 875 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 876 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 877 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 878 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 879 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 880 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 881 882 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 883 ret = wmi_unified_cmd_send(wmi_handle, buf, 884 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 885 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 886 if (QDF_IS_STATUS_ERROR(ret)) { 887 WMI_LOGE("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 888 wmi_buf_free(buf); 889 } 890 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 891 892 return ret; 893 } 894 895 /** 896 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 897 * @wmi: wmi handle 898 * @vdev_id: vdev id 899 * 900 * Return: QDF_STATUS_SUCCESS for success or erro code 901 */ 902 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 903 uint8_t vdev_id) 904 { 905 wmi_vdev_stop_cmd_fixed_param *cmd; 906 wmi_buf_t buf; 907 int32_t len = sizeof(*cmd); 908 909 buf = wmi_buf_alloc(wmi, len); 910 if (!buf) 911 return QDF_STATUS_E_NOMEM; 912 913 cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); 914 WMITLV_SET_HDR(&cmd->tlv_header, 915 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 916 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 917 cmd->vdev_id = vdev_id; 918 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 919 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 920 WMI_LOGP("%s: Failed to send vdev stop command", __func__); 921 wmi_buf_free(buf); 922 return QDF_STATUS_E_FAILURE; 923 } 924 WMI_LOGD("%s:vdev id = %d", __func__, vdev_id); 925 926 return 0; 927 } 928 929 /** 930 * send_vdev_down_cmd_tlv() - send vdev down command to fw 931 * @wmi: wmi handle 932 * @vdev_id: vdev id 933 * 934 * Return: QDF_STATUS_SUCCESS for success or error code 935 */ 936 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 937 { 938 wmi_vdev_down_cmd_fixed_param *cmd; 939 wmi_buf_t buf; 940 int32_t len = sizeof(*cmd); 941 942 buf = wmi_buf_alloc(wmi, len); 943 if (!buf) 944 return QDF_STATUS_E_NOMEM; 945 946 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 947 WMITLV_SET_HDR(&cmd->tlv_header, 948 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 949 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 950 cmd->vdev_id = vdev_id; 951 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 952 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 953 WMI_LOGP("%s: Failed to send vdev down", __func__); 954 wmi_buf_free(buf); 955 return QDF_STATUS_E_FAILURE; 956 } 957 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 958 959 return 0; 960 } 961 962 static inline void copy_channel_info( 963 wmi_vdev_start_request_cmd_fixed_param * cmd, 964 wmi_channel *chan, 965 struct vdev_start_params *req) 966 { 967 chan->mhz = req->channel.mhz; 968 969 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 970 971 chan->band_center_freq1 = req->channel.cfreq1; 972 chan->band_center_freq2 = req->channel.cfreq2; 973 974 if (req->channel.half_rate) 975 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 976 else if (req->channel.quarter_rate) 977 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 978 979 if (req->channel.dfs_set) { 980 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 981 cmd->disable_hw_ack = req->disable_hw_ack; 982 } 983 984 if (req->channel.dfs_set_cfreq2) 985 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 986 987 /* According to firmware both reg power and max tx power 988 * on set channel power is used and set it to max reg 989 * power from regulatory. 990 */ 991 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 992 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 993 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 994 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 995 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 996 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 997 998 } 999 1000 /** 1001 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1002 * @wmi_handle: wmi handle 1003 * @req: vdev start params 1004 * 1005 * Return: QDF status 1006 */ 1007 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1008 struct vdev_start_params *req) 1009 { 1010 wmi_vdev_start_request_cmd_fixed_param *cmd; 1011 wmi_buf_t buf; 1012 wmi_channel *chan; 1013 int32_t len, ret; 1014 uint8_t *buf_ptr; 1015 1016 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1017 buf = wmi_buf_alloc(wmi_handle, len); 1018 if (!buf) 1019 return QDF_STATUS_E_NOMEM; 1020 1021 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1022 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1023 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1024 WMITLV_SET_HDR(&cmd->tlv_header, 1025 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1026 WMITLV_GET_STRUCT_TLVLEN 1027 (wmi_vdev_start_request_cmd_fixed_param)); 1028 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1029 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1030 cmd->vdev_id = req->vdev_id; 1031 1032 /* Fill channel info */ 1033 copy_channel_info(cmd, chan, req); 1034 cmd->beacon_interval = req->beacon_interval; 1035 cmd->dtim_period = req->dtim_period; 1036 1037 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1038 if (req->bcn_tx_rate_code) 1039 wmi_enable_bcn_ratecode(&cmd->flags); 1040 1041 if (!req->is_restart) { 1042 if (req->pmf_enabled) 1043 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1044 } 1045 1046 /* Copy the SSID */ 1047 if (req->ssid.length) { 1048 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1049 cmd->ssid.ssid_len = req->ssid.length; 1050 else 1051 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1052 qdf_mem_copy(cmd->ssid.ssid, req->ssid.mac_ssid, 1053 cmd->ssid.ssid_len); 1054 } 1055 1056 if (req->hidden_ssid) 1057 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1058 1059 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1060 cmd->num_noa_descriptors = req->num_noa_descriptors; 1061 cmd->preferred_rx_streams = req->preferred_rx_streams; 1062 cmd->preferred_tx_streams = req->preferred_tx_streams; 1063 cmd->cac_duration_ms = req->cac_duration_ms; 1064 cmd->regdomain = req->regdomain; 1065 cmd->he_ops = req->he_ops; 1066 1067 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1068 sizeof(wmi_channel)); 1069 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1070 cmd->num_noa_descriptors * 1071 sizeof(wmi_p2p_noa_descriptor)); 1072 WMI_LOGI("%s: vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1073 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1074 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1075 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1076 "req->dis_hw_ack: %d ", __func__, req->vdev_id, 1077 chan->mhz, req->channel.phy_mode, chan->info, 1078 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1079 chan->band_center_freq1, chan->band_center_freq2, 1080 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1081 req->preferred_tx_streams, req->preferred_rx_streams, 1082 req->ldpc_rx_enabled, req->cac_duration_ms, 1083 req->regdomain, req->he_ops, 1084 req->disable_hw_ack); 1085 1086 if (req->is_restart) { 1087 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1088 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1089 WMI_VDEV_RESTART_REQUEST_CMDID); 1090 } else { 1091 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1092 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1093 WMI_VDEV_START_REQUEST_CMDID); 1094 } 1095 if (ret) { 1096 WMI_LOGP("%s: Failed to send vdev start command", __func__); 1097 wmi_buf_free(buf); 1098 return QDF_STATUS_E_FAILURE; 1099 } 1100 1101 return QDF_STATUS_SUCCESS; 1102 } 1103 1104 /** 1105 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1106 * @wmi: wmi handle 1107 * @peer_addr: peer mac address 1108 * @param: pointer to hold peer flush tid parameter 1109 * 1110 * Return: 0 for success or error code 1111 */ 1112 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1113 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1114 struct peer_flush_params *param) 1115 { 1116 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1117 wmi_buf_t buf; 1118 int32_t len = sizeof(*cmd); 1119 1120 buf = wmi_buf_alloc(wmi, len); 1121 if (!buf) 1122 return QDF_STATUS_E_NOMEM; 1123 1124 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1125 WMITLV_SET_HDR(&cmd->tlv_header, 1126 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1127 WMITLV_GET_STRUCT_TLVLEN 1128 (wmi_peer_flush_tids_cmd_fixed_param)); 1129 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1130 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1131 cmd->vdev_id = param->vdev_id; 1132 WMI_LOGD("%s: peer_addr %pM vdev_id %d and peer bitmap %d", __func__, 1133 peer_addr, param->vdev_id, 1134 param->peer_tid_bitmap); 1135 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1136 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1137 WMI_LOGP("%s: Failed to send flush tid command", __func__); 1138 wmi_buf_free(buf); 1139 return QDF_STATUS_E_FAILURE; 1140 } 1141 1142 return 0; 1143 } 1144 1145 /** 1146 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1147 * @wmi: wmi handle 1148 * @peer_addr: peer mac addr 1149 * @vdev_id: vdev id 1150 * 1151 * Return: QDF_STATUS_SUCCESS for success or error code 1152 */ 1153 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1154 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1155 uint8_t vdev_id) 1156 { 1157 wmi_peer_delete_cmd_fixed_param *cmd; 1158 wmi_buf_t buf; 1159 int32_t len = sizeof(*cmd); 1160 buf = wmi_buf_alloc(wmi, len); 1161 if (!buf) 1162 return QDF_STATUS_E_NOMEM; 1163 1164 cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); 1165 WMITLV_SET_HDR(&cmd->tlv_header, 1166 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1167 WMITLV_GET_STRUCT_TLVLEN 1168 (wmi_peer_delete_cmd_fixed_param)); 1169 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1170 cmd->vdev_id = vdev_id; 1171 1172 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); 1173 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1174 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1175 WMI_LOGP("%s: Failed to send peer delete command", __func__); 1176 wmi_buf_free(buf); 1177 return QDF_STATUS_E_FAILURE; 1178 } 1179 1180 return 0; 1181 } 1182 1183 /** 1184 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1185 * @wmi: wmi handle 1186 * @param: pointer to hold peer delete all parameter 1187 * 1188 * Return: QDF_STATUS_SUCCESS for success or error code 1189 */ 1190 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1191 wmi_unified_t wmi, 1192 struct peer_delete_all_params *param) 1193 { 1194 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1195 wmi_buf_t buf; 1196 int32_t len = sizeof(*cmd); 1197 1198 buf = wmi_buf_alloc(wmi, len); 1199 if (!buf) 1200 return QDF_STATUS_E_NOMEM; 1201 1202 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1203 WMITLV_SET_HDR( 1204 &cmd->tlv_header, 1205 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1206 WMITLV_GET_STRUCT_TLVLEN 1207 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1208 cmd->vdev_id = param->vdev_id; 1209 1210 WMI_LOGD("%s: vdev_id %d", __func__, cmd->vdev_id); 1211 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1212 if (wmi_unified_cmd_send(wmi, buf, len, 1213 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1214 WMI_LOGP("%s: Failed to send peer del all command", __func__); 1215 wmi_buf_free(buf); 1216 return QDF_STATUS_E_FAILURE; 1217 } 1218 1219 return QDF_STATUS_SUCCESS; 1220 } 1221 1222 /** 1223 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1224 * to target id. 1225 * @peer_param_id: host param id. 1226 * 1227 * Return: Target param id. 1228 */ 1229 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1230 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1231 uint32_t peer_param_id) 1232 { 1233 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1234 return peer_param_tlv[peer_param_id]; 1235 return WMI_UNAVAILABLE_PARAM; 1236 } 1237 #else 1238 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1239 uint32_t peer_param_id) 1240 { 1241 return peer_param_id; 1242 } 1243 #endif 1244 1245 /** 1246 * send_peer_param_cmd_tlv() - set peer parameter in fw 1247 * @wmi: wmi handle 1248 * @peer_addr: peer mac address 1249 * @param : pointer to hold peer set parameter 1250 * 1251 * Return: QDF_STATUS_SUCCESS for success or error code 1252 */ 1253 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1254 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1255 struct peer_set_params *param) 1256 { 1257 wmi_peer_set_param_cmd_fixed_param *cmd; 1258 wmi_buf_t buf; 1259 int32_t err; 1260 uint32_t param_id; 1261 1262 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1263 if (param_id == WMI_UNAVAILABLE_PARAM) { 1264 WMI_LOGW("%s: Unavailable param %d", __func__, param->param_id); 1265 return QDF_STATUS_E_NOSUPPORT; 1266 } 1267 1268 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1269 if (!buf) 1270 return QDF_STATUS_E_NOMEM; 1271 1272 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1273 WMITLV_SET_HDR(&cmd->tlv_header, 1274 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1275 WMITLV_GET_STRUCT_TLVLEN 1276 (wmi_peer_set_param_cmd_fixed_param)); 1277 cmd->vdev_id = param->vdev_id; 1278 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1279 cmd->param_id = param_id; 1280 cmd->param_value = param->param_value; 1281 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1282 err = wmi_unified_cmd_send(wmi, buf, 1283 sizeof(wmi_peer_set_param_cmd_fixed_param), 1284 WMI_PEER_SET_PARAM_CMDID); 1285 if (err) { 1286 WMI_LOGE("Failed to send set_param cmd"); 1287 wmi_buf_free(buf); 1288 return QDF_STATUS_E_FAILURE; 1289 } 1290 1291 return 0; 1292 } 1293 1294 /** 1295 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1296 * @wmi: wmi handle 1297 * @bssid: bssid 1298 * @vdev_up_params: pointer to hold vdev up parameter 1299 * 1300 * Return: QDF_STATUS_SUCCESS for success or error code 1301 */ 1302 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1303 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1304 struct vdev_up_params *params) 1305 { 1306 wmi_vdev_up_cmd_fixed_param *cmd; 1307 wmi_buf_t buf; 1308 int32_t len = sizeof(*cmd); 1309 1310 WMI_LOGD("%s: VDEV_UP", __func__); 1311 WMI_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, 1312 params->vdev_id, params->assoc_id, bssid); 1313 buf = wmi_buf_alloc(wmi, len); 1314 if (!buf) 1315 return QDF_STATUS_E_NOMEM; 1316 1317 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1318 WMITLV_SET_HDR(&cmd->tlv_header, 1319 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1320 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1321 cmd->vdev_id = params->vdev_id; 1322 cmd->vdev_assoc_id = params->assoc_id; 1323 cmd->profile_idx = params->profile_idx; 1324 cmd->profile_num = params->profile_num; 1325 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1326 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1327 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1328 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1329 WMI_LOGP("%s: Failed to send vdev up command", __func__); 1330 wmi_buf_free(buf); 1331 return QDF_STATUS_E_FAILURE; 1332 } 1333 1334 return 0; 1335 } 1336 1337 /** 1338 * send_peer_create_cmd_tlv() - send peer create command to fw 1339 * @wmi: wmi handle 1340 * @peer_addr: peer mac address 1341 * @peer_type: peer type 1342 * @vdev_id: vdev id 1343 * 1344 * Return: QDF_STATUS_SUCCESS for success or error code 1345 */ 1346 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1347 struct peer_create_params *param) 1348 { 1349 wmi_peer_create_cmd_fixed_param *cmd; 1350 wmi_buf_t buf; 1351 int32_t len = sizeof(*cmd); 1352 1353 buf = wmi_buf_alloc(wmi, len); 1354 if (!buf) 1355 return QDF_STATUS_E_NOMEM; 1356 1357 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1358 WMITLV_SET_HDR(&cmd->tlv_header, 1359 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1360 WMITLV_GET_STRUCT_TLVLEN 1361 (wmi_peer_create_cmd_fixed_param)); 1362 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1363 cmd->peer_type = param->peer_type; 1364 cmd->vdev_id = param->vdev_id; 1365 1366 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1367 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1368 WMI_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); 1369 wmi_buf_free(buf); 1370 return QDF_STATUS_E_FAILURE; 1371 } 1372 WMI_LOGD("%s: peer_addr %pM vdev_id %d", __func__, param->peer_addr, 1373 param->vdev_id); 1374 1375 return 0; 1376 } 1377 1378 /** 1379 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1380 * command to fw 1381 * @wmi: wmi handle 1382 * @rx_reorder_queue_setup_params: Rx reorder queue setup parameters 1383 * 1384 * Return: 0 for success or error code 1385 */ 1386 static 1387 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1388 struct rx_reorder_queue_setup_params *param) 1389 { 1390 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1391 wmi_buf_t buf; 1392 int32_t len = sizeof(*cmd); 1393 1394 buf = wmi_buf_alloc(wmi, len); 1395 if (!buf) 1396 return QDF_STATUS_E_NOMEM; 1397 1398 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 1399 WMITLV_SET_HDR(&cmd->tlv_header, 1400 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 1401 WMITLV_GET_STRUCT_TLVLEN 1402 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 1403 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1404 cmd->vdev_id = param->vdev_id; 1405 cmd->tid = param->tid; 1406 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 1407 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 1408 cmd->queue_no = param->queue_no; 1409 cmd->ba_window_size_valid = param->ba_window_size_valid; 1410 cmd->ba_window_size = param->ba_window_size; 1411 1412 1413 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 1414 if (wmi_unified_cmd_send(wmi, buf, len, 1415 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 1416 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID", 1417 __func__); 1418 wmi_buf_free(buf); 1419 return QDF_STATUS_E_FAILURE; 1420 } 1421 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid %d", __func__, 1422 param->peer_macaddr, param->vdev_id, param->tid); 1423 1424 return QDF_STATUS_SUCCESS; 1425 } 1426 1427 /** 1428 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 1429 * command to fw 1430 * @wmi: wmi handle 1431 * @rx_reorder_queue_remove_params: Rx reorder queue remove parameters 1432 * 1433 * Return: 0 for success or error code 1434 */ 1435 static 1436 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 1437 struct rx_reorder_queue_remove_params *param) 1438 { 1439 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 1440 wmi_buf_t buf; 1441 int32_t len = sizeof(*cmd); 1442 1443 buf = wmi_buf_alloc(wmi, len); 1444 if (!buf) 1445 return QDF_STATUS_E_NOMEM; 1446 1447 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 1448 wmi_buf_data(buf); 1449 WMITLV_SET_HDR(&cmd->tlv_header, 1450 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 1451 WMITLV_GET_STRUCT_TLVLEN 1452 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 1453 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1454 cmd->vdev_id = param->vdev_id; 1455 cmd->tid_mask = param->peer_tid_bitmap; 1456 1457 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 1458 if (wmi_unified_cmd_send(wmi, buf, len, 1459 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 1460 WMI_LOGP("%s: fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID", 1461 __func__); 1462 wmi_buf_free(buf); 1463 return QDF_STATUS_E_FAILURE; 1464 } 1465 WMI_LOGD("%s: peer_macaddr %pM vdev_id %d, tid_map %d", __func__, 1466 param->peer_macaddr, param->vdev_id, param->peer_tid_bitmap); 1467 1468 return QDF_STATUS_SUCCESS; 1469 } 1470 1471 #ifdef WLAN_SUPPORT_GREEN_AP 1472 /** 1473 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 1474 * @wmi_handle: wmi handle 1475 * @value: value 1476 * @pdev_id: pdev id to have radio context 1477 * 1478 * Return: QDF_STATUS_SUCCESS for success or error code 1479 */ 1480 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 1481 uint32_t value, uint8_t pdev_id) 1482 { 1483 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 1484 wmi_buf_t buf; 1485 int32_t len = sizeof(*cmd); 1486 1487 WMI_LOGD("Set Green AP PS val %d", value); 1488 1489 buf = wmi_buf_alloc(wmi_handle, len); 1490 if (!buf) 1491 return QDF_STATUS_E_NOMEM; 1492 1493 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 1494 WMITLV_SET_HDR(&cmd->tlv_header, 1495 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 1496 WMITLV_GET_STRUCT_TLVLEN 1497 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 1498 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1499 wmi_handle, 1500 pdev_id); 1501 cmd->enable = value; 1502 1503 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 1504 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1505 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 1506 WMI_LOGE("Set Green AP PS param Failed val %d", value); 1507 wmi_buf_free(buf); 1508 return QDF_STATUS_E_FAILURE; 1509 } 1510 1511 return 0; 1512 } 1513 #endif 1514 1515 /** 1516 * send_pdev_utf_cmd_tlv() - send utf command to fw 1517 * @wmi_handle: wmi handle 1518 * @param: pointer to pdev_utf_params 1519 * @mac_id: mac id to have radio context 1520 * 1521 * Return: QDF_STATUS_SUCCESS for success or error code 1522 */ 1523 static QDF_STATUS 1524 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 1525 struct pdev_utf_params *param, 1526 uint8_t mac_id) 1527 { 1528 wmi_buf_t buf; 1529 uint8_t *cmd; 1530 /* if param->len is 0 no data is sent, return error */ 1531 QDF_STATUS ret = QDF_STATUS_E_INVAL; 1532 static uint8_t msgref = 1; 1533 uint8_t segNumber = 0, segInfo, numSegments; 1534 uint16_t chunk_len, total_bytes; 1535 uint8_t *bufpos; 1536 struct seg_hdr_info segHdrInfo; 1537 1538 bufpos = param->utf_payload; 1539 total_bytes = param->len; 1540 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 1541 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 1542 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 1543 1544 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 1545 numSegments++; 1546 1547 while (param->len) { 1548 if (param->len > MAX_WMI_UTF_LEN) 1549 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 1550 else 1551 chunk_len = param->len; 1552 1553 buf = wmi_buf_alloc(wmi_handle, 1554 (chunk_len + sizeof(segHdrInfo) + 1555 WMI_TLV_HDR_SIZE)); 1556 if (!buf) 1557 return QDF_STATUS_E_NOMEM; 1558 1559 cmd = (uint8_t *) wmi_buf_data(buf); 1560 1561 segHdrInfo.len = total_bytes; 1562 segHdrInfo.msgref = msgref; 1563 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 1564 segHdrInfo.segmentInfo = segInfo; 1565 segHdrInfo.pad = 0; 1566 1567 WMI_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," 1568 " segHdrInfo.segmentInfo = %d", 1569 __func__, segHdrInfo.len, segHdrInfo.msgref, 1570 segHdrInfo.segmentInfo); 1571 1572 WMI_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" 1573 "chunk len %d", __func__, total_bytes, segNumber, 1574 numSegments, chunk_len); 1575 1576 segNumber++; 1577 1578 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 1579 (chunk_len + sizeof(segHdrInfo))); 1580 cmd += WMI_TLV_HDR_SIZE; 1581 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ 1582 memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); 1583 1584 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 1585 ret = wmi_unified_cmd_send(wmi_handle, buf, 1586 (chunk_len + sizeof(segHdrInfo) + 1587 WMI_TLV_HDR_SIZE), 1588 WMI_PDEV_UTF_CMDID); 1589 1590 if (QDF_IS_STATUS_ERROR(ret)) { 1591 WMI_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); 1592 wmi_buf_free(buf); 1593 break; 1594 } 1595 1596 param->len -= chunk_len; 1597 bufpos += chunk_len; 1598 } 1599 1600 msgref++; 1601 1602 return ret; 1603 } 1604 1605 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1606 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1607 { 1608 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 1609 return pdev_param_tlv[host_param]; 1610 return WMI_UNAVAILABLE_PARAM; 1611 } 1612 #else 1613 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 1614 { 1615 return host_param; 1616 } 1617 #endif 1618 1619 /** 1620 * send_pdev_param_cmd_tlv() - set pdev parameters 1621 * @wmi_handle: wmi handle 1622 * @param: pointer to pdev parameter 1623 * @mac_id: radio context 1624 * 1625 * Return: 0 on success, errno on failure 1626 */ 1627 static QDF_STATUS 1628 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 1629 struct pdev_params *param, 1630 uint8_t mac_id) 1631 { 1632 QDF_STATUS ret; 1633 wmi_pdev_set_param_cmd_fixed_param *cmd; 1634 wmi_buf_t buf; 1635 uint16_t len = sizeof(*cmd); 1636 uint32_t pdev_param; 1637 1638 pdev_param = convert_host_pdev_param_tlv(param->param_id); 1639 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 1640 WMI_LOGW("%s: Unavailable param %d", 1641 __func__, param->param_id); 1642 return QDF_STATUS_E_INVAL; 1643 } 1644 1645 buf = wmi_buf_alloc(wmi_handle, len); 1646 if (!buf) 1647 return QDF_STATUS_E_NOMEM; 1648 1649 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1650 WMITLV_SET_HDR(&cmd->tlv_header, 1651 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 1652 WMITLV_GET_STRUCT_TLVLEN 1653 (wmi_pdev_set_param_cmd_fixed_param)); 1654 if (param->is_host_pdev_id) 1655 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 1656 wmi_handle, 1657 mac_id); 1658 else 1659 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1660 wmi_handle, 1661 mac_id); 1662 cmd->param_id = pdev_param; 1663 cmd->param_value = param->param_value; 1664 WMI_LOGD("Setting pdev param = %x, value = %u", param->param_id, 1665 param->param_value); 1666 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 1667 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1668 WMI_PDEV_SET_PARAM_CMDID); 1669 if (QDF_IS_STATUS_ERROR(ret)) { 1670 WMI_LOGE("Failed to send set param command ret = %d", ret); 1671 wmi_buf_free(buf); 1672 } 1673 return ret; 1674 } 1675 1676 /** 1677 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 1678 * @wmi_handle: wmi handle 1679 * @msg: Structure containing the following parameters 1680 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 1681 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 1682 * 1683 * Provides notification to the WLAN firmware that host driver is requesting a 1684 * HardWare (HW) Mode change. This command is needed to support iHelium in the 1685 * configurations that include the Dual Band Simultaneous (DBS) feature. 1686 * 1687 * Return: Success if the cmd is sent successfully to the firmware 1688 */ 1689 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 1690 uint32_t hw_mode_index) 1691 { 1692 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 1693 wmi_buf_t buf; 1694 uint32_t len; 1695 1696 len = sizeof(*cmd); 1697 1698 buf = wmi_buf_alloc(wmi_handle, len); 1699 if (!buf) 1700 return QDF_STATUS_E_NOMEM; 1701 1702 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 1703 WMITLV_SET_HDR(&cmd->tlv_header, 1704 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 1705 WMITLV_GET_STRUCT_TLVLEN( 1706 wmi_pdev_set_hw_mode_cmd_fixed_param)); 1707 1708 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1709 wmi_handle, 1710 WMI_HOST_PDEV_ID_SOC); 1711 cmd->hw_mode_index = hw_mode_index; 1712 WMI_LOGD("%s: HW mode index:%d", __func__, cmd->hw_mode_index); 1713 1714 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 1715 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1716 WMI_PDEV_SET_HW_MODE_CMDID)) { 1717 WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID", 1718 __func__); 1719 wmi_buf_free(buf); 1720 return QDF_STATUS_E_FAILURE; 1721 } 1722 1723 return QDF_STATUS_SUCCESS; 1724 } 1725 1726 /** 1727 * send_suspend_cmd_tlv() - WMI suspend function 1728 * @param wmi_handle : handle to WMI. 1729 * @param param : pointer to hold suspend parameter 1730 * @mac_id: radio context 1731 * 1732 * Return 0 on success and -ve on failure. 1733 */ 1734 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 1735 struct suspend_params *param, 1736 uint8_t mac_id) 1737 { 1738 wmi_pdev_suspend_cmd_fixed_param *cmd; 1739 wmi_buf_t wmibuf; 1740 uint32_t len = sizeof(*cmd); 1741 int32_t ret; 1742 1743 /* 1744 * send the command to Target to ignore the 1745 * PCIE reset so as to ensure that Host and target 1746 * states are in sync 1747 */ 1748 wmibuf = wmi_buf_alloc(wmi_handle, len); 1749 if (!wmibuf) 1750 return QDF_STATUS_E_NOMEM; 1751 1752 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 1753 WMITLV_SET_HDR(&cmd->tlv_header, 1754 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 1755 WMITLV_GET_STRUCT_TLVLEN 1756 (wmi_pdev_suspend_cmd_fixed_param)); 1757 if (param->disable_target_intr) 1758 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 1759 else 1760 cmd->suspend_opt = WMI_PDEV_SUSPEND; 1761 1762 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1763 wmi_handle, 1764 mac_id); 1765 1766 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 1767 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 1768 WMI_PDEV_SUSPEND_CMDID); 1769 if (ret) { 1770 wmi_buf_free(wmibuf); 1771 WMI_LOGE("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 1772 } 1773 1774 return ret; 1775 } 1776 1777 /** 1778 * send_resume_cmd_tlv() - WMI resume function 1779 * @param wmi_handle : handle to WMI. 1780 * @mac_id: radio context 1781 * 1782 * Return: 0 on success and -ve on failure. 1783 */ 1784 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 1785 uint8_t mac_id) 1786 { 1787 wmi_buf_t wmibuf; 1788 wmi_pdev_resume_cmd_fixed_param *cmd; 1789 QDF_STATUS ret; 1790 1791 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1792 if (!wmibuf) 1793 return QDF_STATUS_E_NOMEM; 1794 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 1795 WMITLV_SET_HDR(&cmd->tlv_header, 1796 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 1797 WMITLV_GET_STRUCT_TLVLEN 1798 (wmi_pdev_resume_cmd_fixed_param)); 1799 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 1800 wmi_handle, 1801 mac_id); 1802 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 1803 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 1804 WMI_PDEV_RESUME_CMDID); 1805 if (QDF_IS_STATUS_ERROR(ret)) { 1806 WMI_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); 1807 wmi_buf_free(wmibuf); 1808 } 1809 1810 return ret; 1811 } 1812 1813 /** 1814 * send_wow_enable_cmd_tlv() - WMI wow enable function 1815 * @param wmi_handle : handle to WMI. 1816 * @param param : pointer to hold wow enable parameter 1817 * @mac_id: radio context 1818 * 1819 * Return: 0 on success and -ve on failure. 1820 */ 1821 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 1822 struct wow_cmd_params *param, 1823 uint8_t mac_id) 1824 { 1825 wmi_wow_enable_cmd_fixed_param *cmd; 1826 wmi_buf_t buf; 1827 int32_t len; 1828 int32_t ret; 1829 1830 len = sizeof(wmi_wow_enable_cmd_fixed_param); 1831 1832 buf = wmi_buf_alloc(wmi_handle, len); 1833 if (!buf) 1834 return QDF_STATUS_E_NOMEM; 1835 1836 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 1837 WMITLV_SET_HDR(&cmd->tlv_header, 1838 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 1839 WMITLV_GET_STRUCT_TLVLEN 1840 (wmi_wow_enable_cmd_fixed_param)); 1841 cmd->enable = param->enable; 1842 if (param->can_suspend_link) 1843 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 1844 else 1845 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 1846 cmd->flags = param->flags; 1847 1848 WMI_LOGI("suspend type: %s", 1849 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 1850 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED"); 1851 1852 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 1853 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1854 WMI_WOW_ENABLE_CMDID); 1855 if (ret) 1856 wmi_buf_free(buf); 1857 1858 return ret; 1859 } 1860 1861 /** 1862 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 1863 * @wmi_handle: wmi handle 1864 * @peer_addr: peer mac address 1865 * @param: pointer to ap_ps parameter structure 1866 * 1867 * Return: QDF_STATUS_SUCCESS for success or error code 1868 */ 1869 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1870 uint8_t *peer_addr, 1871 struct ap_ps_params *param) 1872 { 1873 wmi_ap_ps_peer_cmd_fixed_param *cmd; 1874 wmi_buf_t buf; 1875 int32_t err; 1876 1877 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1878 if (!buf) 1879 return QDF_STATUS_E_NOMEM; 1880 1881 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 1882 WMITLV_SET_HDR(&cmd->tlv_header, 1883 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 1884 WMITLV_GET_STRUCT_TLVLEN 1885 (wmi_ap_ps_peer_cmd_fixed_param)); 1886 cmd->vdev_id = param->vdev_id; 1887 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1888 cmd->param = param->param; 1889 cmd->value = param->value; 1890 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 1891 err = wmi_unified_cmd_send(wmi_handle, buf, 1892 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 1893 if (err) { 1894 WMI_LOGE("Failed to send set_ap_ps_param cmd"); 1895 wmi_buf_free(buf); 1896 return QDF_STATUS_E_FAILURE; 1897 } 1898 1899 return 0; 1900 } 1901 1902 /** 1903 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 1904 * @wmi_handle: wmi handle 1905 * @peer_addr: peer mac address 1906 * @param: pointer to sta_ps parameter structure 1907 * 1908 * Return: QDF_STATUS_SUCCESS for success or error code 1909 */ 1910 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 1911 struct sta_ps_params *param) 1912 { 1913 wmi_sta_powersave_param_cmd_fixed_param *cmd; 1914 wmi_buf_t buf; 1915 int32_t len = sizeof(*cmd); 1916 1917 buf = wmi_buf_alloc(wmi_handle, len); 1918 if (!buf) 1919 return QDF_STATUS_E_NOMEM; 1920 1921 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 1922 WMITLV_SET_HDR(&cmd->tlv_header, 1923 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 1924 WMITLV_GET_STRUCT_TLVLEN 1925 (wmi_sta_powersave_param_cmd_fixed_param)); 1926 cmd->vdev_id = param->vdev_id; 1927 cmd->param = param->param_id; 1928 cmd->value = param->value; 1929 1930 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 1931 if (wmi_unified_cmd_send(wmi_handle, buf, len, 1932 WMI_STA_POWERSAVE_PARAM_CMDID)) { 1933 WMI_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", 1934 param->vdev_id, param->param_id, param->value); 1935 wmi_buf_free(buf); 1936 return QDF_STATUS_E_FAILURE; 1937 } 1938 1939 return 0; 1940 } 1941 1942 /** 1943 * send_crash_inject_cmd_tlv() - inject fw crash 1944 * @wmi_handle: wmi handle 1945 * @param: ponirt to crash inject parameter structure 1946 * 1947 * Return: QDF_STATUS_SUCCESS for success or return error 1948 */ 1949 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 1950 struct crash_inject *param) 1951 { 1952 int32_t ret = 0; 1953 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 1954 uint16_t len = sizeof(*cmd); 1955 wmi_buf_t buf; 1956 1957 buf = wmi_buf_alloc(wmi_handle, len); 1958 if (!buf) 1959 return QDF_STATUS_E_NOMEM; 1960 1961 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 1962 WMITLV_SET_HDR(&cmd->tlv_header, 1963 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 1964 WMITLV_GET_STRUCT_TLVLEN 1965 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 1966 cmd->type = param->type; 1967 cmd->delay_time_ms = param->delay_time_ms; 1968 1969 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 1970 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1971 WMI_FORCE_FW_HANG_CMDID); 1972 if (ret) { 1973 WMI_LOGE("%s: Failed to send set param command, ret = %d", 1974 __func__, ret); 1975 wmi_buf_free(buf); 1976 } 1977 1978 return ret; 1979 } 1980 1981 #ifdef FEATURE_FW_LOG_PARSING 1982 /** 1983 * send_dbglog_cmd_tlv() - set debug log level 1984 * @param wmi_handle : handle to WMI. 1985 * @param param : pointer to hold dbglog level parameter 1986 * 1987 * Return: 0 on success and -ve on failure. 1988 */ 1989 static QDF_STATUS 1990 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 1991 struct dbglog_params *dbglog_param) 1992 { 1993 wmi_buf_t buf; 1994 wmi_debug_log_config_cmd_fixed_param *configmsg; 1995 QDF_STATUS status; 1996 int32_t i; 1997 int32_t len; 1998 int8_t *buf_ptr; 1999 int32_t *module_id_bitmap_array; /* Used to fomr the second tlv */ 2000 2001 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2002 2003 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2004 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2005 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2006 buf = wmi_buf_alloc(wmi_handle, len); 2007 if (!buf) 2008 return QDF_STATUS_E_NOMEM; 2009 2010 configmsg = 2011 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 2012 buf_ptr = (int8_t *) configmsg; 2013 WMITLV_SET_HDR(&configmsg->tlv_header, 2014 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 2015 WMITLV_GET_STRUCT_TLVLEN 2016 (wmi_debug_log_config_cmd_fixed_param)); 2017 configmsg->dbg_log_param = dbglog_param->param; 2018 configmsg->value = dbglog_param->val; 2019 /* Filling in the data part of second tlv -- should 2020 * follow first tlv _ WMI_TLV_HDR_SIZE */ 2021 module_id_bitmap_array = (uint32_t *) (buf_ptr + 2022 sizeof 2023 (wmi_debug_log_config_cmd_fixed_param) 2024 + WMI_TLV_HDR_SIZE); 2025 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 2026 WMITLV_TAG_ARRAY_UINT32, 2027 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2028 if (dbglog_param->module_id_bitmap) { 2029 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 2030 module_id_bitmap_array[i] = 2031 dbglog_param->module_id_bitmap[i]; 2032 } 2033 } 2034 2035 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 2036 status = wmi_unified_cmd_send(wmi_handle, buf, 2037 len, WMI_DBGLOG_CFG_CMDID); 2038 2039 if (status != QDF_STATUS_SUCCESS) 2040 wmi_buf_free(buf); 2041 2042 return status; 2043 } 2044 #endif 2045 2046 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2047 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2048 { 2049 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2050 return vdev_param_tlv[host_param]; 2051 return WMI_UNAVAILABLE_PARAM; 2052 } 2053 #else 2054 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2055 { 2056 return host_param; 2057 } 2058 #endif 2059 2060 /** 2061 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 2062 * @param wmi_handle : handle to WMI. 2063 * @param macaddr : MAC address 2064 * @param param : pointer to hold vdev set parameter 2065 * 2066 * Return: 0 on success and -ve on failure. 2067 */ 2068 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 2069 struct vdev_set_params *param) 2070 { 2071 QDF_STATUS ret; 2072 wmi_vdev_set_param_cmd_fixed_param *cmd; 2073 wmi_buf_t buf; 2074 uint16_t len = sizeof(*cmd); 2075 uint32_t vdev_param; 2076 2077 vdev_param = convert_host_vdev_param_tlv(param->param_id); 2078 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 2079 WMI_LOGW("%s:Vdev param %d not available", __func__, 2080 param->param_id); 2081 return QDF_STATUS_E_INVAL; 2082 2083 } 2084 2085 buf = wmi_buf_alloc(wmi_handle, len); 2086 if (!buf) 2087 return QDF_STATUS_E_NOMEM; 2088 2089 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2090 WMITLV_SET_HDR(&cmd->tlv_header, 2091 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 2092 WMITLV_GET_STRUCT_TLVLEN 2093 (wmi_vdev_set_param_cmd_fixed_param)); 2094 cmd->vdev_id = param->vdev_id; 2095 cmd->param_id = vdev_param; 2096 cmd->param_value = param->param_value; 2097 WMI_LOGD("Setting vdev %d param = %x, value = %u", 2098 cmd->vdev_id, cmd->param_id, cmd->param_value); 2099 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 2100 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2101 WMI_VDEV_SET_PARAM_CMDID); 2102 if (QDF_IS_STATUS_ERROR(ret)) { 2103 WMI_LOGE("Failed to send set param command ret = %d", ret); 2104 wmi_buf_free(buf); 2105 } 2106 2107 return ret; 2108 } 2109 2110 /** 2111 * send_stats_request_cmd_tlv() - WMI request stats function 2112 * @param wmi_handle : handle to WMI. 2113 * @param macaddr : MAC address 2114 * @param param : pointer to hold stats request parameter 2115 * 2116 * Return: 0 on success and -ve on failure. 2117 */ 2118 static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 2119 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 2120 struct stats_request_params *param) 2121 { 2122 int32_t ret; 2123 wmi_request_stats_cmd_fixed_param *cmd; 2124 wmi_buf_t buf; 2125 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 2126 2127 buf = wmi_buf_alloc(wmi_handle, len); 2128 if (!buf) 2129 return -QDF_STATUS_E_NOMEM; 2130 2131 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 2132 WMITLV_SET_HDR(&cmd->tlv_header, 2133 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 2134 WMITLV_GET_STRUCT_TLVLEN 2135 (wmi_request_stats_cmd_fixed_param)); 2136 cmd->stats_id = param->stats_id; 2137 cmd->vdev_id = param->vdev_id; 2138 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2139 wmi_handle, 2140 param->pdev_id); 2141 2142 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 2143 2144 WMI_LOGD("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d-->", 2145 cmd->stats_id, cmd->vdev_id, cmd->pdev_id); 2146 2147 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 2148 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 2149 WMI_REQUEST_STATS_CMDID); 2150 2151 if (ret) { 2152 WMI_LOGE("Failed to send status request to fw =%d", ret); 2153 wmi_buf_free(buf); 2154 } 2155 2156 return ret; 2157 } 2158 2159 /** 2160 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 2161 * @wmi_handle: handle to WMI. 2162 * @macaddr: Peer mac address to be filter 2163 * @mac_id: mac id to have radio context 2164 * @enb_dsb: Enable MAC based filtering or Disable 2165 * 2166 * Return: QDF_STATUS 2167 */ 2168 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 2169 uint8_t *macaddr, 2170 uint8_t mac_id, 2171 uint8_t enb_dsb) 2172 { 2173 int32_t ret; 2174 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 2175 wmi_pdev_pktlog_filter_info *mac_info; 2176 wmi_buf_t buf; 2177 uint8_t *buf_ptr; 2178 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 2179 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 2180 2181 buf = wmi_buf_alloc(wmi_handle, len); 2182 if (!buf) 2183 return QDF_STATUS_E_NOMEM; 2184 2185 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2186 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 2187 WMITLV_SET_HDR(&cmd->tlv_header, 2188 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 2189 WMITLV_GET_STRUCT_TLVLEN 2190 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 2191 cmd->pdev_id = mac_id; 2192 cmd->enable = enb_dsb; 2193 cmd->num_of_mac_addresses = 1; 2194 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 2195 2196 buf_ptr += sizeof(*cmd); 2197 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2198 sizeof(wmi_pdev_pktlog_filter_info)); 2199 buf_ptr += WMI_TLV_HDR_SIZE; 2200 2201 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 2202 2203 WMITLV_SET_HDR(&mac_info->tlv_header, 2204 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 2205 WMITLV_GET_STRUCT_TLVLEN 2206 (wmi_pdev_pktlog_filter_info)); 2207 2208 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 2209 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2210 WMI_PDEV_PKTLOG_FILTER_CMDID); 2211 if (ret) { 2212 WMI_LOGE("Failed to send peer based pktlog command to FW =%d" 2213 , ret); 2214 wmi_buf_free(buf); 2215 } 2216 2217 return ret; 2218 } 2219 2220 /** 2221 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 2222 * @param wmi_handle : handle to WMI. 2223 * @param PKTLOG_EVENT : packet log event 2224 * @mac_id: mac id to have radio context 2225 * 2226 * Return: 0 on success and -ve on failure. 2227 */ 2228 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 2229 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 2230 { 2231 int32_t ret, idx, max_idx; 2232 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 2233 wmi_buf_t buf; 2234 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 2235 2236 buf = wmi_buf_alloc(wmi_handle, len); 2237 if (!buf) 2238 return -QDF_STATUS_E_NOMEM; 2239 2240 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 2241 WMITLV_SET_HDR(&cmd->tlv_header, 2242 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 2243 WMITLV_GET_STRUCT_TLVLEN 2244 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 2245 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 2246 cmd->evlist = 0; 2247 for (idx = 0; idx < max_idx; idx++) { 2248 if (PKTLOG_EVENT & (1 << idx)) 2249 cmd->evlist |= pktlog_event_tlv[idx]; 2250 } 2251 cmd->pdev_id = mac_id; 2252 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 2253 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2254 WMI_PDEV_PKTLOG_ENABLE_CMDID); 2255 if (ret) { 2256 WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); 2257 wmi_buf_free(buf); 2258 } 2259 2260 return ret; 2261 } 2262 2263 /** 2264 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 2265 * @param wmi_handle : handle to WMI. 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_disable_cmd_tlv(wmi_unified_t wmi_handle, 2271 uint8_t mac_id) 2272 { 2273 int32_t ret; 2274 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 2275 wmi_buf_t buf; 2276 uint16_t len = sizeof(wmi_pdev_pktlog_disable_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_disable_cmd_fixed_param *) wmi_buf_data(buf); 2283 WMITLV_SET_HDR(&cmd->tlv_header, 2284 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 2285 WMITLV_GET_STRUCT_TLVLEN 2286 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 2287 cmd->pdev_id = mac_id; 2288 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 2289 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2290 WMI_PDEV_PKTLOG_DISABLE_CMDID); 2291 if (ret) { 2292 WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); 2293 wmi_buf_free(buf); 2294 } 2295 2296 return ret; 2297 } 2298 2299 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 2300 /** 2301 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 2302 * sync time between bwtween host and firmware 2303 * @param wmi_handle : handle to WMI. 2304 * 2305 * Return: None 2306 */ 2307 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 2308 { 2309 wmi_buf_t buf; 2310 QDF_STATUS status = QDF_STATUS_SUCCESS; 2311 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 2312 int32_t len; 2313 qdf_time_t time_ms; 2314 2315 len = sizeof(*time_stamp); 2316 buf = wmi_buf_alloc(wmi_handle, len); 2317 2318 if (!buf) 2319 return; 2320 2321 time_stamp = 2322 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 2323 (wmi_buf_data(buf)); 2324 WMITLV_SET_HDR(&time_stamp->tlv_header, 2325 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 2326 WMITLV_GET_STRUCT_TLVLEN( 2327 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 2328 2329 time_ms = qdf_get_time_of_the_day_ms(); 2330 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 2331 time_stamp->time_stamp_low = time_ms & 2332 WMI_FW_TIME_STAMP_LOW_MASK; 2333 /* 2334 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 2335 * wont exceed 27 bit 2336 */ 2337 time_stamp->time_stamp_high = 0; 2338 WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), 2339 time_stamp->mode, time_stamp->time_stamp_low, 2340 time_stamp->time_stamp_high); 2341 2342 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 2343 status = wmi_unified_cmd_send(wmi_handle, buf, 2344 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 2345 if (status) { 2346 WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 2347 wmi_buf_free(buf); 2348 } 2349 2350 } 2351 2352 /** 2353 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 2354 * @param wmi_handle : handle to WMI. 2355 * @param param : pointer to hold FILS Discovery send cmd parameter 2356 * 2357 * Return: 0 on success and -ve on failure. 2358 */ 2359 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 2360 struct fils_discovery_tmpl_params *param) 2361 { 2362 int32_t ret; 2363 wmi_fd_tmpl_cmd_fixed_param *cmd; 2364 wmi_buf_t wmi_buf; 2365 uint8_t *buf_ptr; 2366 uint32_t wmi_buf_len; 2367 2368 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 2369 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 2370 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2371 if (!wmi_buf) 2372 return QDF_STATUS_E_NOMEM; 2373 2374 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2375 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 2376 WMITLV_SET_HDR(&cmd->tlv_header, 2377 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 2378 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 2379 cmd->vdev_id = param->vdev_id; 2380 cmd->buf_len = param->tmpl_len; 2381 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 2382 2383 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2384 buf_ptr += WMI_TLV_HDR_SIZE; 2385 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2386 2387 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 2388 ret = wmi_unified_cmd_send(wmi_handle, 2389 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 2390 2391 if (ret) { 2392 WMI_LOGE("%s: Failed to send fd tmpl: %d", __func__, ret); 2393 wmi_buf_free(wmi_buf); 2394 return ret; 2395 } 2396 2397 return 0; 2398 } 2399 2400 /** 2401 * send_beacon_send_tmpl_cmd_tlv() - WMI beacon send function 2402 * @param wmi_handle : handle to WMI. 2403 * @param param : pointer to hold beacon send cmd parameter 2404 * 2405 * Return: 0 on success and -ve on failure. 2406 */ 2407 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 2408 struct beacon_tmpl_params *param) 2409 { 2410 int32_t ret; 2411 wmi_bcn_tmpl_cmd_fixed_param *cmd; 2412 wmi_bcn_prb_info *bcn_prb_info; 2413 wmi_buf_t wmi_buf; 2414 uint8_t *buf_ptr; 2415 uint32_t wmi_buf_len; 2416 2417 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 2418 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 2419 param->tmpl_len_aligned; 2420 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 2421 if (!wmi_buf) 2422 return QDF_STATUS_E_NOMEM; 2423 2424 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2425 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 2426 WMITLV_SET_HDR(&cmd->tlv_header, 2427 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 2428 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 2429 cmd->vdev_id = param->vdev_id; 2430 cmd->tim_ie_offset = param->tim_ie_offset; 2431 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 2432 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 2433 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 2434 cmd->esp_ie_offset = param->esp_ie_offset; 2435 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 2436 cmd->ema_params = param->ema_params; 2437 cmd->buf_len = param->tmpl_len; 2438 2439 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 2440 param->enable_bigtk); 2441 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 2442 2443 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 2444 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 2445 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 2446 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 2447 bcn_prb_info->caps = 0; 2448 bcn_prb_info->erp = 0; 2449 buf_ptr += sizeof(wmi_bcn_prb_info); 2450 2451 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 2452 buf_ptr += WMI_TLV_HDR_SIZE; 2453 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 2454 2455 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 2456 ret = wmi_unified_cmd_send(wmi_handle, 2457 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 2458 if (ret) { 2459 WMI_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); 2460 wmi_buf_free(wmi_buf); 2461 } 2462 2463 return 0; 2464 } 2465 2466 static inline void copy_peer_flags_tlv( 2467 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2468 struct peer_assoc_params *param) 2469 { 2470 /* 2471 * The target only needs a subset of the flags maintained in the host. 2472 * Just populate those flags and send it down 2473 */ 2474 cmd->peer_flags = 0; 2475 2476 /* 2477 * Do not enable HT/VHT if WMM/wme is disabled for vap. 2478 */ 2479 if (param->is_wme_set) { 2480 2481 if (param->qos_flag) 2482 cmd->peer_flags |= WMI_PEER_QOS; 2483 if (param->apsd_flag) 2484 cmd->peer_flags |= WMI_PEER_APSD; 2485 if (param->ht_flag) 2486 cmd->peer_flags |= WMI_PEER_HT; 2487 if (param->bw_40) 2488 cmd->peer_flags |= WMI_PEER_40MHZ; 2489 if (param->bw_80) 2490 cmd->peer_flags |= WMI_PEER_80MHZ; 2491 if (param->bw_160) 2492 cmd->peer_flags |= WMI_PEER_160MHZ; 2493 2494 /* Typically if STBC is enabled for VHT it should be enabled 2495 * for HT as well 2496 **/ 2497 if (param->stbc_flag) 2498 cmd->peer_flags |= WMI_PEER_STBC; 2499 2500 /* Typically if LDPC is enabled for VHT it should be enabled 2501 * for HT as well 2502 **/ 2503 if (param->ldpc_flag) 2504 cmd->peer_flags |= WMI_PEER_LDPC; 2505 2506 if (param->static_mimops_flag) 2507 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 2508 if (param->dynamic_mimops_flag) 2509 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 2510 if (param->spatial_mux_flag) 2511 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 2512 if (param->vht_flag) 2513 cmd->peer_flags |= WMI_PEER_VHT; 2514 if (param->he_flag) 2515 cmd->peer_flags |= WMI_PEER_HE; 2516 if (param->p2p_capable_sta) 2517 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 2518 } 2519 2520 if (param->is_pmf_enabled) 2521 cmd->peer_flags |= WMI_PEER_PMF; 2522 /* 2523 * Suppress authorization for all AUTH modes that need 4-way handshake 2524 * (during re-association). 2525 * Authorization will be done for these modes on key installation. 2526 */ 2527 if (param->auth_flag) 2528 cmd->peer_flags |= WMI_PEER_AUTH; 2529 if (param->need_ptk_4_way) 2530 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 2531 else 2532 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 2533 if (param->need_gtk_2_way) 2534 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 2535 /* safe mode bypass the 4-way handshake */ 2536 if (param->safe_mode_enabled) 2537 cmd->peer_flags &= 2538 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 2539 /* inter BSS peer */ 2540 if (param->inter_bss_peer) 2541 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 2542 /* Disable AMSDU for station transmit, if user configures it */ 2543 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 2544 * it 2545 * if (param->amsdu_disable) Add after FW support 2546 **/ 2547 2548 /* Target asserts if node is marked HT and all MCS is set to 0. 2549 * Mark the node as non-HT if all the mcs rates are disabled through 2550 * iwpriv 2551 **/ 2552 if (param->peer_ht_rates.num_rates == 0) 2553 cmd->peer_flags &= ~WMI_PEER_HT; 2554 2555 if (param->twt_requester) 2556 cmd->peer_flags |= WMI_PEER_TWT_REQ; 2557 2558 if (param->twt_responder) 2559 cmd->peer_flags |= WMI_PEER_TWT_RESP; 2560 } 2561 2562 static inline void copy_peer_mac_addr_tlv( 2563 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 2564 struct peer_assoc_params *param) 2565 { 2566 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 2567 } 2568 2569 /** 2570 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 2571 * @param wmi_handle : handle to WMI. 2572 * @param param : pointer to peer assoc parameter 2573 * 2574 * Return: 0 on success and -ve on failure. 2575 */ 2576 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 2577 struct peer_assoc_params *param) 2578 { 2579 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 2580 wmi_vht_rate_set *mcs; 2581 wmi_he_rate_set *he_mcs; 2582 wmi_buf_t buf; 2583 int32_t len; 2584 uint8_t *buf_ptr; 2585 QDF_STATUS ret; 2586 uint32_t peer_legacy_rates_align; 2587 uint32_t peer_ht_rates_align; 2588 int32_t i; 2589 2590 2591 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 2592 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 2593 2594 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 2595 (peer_legacy_rates_align * sizeof(uint8_t)) + 2596 WMI_TLV_HDR_SIZE + 2597 (peer_ht_rates_align * sizeof(uint8_t)) + 2598 sizeof(wmi_vht_rate_set) + 2599 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 2600 + WMI_TLV_HDR_SIZE); 2601 2602 buf = wmi_buf_alloc(wmi_handle, len); 2603 if (!buf) 2604 return QDF_STATUS_E_NOMEM; 2605 2606 buf_ptr = (uint8_t *) wmi_buf_data(buf); 2607 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 2608 WMITLV_SET_HDR(&cmd->tlv_header, 2609 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 2610 WMITLV_GET_STRUCT_TLVLEN 2611 (wmi_peer_assoc_complete_cmd_fixed_param)); 2612 2613 cmd->vdev_id = param->vdev_id; 2614 2615 cmd->peer_new_assoc = param->peer_new_assoc; 2616 cmd->peer_associd = param->peer_associd; 2617 2618 copy_peer_flags_tlv(cmd, param); 2619 copy_peer_mac_addr_tlv(cmd, param); 2620 2621 cmd->peer_rate_caps = param->peer_rate_caps; 2622 cmd->peer_caps = param->peer_caps; 2623 cmd->peer_listen_intval = param->peer_listen_intval; 2624 cmd->peer_ht_caps = param->peer_ht_caps; 2625 cmd->peer_max_mpdu = param->peer_max_mpdu; 2626 cmd->peer_mpdu_density = param->peer_mpdu_density; 2627 cmd->peer_vht_caps = param->peer_vht_caps; 2628 cmd->peer_phymode = param->peer_phymode; 2629 2630 /* Update 11ax capabilities */ 2631 cmd->peer_he_cap_info = 2632 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 2633 cmd->peer_he_cap_info_ext = 2634 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 2635 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 2636 cmd->peer_he_ops = param->peer_he_ops; 2637 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 2638 sizeof(param->peer_he_cap_phyinfo)); 2639 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 2640 sizeof(param->peer_ppet)); 2641 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 2642 2643 /* Update peer legacy rate information */ 2644 buf_ptr += sizeof(*cmd); 2645 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2646 peer_legacy_rates_align); 2647 buf_ptr += WMI_TLV_HDR_SIZE; 2648 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 2649 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 2650 param->peer_legacy_rates.num_rates); 2651 2652 /* Update peer HT rate information */ 2653 buf_ptr += peer_legacy_rates_align; 2654 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 2655 peer_ht_rates_align); 2656 buf_ptr += WMI_TLV_HDR_SIZE; 2657 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 2658 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 2659 param->peer_ht_rates.num_rates); 2660 2661 /* VHT Rates */ 2662 buf_ptr += peer_ht_rates_align; 2663 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 2664 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 2665 2666 cmd->peer_nss = param->peer_nss; 2667 2668 /* Update bandwidth-NSS mapping */ 2669 cmd->peer_bw_rxnss_override = 0; 2670 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2671 2672 mcs = (wmi_vht_rate_set *) buf_ptr; 2673 if (param->vht_capable) { 2674 mcs->rx_max_rate = param->rx_max_rate; 2675 mcs->rx_mcs_set = param->rx_mcs_set; 2676 mcs->tx_max_rate = param->tx_max_rate; 2677 mcs->tx_mcs_set = param->tx_mcs_set; 2678 } 2679 2680 /* HE Rates */ 2681 cmd->min_data_rate = param->min_data_rate; 2682 cmd->peer_he_mcs = param->peer_he_mcs_count; 2683 buf_ptr += sizeof(wmi_vht_rate_set); 2684 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2685 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 2686 buf_ptr += WMI_TLV_HDR_SIZE; 2687 2688 /* Loop through the HE rate set */ 2689 for (i = 0; i < param->peer_he_mcs_count; i++) { 2690 he_mcs = (wmi_he_rate_set *) buf_ptr; 2691 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 2692 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 2693 2694 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2695 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2696 WMI_LOGD("%s:HE idx %d RxMCSmap %x TxMCSmap %x ", __func__, 2697 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 2698 buf_ptr += sizeof(wmi_he_rate_set); 2699 } 2700 2701 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 2702 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2703 == WMI_HOST_HE_INVALID_MCSNSSMAP || 2704 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 2705 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 2706 WMI_LOGD("param->peer_he_tx_mcs_set[160MHz]=%x", 2707 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2708 WMI_LOGD("param->peer_he_rx_mcs_set[160MHz]=%x", 2709 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 2710 WMI_LOGD("peer_mac=%02x:%02x:%02x:%02x:%02x:%02x", 2711 param->peer_mac[0], param->peer_mac[1], 2712 param->peer_mac[2], param->peer_mac[3], 2713 param->peer_mac[4], param->peer_mac[5]); 2714 } 2715 2716 WMI_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " 2717 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 2718 "nss %d phymode %d peer_mpdu_density %d " 2719 "cmd->peer_vht_caps %x " 2720 "HE cap_info %x ops %x " 2721 "HE cap_info_ext %x " 2722 "HE phy %x %x %x " 2723 "peer_bw_rxnss_override %x", __func__, 2724 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 2725 cmd->peer_rate_caps, cmd->peer_caps, 2726 cmd->peer_listen_intval, cmd->peer_ht_caps, 2727 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 2728 cmd->peer_mpdu_density, 2729 cmd->peer_vht_caps, cmd->peer_he_cap_info, 2730 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 2731 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 2732 cmd->peer_he_cap_phy[2], 2733 cmd->peer_bw_rxnss_override); 2734 2735 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 2736 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2737 WMI_PEER_ASSOC_CMDID); 2738 if (QDF_IS_STATUS_ERROR(ret)) { 2739 WMI_LOGP("%s: Failed to send peer assoc command ret = %d", 2740 __func__, ret); 2741 wmi_buf_free(buf); 2742 } 2743 2744 return ret; 2745 } 2746 2747 /* copy_scan_notify_events() - Helper routine to copy scan notify events 2748 */ 2749 static inline void copy_scan_event_cntrl_flags( 2750 wmi_start_scan_cmd_fixed_param * cmd, 2751 struct scan_req_params *param) 2752 { 2753 2754 /* Scan events subscription */ 2755 if (param->scan_ev_started) 2756 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 2757 if (param->scan_ev_completed) 2758 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 2759 if (param->scan_ev_bss_chan) 2760 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 2761 if (param->scan_ev_foreign_chan) 2762 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 2763 if (param->scan_ev_dequeued) 2764 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 2765 if (param->scan_ev_preempted) 2766 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 2767 if (param->scan_ev_start_failed) 2768 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 2769 if (param->scan_ev_restarted) 2770 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 2771 if (param->scan_ev_foreign_chn_exit) 2772 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 2773 if (param->scan_ev_suspended) 2774 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 2775 if (param->scan_ev_resumed) 2776 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 2777 2778 /** Set scan control flags */ 2779 cmd->scan_ctrl_flags = 0; 2780 if (param->scan_f_passive) 2781 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 2782 if (param->scan_f_strict_passive_pch) 2783 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 2784 if (param->scan_f_promisc_mode) 2785 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 2786 if (param->scan_f_capture_phy_err) 2787 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 2788 if (param->scan_f_half_rate) 2789 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 2790 if (param->scan_f_quarter_rate) 2791 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 2792 if (param->scan_f_cck_rates) 2793 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 2794 if (param->scan_f_ofdm_rates) 2795 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 2796 if (param->scan_f_chan_stat_evnt) 2797 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 2798 if (param->scan_f_filter_prb_req) 2799 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 2800 if (param->scan_f_bcast_probe) 2801 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 2802 if (param->scan_f_offchan_mgmt_tx) 2803 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 2804 if (param->scan_f_offchan_data_tx) 2805 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 2806 if (param->scan_f_force_active_dfs_chn) 2807 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 2808 if (param->scan_f_add_tpc_ie_in_probe) 2809 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 2810 if (param->scan_f_add_ds_ie_in_probe) 2811 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 2812 if (param->scan_f_add_spoofed_mac_in_probe) 2813 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 2814 if (param->scan_f_add_rand_seq_in_probe) 2815 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 2816 if (param->scan_f_en_ie_whitelist_in_probe) 2817 cmd->scan_ctrl_flags |= 2818 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 2819 2820 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 2821 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 2822 param->adaptive_dwell_time_mode); 2823 } 2824 2825 /* scan_copy_ie_buffer() - Copy scan ie_data */ 2826 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 2827 struct scan_req_params *params) 2828 { 2829 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 2830 } 2831 2832 /** 2833 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 2834 * @mac: random mac addr 2835 * @mask: random mac mask 2836 * @mac_addr: wmi random mac 2837 * @mac_mask: wmi random mac mask 2838 * 2839 * Return None. 2840 */ 2841 static inline 2842 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 2843 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 2844 { 2845 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 2846 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 2847 } 2848 2849 /* 2850 * wmi_fill_vendor_oui() - fill vendor OUIs 2851 * @buf_ptr: pointer to wmi tlv buffer 2852 * @num_vendor_oui: number of vendor OUIs to be filled 2853 * @param_voui: pointer to OUI buffer 2854 * 2855 * This function populates the wmi tlv buffer when vendor specific OUIs are 2856 * present. 2857 * 2858 * Return: None 2859 */ 2860 static inline 2861 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 2862 uint32_t *pvoui) 2863 { 2864 wmi_vendor_oui *voui = NULL; 2865 uint32_t i; 2866 2867 voui = (wmi_vendor_oui *)buf_ptr; 2868 2869 for (i = 0; i < num_vendor_oui; i++) { 2870 WMITLV_SET_HDR(&voui[i].tlv_header, 2871 WMITLV_TAG_STRUC_wmi_vendor_oui, 2872 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 2873 voui[i].oui_type_subtype = pvoui[i]; 2874 } 2875 } 2876 2877 /* 2878 * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs 2879 * @ie_bitmap: output pointer to ie bit map in cmd 2880 * @num_vendor_oui: output pointer to num vendor OUIs 2881 * @ie_whitelist: input parameter 2882 * 2883 * This function populates the IE whitelist attrs of scan, pno and 2884 * scan oui commands for ie_whitelist parameter. 2885 * 2886 * Return: None 2887 */ 2888 static inline 2889 void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap, 2890 uint32_t *num_vendor_oui, 2891 struct probe_req_whitelist_attr *ie_whitelist) 2892 { 2893 uint32_t i = 0; 2894 2895 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 2896 ie_bitmap[i] = ie_whitelist->ie_bitmap[i]; 2897 2898 *num_vendor_oui = ie_whitelist->num_vendor_oui; 2899 } 2900 2901 /** 2902 * send_scan_start_cmd_tlv() - WMI scan start function 2903 * @param wmi_handle : handle to WMI. 2904 * @param param : pointer to hold scan start cmd parameter 2905 * 2906 * Return: 0 on success and -ve on failure. 2907 */ 2908 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 2909 struct scan_req_params *params) 2910 { 2911 int32_t ret = 0; 2912 int32_t i; 2913 wmi_buf_t wmi_buf; 2914 wmi_start_scan_cmd_fixed_param *cmd; 2915 uint8_t *buf_ptr; 2916 uint32_t *tmp_ptr; 2917 wmi_ssid *ssid = NULL; 2918 wmi_mac_addr *bssid; 2919 size_t len = sizeof(*cmd); 2920 uint16_t extraie_len_with_pad = 0; 2921 uint8_t phymode_roundup = 0; 2922 struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; 2923 wmi_hint_freq_short_ssid *s_ssid = NULL; 2924 wmi_hint_freq_bssid *hint_bssid = NULL; 2925 2926 /* Length TLV placeholder for array of uint32_t */ 2927 len += WMI_TLV_HDR_SIZE; 2928 /* calculate the length of buffer required */ 2929 if (params->chan_list.num_chan) 2930 len += params->chan_list.num_chan * sizeof(uint32_t); 2931 2932 /* Length TLV placeholder for array of wmi_ssid structures */ 2933 len += WMI_TLV_HDR_SIZE; 2934 if (params->num_ssids) 2935 len += params->num_ssids * sizeof(wmi_ssid); 2936 2937 /* Length TLV placeholder for array of wmi_mac_addr structures */ 2938 len += WMI_TLV_HDR_SIZE; 2939 if (params->num_bssid) 2940 len += sizeof(wmi_mac_addr) * params->num_bssid; 2941 2942 /* Length TLV placeholder for array of bytes */ 2943 len += WMI_TLV_HDR_SIZE; 2944 if (params->extraie.len) 2945 extraie_len_with_pad = 2946 roundup(params->extraie.len, sizeof(uint32_t)); 2947 len += extraie_len_with_pad; 2948 2949 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 2950 if (ie_whitelist->num_vendor_oui) 2951 len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 2952 2953 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 2954 if (params->scan_f_wide_band) 2955 phymode_roundup = 2956 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 2957 sizeof(uint32_t)); 2958 len += phymode_roundup; 2959 2960 len += WMI_TLV_HDR_SIZE; 2961 if (params->num_hint_bssid) 2962 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 2963 2964 len += WMI_TLV_HDR_SIZE; 2965 if (params->num_hint_s_ssid) 2966 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 2967 2968 /* Allocate the memory */ 2969 wmi_buf = wmi_buf_alloc(wmi_handle, len); 2970 if (!wmi_buf) 2971 return QDF_STATUS_E_FAILURE; 2972 2973 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 2974 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 2975 WMITLV_SET_HDR(&cmd->tlv_header, 2976 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 2977 WMITLV_GET_STRUCT_TLVLEN 2978 (wmi_start_scan_cmd_fixed_param)); 2979 2980 cmd->scan_id = params->scan_id; 2981 cmd->scan_req_id = params->scan_req_id; 2982 cmd->vdev_id = params->vdev_id; 2983 cmd->scan_priority = params->scan_priority; 2984 2985 copy_scan_event_cntrl_flags(cmd, params); 2986 2987 cmd->dwell_time_active = params->dwell_time_active; 2988 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 2989 cmd->dwell_time_passive = params->dwell_time_passive; 2990 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 2991 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 2992 cmd->scan_start_offset = params->scan_offset_time; 2993 cmd->min_rest_time = params->min_rest_time; 2994 cmd->max_rest_time = params->max_rest_time; 2995 cmd->repeat_probe_time = params->repeat_probe_time; 2996 cmd->probe_spacing_time = params->probe_spacing_time; 2997 cmd->idle_time = params->idle_time; 2998 cmd->max_scan_time = params->max_scan_time; 2999 cmd->probe_delay = params->probe_delay; 3000 cmd->burst_duration = params->burst_duration; 3001 cmd->num_chan = params->chan_list.num_chan; 3002 cmd->num_bssid = params->num_bssid; 3003 cmd->num_ssids = params->num_ssids; 3004 cmd->ie_len = params->extraie.len; 3005 cmd->n_probes = params->n_probes; 3006 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 3007 3008 if (params->scan_random.randomize) 3009 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 3010 params->scan_random.mac_mask, 3011 &cmd->mac_addr, 3012 &cmd->mac_mask); 3013 3014 if (ie_whitelist->white_list) 3015 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 3016 &cmd->num_vendor_oui, 3017 ie_whitelist); 3018 3019 buf_ptr += sizeof(*cmd); 3020 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3021 for (i = 0; i < params->chan_list.num_chan; ++i) 3022 tmp_ptr[i] = params->chan_list.chan[i].freq; 3023 3024 WMITLV_SET_HDR(buf_ptr, 3025 WMITLV_TAG_ARRAY_UINT32, 3026 (params->chan_list.num_chan * sizeof(uint32_t))); 3027 buf_ptr += WMI_TLV_HDR_SIZE + 3028 (params->chan_list.num_chan * sizeof(uint32_t)); 3029 3030 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 3031 WMI_LOGE("Invalid value for num_ssids %d", params->num_ssids); 3032 goto error; 3033 } 3034 3035 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3036 (params->num_ssids * sizeof(wmi_ssid))); 3037 3038 if (params->num_ssids) { 3039 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 3040 for (i = 0; i < params->num_ssids; ++i) { 3041 ssid->ssid_len = params->ssid[i].length; 3042 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 3043 params->ssid[i].length); 3044 ssid++; 3045 } 3046 } 3047 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 3048 3049 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3050 (params->num_bssid * sizeof(wmi_mac_addr))); 3051 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 3052 3053 if (params->num_bssid) { 3054 for (i = 0; i < params->num_bssid; ++i) { 3055 WMI_CHAR_ARRAY_TO_MAC_ADDR( 3056 ¶ms->bssid_list[i].bytes[0], bssid); 3057 bssid++; 3058 } 3059 } 3060 3061 buf_ptr += WMI_TLV_HDR_SIZE + 3062 (params->num_bssid * sizeof(wmi_mac_addr)); 3063 3064 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 3065 if (params->extraie.len) 3066 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 3067 params); 3068 3069 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 3070 3071 /* probe req ie whitelisting */ 3072 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3073 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 3074 3075 buf_ptr += WMI_TLV_HDR_SIZE; 3076 3077 if (cmd->num_vendor_oui) { 3078 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 3079 ie_whitelist->voui); 3080 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 3081 } 3082 3083 /* Add phy mode TLV if it's a wide band scan */ 3084 if (params->scan_f_wide_band) { 3085 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 3086 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 3087 for (i = 0; i < params->chan_list.num_chan; ++i) 3088 buf_ptr[i] = 3089 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 3090 buf_ptr += phymode_roundup; 3091 } else { 3092 /* Add ZERO legth phy mode TLV */ 3093 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 3094 buf_ptr += WMI_TLV_HDR_SIZE; 3095 } 3096 3097 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3098 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 3099 if (params->num_hint_s_ssid) { 3100 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3101 for (i = 0; i < params->num_hint_s_ssid; ++i) { 3102 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 3103 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 3104 s_ssid++; 3105 } 3106 } 3107 buf_ptr += WMI_TLV_HDR_SIZE + 3108 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 3109 3110 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 3111 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 3112 if (params->num_hint_bssid) { 3113 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 3114 for (i = 0; i < params->num_hint_bssid; ++i) { 3115 hint_bssid->freq_flags = 3116 params->hint_bssid[i].freq_flags; 3117 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 3118 &hint_bssid->bssid); 3119 hint_bssid++; 3120 } 3121 } 3122 3123 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 3124 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3125 len, WMI_START_SCAN_CMDID); 3126 if (ret) { 3127 WMI_LOGE("%s: Failed to start scan: %d", __func__, ret); 3128 wmi_buf_free(wmi_buf); 3129 } 3130 return ret; 3131 error: 3132 wmi_buf_free(wmi_buf); 3133 return QDF_STATUS_E_FAILURE; 3134 } 3135 3136 /** 3137 * send_scan_stop_cmd_tlv() - WMI scan start function 3138 * @param wmi_handle : handle to WMI. 3139 * @param param : pointer to hold scan cancel cmd parameter 3140 * 3141 * Return: 0 on success and -ve on failure. 3142 */ 3143 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 3144 struct scan_cancel_param *param) 3145 { 3146 wmi_stop_scan_cmd_fixed_param *cmd; 3147 int ret; 3148 int len = sizeof(*cmd); 3149 wmi_buf_t wmi_buf; 3150 3151 /* Allocate the memory */ 3152 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3153 if (!wmi_buf) { 3154 ret = QDF_STATUS_E_NOMEM; 3155 goto error; 3156 } 3157 3158 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 3159 WMITLV_SET_HDR(&cmd->tlv_header, 3160 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 3161 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 3162 cmd->vdev_id = param->vdev_id; 3163 cmd->requestor = param->requester; 3164 cmd->scan_id = param->scan_id; 3165 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3166 wmi_handle, 3167 param->pdev_id); 3168 /* stop the scan with the corresponding scan_id */ 3169 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 3170 /* Cancelling all scans */ 3171 cmd->req_type = WMI_SCAN_STOP_ALL; 3172 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 3173 /* Cancelling VAP scans */ 3174 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 3175 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 3176 /* Cancelling specific scan */ 3177 cmd->req_type = WMI_SCAN_STOP_ONE; 3178 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 3179 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 3180 } else { 3181 WMI_LOGE("%s: Invalid Command : ", __func__); 3182 wmi_buf_free(wmi_buf); 3183 return QDF_STATUS_E_INVAL; 3184 } 3185 3186 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 3187 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 3188 len, WMI_STOP_SCAN_CMDID); 3189 if (ret) { 3190 WMI_LOGE("%s: Failed to send stop scan: %d", __func__, ret); 3191 wmi_buf_free(wmi_buf); 3192 } 3193 3194 error: 3195 return ret; 3196 } 3197 3198 #define WMI_MAX_CHAN_INFO_LOG 192 3199 3200 /** 3201 * wmi_scan_chanlist_dump() - Dump scan channel list info 3202 * @scan_chan_list: scan channel list 3203 * 3204 * Return: void 3205 */ 3206 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 3207 { 3208 uint32_t i; 3209 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 3210 uint32_t len = 0; 3211 struct channel_param *chan; 3212 int ret; 3213 3214 wmi_debug("Total chan %d", scan_chan_list->nallchans); 3215 for (i = 0; i < scan_chan_list->nallchans; i++) { 3216 chan = &scan_chan_list->ch_param[i]; 3217 ret = qdf_scnprintf(info + len, sizeof(info) - len, 3218 " %d[%d][%d]", chan->mhz, chan->maxregpower, 3219 chan->dfs_set); 3220 if (ret <= 0) 3221 break; 3222 len += ret; 3223 if (len >= (sizeof(info) - 20)) { 3224 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3225 len = 0; 3226 } 3227 } 3228 if (len) 3229 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 3230 } 3231 3232 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 3233 struct scan_chan_list_params *chan_list) 3234 { 3235 wmi_buf_t buf; 3236 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 3237 wmi_scan_chan_list_cmd_fixed_param *cmd; 3238 int i; 3239 uint8_t *buf_ptr; 3240 wmi_channel *chan_info; 3241 struct channel_param *tchan_info; 3242 uint16_t len; 3243 uint16_t num_send_chans, num_sends = 0; 3244 3245 wmi_scan_chanlist_dump(chan_list); 3246 tchan_info = &chan_list->ch_param[0]; 3247 while (chan_list->nallchans) { 3248 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 3249 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 3250 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 3251 else 3252 num_send_chans = chan_list->nallchans; 3253 3254 chan_list->nallchans -= num_send_chans; 3255 len += sizeof(wmi_channel) * num_send_chans; 3256 buf = wmi_buf_alloc(wmi_handle, len); 3257 if (!buf) { 3258 qdf_status = QDF_STATUS_E_NOMEM; 3259 goto end; 3260 } 3261 3262 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3263 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 3264 WMITLV_SET_HDR(&cmd->tlv_header, 3265 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 3266 WMITLV_GET_STRUCT_TLVLEN 3267 (wmi_scan_chan_list_cmd_fixed_param)); 3268 3269 WMI_LOGD("no of channels = %d, len = %d", num_send_chans, len); 3270 3271 if (num_sends) 3272 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 3273 3274 if (chan_list->max_bw_support_present) 3275 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 3276 3277 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 3278 wmi_handle, 3279 chan_list->pdev_id); 3280 3281 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 3282 3283 cmd->num_scan_chans = num_send_chans; 3284 WMITLV_SET_HDR((buf_ptr + 3285 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 3286 WMITLV_TAG_ARRAY_STRUC, 3287 sizeof(wmi_channel) * num_send_chans); 3288 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 3289 WMI_TLV_HDR_SIZE); 3290 3291 for (i = 0; i < num_send_chans; ++i) { 3292 WMITLV_SET_HDR(&chan_info->tlv_header, 3293 WMITLV_TAG_STRUC_wmi_channel, 3294 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 3295 chan_info->mhz = tchan_info->mhz; 3296 chan_info->band_center_freq1 = 3297 tchan_info->cfreq1; 3298 chan_info->band_center_freq2 = 3299 tchan_info->cfreq2; 3300 3301 if (tchan_info->is_chan_passive) 3302 WMI_SET_CHANNEL_FLAG(chan_info, 3303 WMI_CHAN_FLAG_PASSIVE); 3304 if (tchan_info->dfs_set) 3305 WMI_SET_CHANNEL_FLAG(chan_info, 3306 WMI_CHAN_FLAG_DFS); 3307 3308 if (tchan_info->dfs_set_cfreq2) 3309 WMI_SET_CHANNEL_FLAG(chan_info, 3310 WMI_CHAN_FLAG_DFS_CFREQ2); 3311 3312 if (tchan_info->allow_he) 3313 WMI_SET_CHANNEL_FLAG(chan_info, 3314 WMI_CHAN_FLAG_ALLOW_HE); 3315 3316 if (tchan_info->allow_vht) 3317 WMI_SET_CHANNEL_FLAG(chan_info, 3318 WMI_CHAN_FLAG_ALLOW_VHT); 3319 3320 if (tchan_info->allow_ht) 3321 WMI_SET_CHANNEL_FLAG(chan_info, 3322 WMI_CHAN_FLAG_ALLOW_HT); 3323 WMI_SET_CHANNEL_MODE(chan_info, 3324 tchan_info->phy_mode); 3325 3326 if (tchan_info->half_rate) 3327 WMI_SET_CHANNEL_FLAG(chan_info, 3328 WMI_CHAN_FLAG_HALF_RATE); 3329 3330 if (tchan_info->quarter_rate) 3331 WMI_SET_CHANNEL_FLAG(chan_info, 3332 WMI_CHAN_FLAG_QUARTER_RATE); 3333 3334 if (tchan_info->psc_channel) 3335 WMI_SET_CHANNEL_FLAG(chan_info, 3336 WMI_CHAN_FLAG_PSC); 3337 3338 /* also fill in power information */ 3339 WMI_SET_CHANNEL_MIN_POWER(chan_info, 3340 tchan_info->minpower); 3341 WMI_SET_CHANNEL_MAX_POWER(chan_info, 3342 tchan_info->maxpower); 3343 WMI_SET_CHANNEL_REG_POWER(chan_info, 3344 tchan_info->maxregpower); 3345 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 3346 tchan_info->antennamax); 3347 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 3348 tchan_info->reg_class_id); 3349 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 3350 tchan_info->maxregpower); 3351 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 3352 tchan_info->max_bw_supported); 3353 3354 tchan_info++; 3355 chan_info++; 3356 } 3357 3358 qdf_status = wmi_unified_cmd_send( 3359 wmi_handle, 3360 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 3361 3362 if (QDF_IS_STATUS_ERROR(qdf_status)) { 3363 WMI_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 3364 wmi_buf_free(buf); 3365 goto end; 3366 } 3367 num_sends++; 3368 } 3369 3370 end: 3371 return qdf_status; 3372 } 3373 3374 /** 3375 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 3376 * 3377 * @bufp: Pointer to buffer 3378 * @param: Pointer to tx param 3379 * 3380 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 3381 */ 3382 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 3383 struct tx_send_params param) 3384 { 3385 wmi_tx_send_params *tx_param; 3386 QDF_STATUS status = QDF_STATUS_SUCCESS; 3387 3388 if (!bufp) { 3389 status = QDF_STATUS_E_FAILURE; 3390 return status; 3391 } 3392 tx_param = (wmi_tx_send_params *)bufp; 3393 WMITLV_SET_HDR(&tx_param->tlv_header, 3394 WMITLV_TAG_STRUC_wmi_tx_send_params, 3395 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 3396 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 3397 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 3398 param.mcs_mask); 3399 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 3400 param.nss_mask); 3401 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 3402 param.retry_limit); 3403 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 3404 param.chain_mask); 3405 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 3406 param.bw_mask); 3407 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 3408 param.preamble_type); 3409 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 3410 param.frame_type); 3411 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 3412 param.cfr_enable); 3413 3414 return status; 3415 } 3416 3417 #ifdef CONFIG_HL_SUPPORT 3418 /** 3419 * send_mgmt_cmd_tlv() - WMI scan start function 3420 * @wmi_handle : handle to WMI. 3421 * @param : pointer to hold mgmt cmd parameter 3422 * 3423 * Return: 0 on success and -ve on failure. 3424 */ 3425 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3426 struct wmi_mgmt_params *param) 3427 { 3428 wmi_buf_t buf; 3429 uint8_t *bufp; 3430 int32_t cmd_len; 3431 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3432 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3433 mgmt_tx_dl_frm_len; 3434 3435 if (param->frm_len > mgmt_tx_dl_frm_len) { 3436 WMI_LOGE("%s:mgmt frame len %u exceeds %u", 3437 __func__, param->frm_len, mgmt_tx_dl_frm_len); 3438 return QDF_STATUS_E_INVAL; 3439 } 3440 3441 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3442 WMI_TLV_HDR_SIZE + 3443 roundup(bufp_len, sizeof(uint32_t)); 3444 3445 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3446 if (!buf) 3447 return QDF_STATUS_E_NOMEM; 3448 3449 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3450 bufp = (uint8_t *) cmd; 3451 WMITLV_SET_HDR(&cmd->tlv_header, 3452 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3453 WMITLV_GET_STRUCT_TLVLEN 3454 (wmi_mgmt_tx_send_cmd_fixed_param)); 3455 3456 cmd->vdev_id = param->vdev_id; 3457 3458 cmd->desc_id = param->desc_id; 3459 cmd->chanfreq = param->chanfreq; 3460 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3461 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3462 sizeof(uint32_t))); 3463 bufp += WMI_TLV_HDR_SIZE; 3464 qdf_mem_copy(bufp, param->pdata, bufp_len); 3465 3466 cmd->frame_len = param->frm_len; 3467 cmd->buf_len = bufp_len; 3468 cmd->tx_params_valid = param->tx_params_valid; 3469 3470 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3471 bufp, cmd->vdev_id, cmd->chanfreq); 3472 3473 bufp += roundup(bufp_len, sizeof(uint32_t)); 3474 if (param->tx_params_valid) { 3475 if (populate_tx_send_params(bufp, param->tx_param) != 3476 QDF_STATUS_SUCCESS) { 3477 WMI_LOGE("%s: Populate TX send params failed", 3478 __func__); 3479 goto free_buf; 3480 } 3481 cmd_len += sizeof(wmi_tx_send_params); 3482 } 3483 3484 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3485 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3486 WMI_MGMT_TX_SEND_CMDID)) { 3487 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3488 goto free_buf; 3489 } 3490 return QDF_STATUS_SUCCESS; 3491 3492 free_buf: 3493 wmi_buf_free(buf); 3494 return QDF_STATUS_E_FAILURE; 3495 } 3496 #else 3497 /** 3498 * send_mgmt_cmd_tlv() - WMI scan start function 3499 * @wmi_handle : handle to WMI. 3500 * @param : pointer to hold mgmt cmd parameter 3501 * 3502 * Return: 0 on success and -ve on failure. 3503 */ 3504 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 3505 struct wmi_mgmt_params *param) 3506 { 3507 wmi_buf_t buf; 3508 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 3509 int32_t cmd_len; 3510 uint64_t dma_addr; 3511 void *qdf_ctx = param->qdf_ctx; 3512 uint8_t *bufp; 3513 QDF_STATUS status = QDF_STATUS_SUCCESS; 3514 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 3515 mgmt_tx_dl_frm_len; 3516 3517 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 3518 WMI_TLV_HDR_SIZE + 3519 roundup(bufp_len, sizeof(uint32_t)); 3520 3521 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3522 if (!buf) 3523 return QDF_STATUS_E_NOMEM; 3524 3525 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 3526 bufp = (uint8_t *) cmd; 3527 WMITLV_SET_HDR(&cmd->tlv_header, 3528 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 3529 WMITLV_GET_STRUCT_TLVLEN 3530 (wmi_mgmt_tx_send_cmd_fixed_param)); 3531 3532 cmd->vdev_id = param->vdev_id; 3533 3534 cmd->desc_id = param->desc_id; 3535 cmd->chanfreq = param->chanfreq; 3536 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 3537 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3538 sizeof(uint32_t))); 3539 bufp += WMI_TLV_HDR_SIZE; 3540 qdf_mem_copy(bufp, param->pdata, bufp_len); 3541 3542 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 3543 QDF_DMA_TO_DEVICE); 3544 if (status != QDF_STATUS_SUCCESS) { 3545 WMI_LOGE("%s: wmi buf map failed", __func__); 3546 goto free_buf; 3547 } 3548 3549 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3550 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3551 #if defined(HTT_PADDR64) 3552 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3553 #endif 3554 cmd->frame_len = param->frm_len; 3555 cmd->buf_len = bufp_len; 3556 cmd->tx_params_valid = param->tx_params_valid; 3557 3558 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 3559 bufp, cmd->vdev_id, cmd->chanfreq); 3560 3561 bufp += roundup(bufp_len, sizeof(uint32_t)); 3562 if (param->tx_params_valid) { 3563 status = populate_tx_send_params(bufp, param->tx_param); 3564 if (status != QDF_STATUS_SUCCESS) { 3565 WMI_LOGE("%s: Populate TX send params failed", 3566 __func__); 3567 goto unmap_tx_frame; 3568 } 3569 cmd_len += sizeof(wmi_tx_send_params); 3570 } 3571 3572 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 3573 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3574 WMI_MGMT_TX_SEND_CMDID)) { 3575 WMI_LOGE("%s: Failed to send mgmt Tx", __func__); 3576 goto unmap_tx_frame; 3577 } 3578 return QDF_STATUS_SUCCESS; 3579 3580 unmap_tx_frame: 3581 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 3582 QDF_DMA_TO_DEVICE); 3583 free_buf: 3584 wmi_buf_free(buf); 3585 return QDF_STATUS_E_FAILURE; 3586 } 3587 #endif /* CONFIG_HL_SUPPORT */ 3588 3589 /** 3590 * send_offchan_data_tx_send_cmd_tlv() - Send off-chan tx data 3591 * @wmi_handle : handle to WMI. 3592 * @param : pointer to offchan data tx cmd parameter 3593 * 3594 * Return: QDF_STATUS_SUCCESS on success and error on failure. 3595 */ 3596 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 3597 struct wmi_offchan_data_tx_params *param) 3598 { 3599 wmi_buf_t buf; 3600 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 3601 int32_t cmd_len; 3602 uint64_t dma_addr; 3603 void *qdf_ctx = param->qdf_ctx; 3604 uint8_t *bufp; 3605 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 3606 param->frm_len : mgmt_tx_dl_frm_len; 3607 QDF_STATUS status = QDF_STATUS_SUCCESS; 3608 3609 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 3610 WMI_TLV_HDR_SIZE + 3611 roundup(bufp_len, sizeof(uint32_t)); 3612 3613 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 3614 if (!buf) 3615 return QDF_STATUS_E_NOMEM; 3616 3617 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 3618 bufp = (uint8_t *) cmd; 3619 WMITLV_SET_HDR(&cmd->tlv_header, 3620 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 3621 WMITLV_GET_STRUCT_TLVLEN 3622 (wmi_offchan_data_tx_send_cmd_fixed_param)); 3623 3624 cmd->vdev_id = param->vdev_id; 3625 3626 cmd->desc_id = param->desc_id; 3627 cmd->chanfreq = param->chanfreq; 3628 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 3629 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 3630 sizeof(uint32_t))); 3631 bufp += WMI_TLV_HDR_SIZE; 3632 qdf_mem_copy(bufp, param->pdata, bufp_len); 3633 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 3634 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 3635 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 3636 #if defined(HTT_PADDR64) 3637 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 3638 #endif 3639 cmd->frame_len = param->frm_len; 3640 cmd->buf_len = bufp_len; 3641 cmd->tx_params_valid = param->tx_params_valid; 3642 3643 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 3644 bufp, cmd->vdev_id, cmd->chanfreq); 3645 3646 bufp += roundup(bufp_len, sizeof(uint32_t)); 3647 if (param->tx_params_valid) { 3648 status = populate_tx_send_params(bufp, param->tx_param); 3649 if (status != QDF_STATUS_SUCCESS) { 3650 WMI_LOGE("%s: Populate TX send params failed", 3651 __func__); 3652 goto err1; 3653 } 3654 cmd_len += sizeof(wmi_tx_send_params); 3655 } 3656 3657 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 3658 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 3659 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 3660 WMI_LOGE("%s: Failed to offchan data Tx", __func__); 3661 goto err1; 3662 } 3663 3664 return QDF_STATUS_SUCCESS; 3665 3666 err1: 3667 wmi_buf_free(buf); 3668 return QDF_STATUS_E_FAILURE; 3669 } 3670 3671 /** 3672 * send_modem_power_state_cmd_tlv() - set modem power state to fw 3673 * @wmi_handle: wmi handle 3674 * @param_value: parameter value 3675 * 3676 * Return: QDF_STATUS_SUCCESS for success or error code 3677 */ 3678 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 3679 uint32_t param_value) 3680 { 3681 QDF_STATUS ret; 3682 wmi_modem_power_state_cmd_param *cmd; 3683 wmi_buf_t buf; 3684 uint16_t len = sizeof(*cmd); 3685 3686 buf = wmi_buf_alloc(wmi_handle, len); 3687 if (!buf) 3688 return QDF_STATUS_E_NOMEM; 3689 3690 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 3691 WMITLV_SET_HDR(&cmd->tlv_header, 3692 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 3693 WMITLV_GET_STRUCT_TLVLEN 3694 (wmi_modem_power_state_cmd_param)); 3695 cmd->modem_power_state = param_value; 3696 WMI_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, 3697 param_value); 3698 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 3699 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3700 WMI_MODEM_POWER_STATE_CMDID); 3701 if (QDF_IS_STATUS_ERROR(ret)) { 3702 WMI_LOGE("Failed to send notify cmd ret = %d", ret); 3703 wmi_buf_free(buf); 3704 } 3705 3706 return ret; 3707 } 3708 3709 /** 3710 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 3711 * @wmi_handle: wmi handle 3712 * @vdev_id: vdev id 3713 * @val: value 3714 * 3715 * Return: QDF_STATUS_SUCCESS for success or error code. 3716 */ 3717 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 3718 uint32_t vdev_id, uint8_t val) 3719 { 3720 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 3721 wmi_buf_t buf; 3722 int32_t len = sizeof(*cmd); 3723 3724 WMI_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 3725 3726 buf = wmi_buf_alloc(wmi_handle, len); 3727 if (!buf) 3728 return QDF_STATUS_E_NOMEM; 3729 3730 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 3731 WMITLV_SET_HDR(&cmd->tlv_header, 3732 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 3733 WMITLV_GET_STRUCT_TLVLEN 3734 (wmi_sta_powersave_mode_cmd_fixed_param)); 3735 cmd->vdev_id = vdev_id; 3736 if (val) 3737 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 3738 else 3739 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 3740 3741 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 3742 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3743 WMI_STA_POWERSAVE_MODE_CMDID)) { 3744 WMI_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", 3745 vdev_id, val); 3746 wmi_buf_free(buf); 3747 return QDF_STATUS_E_FAILURE; 3748 } 3749 return QDF_STATUS_SUCCESS; 3750 } 3751 3752 /** 3753 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 3754 * @wmi_handle: wmi handle 3755 * @vdev_id: vdev id 3756 * 3757 * Return: QDF_STATUS_SUCCESS for success or error code. 3758 */ 3759 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 3760 uint8_t val) 3761 { 3762 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 3763 wmi_buf_t buf; 3764 size_t len = sizeof(*cmd); 3765 3766 buf = wmi_buf_alloc(wmi_handle, len); 3767 if (!buf) 3768 return QDF_STATUS_E_NOMEM; 3769 3770 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 3771 WMITLV_SET_HDR(&cmd->tlv_header, 3772 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 3773 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 3774 3775 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 3776 WMI_IDLE_TRIGGER_MONITOR_OFF); 3777 3778 WMI_LOGD("val:%d", cmd->idle_trigger_monitor); 3779 3780 if (wmi_unified_cmd_send(wmi_handle, buf, len, 3781 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 3782 wmi_buf_free(buf); 3783 return QDF_STATUS_E_FAILURE; 3784 } 3785 return QDF_STATUS_SUCCESS; 3786 } 3787 3788 /** 3789 * send_set_mimops_cmd_tlv() - set MIMO powersave 3790 * @wmi_handle: wmi handle 3791 * @vdev_id: vdev id 3792 * @value: value 3793 * 3794 * Return: QDF_STATUS_SUCCESS for success or error code. 3795 */ 3796 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 3797 uint8_t vdev_id, int value) 3798 { 3799 QDF_STATUS ret; 3800 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 3801 wmi_buf_t buf; 3802 uint16_t len = sizeof(*cmd); 3803 3804 buf = wmi_buf_alloc(wmi_handle, len); 3805 if (!buf) 3806 return QDF_STATUS_E_NOMEM; 3807 3808 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 3809 WMITLV_SET_HDR(&cmd->tlv_header, 3810 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 3811 WMITLV_GET_STRUCT_TLVLEN 3812 (wmi_sta_smps_force_mode_cmd_fixed_param)); 3813 3814 cmd->vdev_id = vdev_id; 3815 3816 /* WMI_SMPS_FORCED_MODE values do not directly map 3817 * to SM power save values defined in the specification. 3818 * Make sure to send the right mapping. 3819 */ 3820 switch (value) { 3821 case 0: 3822 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 3823 break; 3824 case 1: 3825 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 3826 break; 3827 case 2: 3828 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 3829 break; 3830 case 3: 3831 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 3832 break; 3833 default: 3834 WMI_LOGE("%s:INVALID Mimo PS CONFIG", __func__); 3835 wmi_buf_free(buf); 3836 return QDF_STATUS_E_FAILURE; 3837 } 3838 3839 WMI_LOGD("Setting vdev %d value = %u", vdev_id, value); 3840 3841 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 3842 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3843 WMI_STA_SMPS_FORCE_MODE_CMDID); 3844 if (QDF_IS_STATUS_ERROR(ret)) { 3845 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3846 wmi_buf_free(buf); 3847 } 3848 3849 return ret; 3850 } 3851 3852 /** 3853 * send_set_smps_params_cmd_tlv() - set smps params 3854 * @wmi_handle: wmi handle 3855 * @vdev_id: vdev id 3856 * @value: value 3857 * 3858 * Return: QDF_STATUS_SUCCESS for success or error code. 3859 */ 3860 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 3861 int value) 3862 { 3863 QDF_STATUS ret; 3864 wmi_sta_smps_param_cmd_fixed_param *cmd; 3865 wmi_buf_t buf; 3866 uint16_t len = sizeof(*cmd); 3867 3868 buf = wmi_buf_alloc(wmi_handle, len); 3869 if (!buf) 3870 return QDF_STATUS_E_NOMEM; 3871 3872 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 3873 WMITLV_SET_HDR(&cmd->tlv_header, 3874 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 3875 WMITLV_GET_STRUCT_TLVLEN 3876 (wmi_sta_smps_param_cmd_fixed_param)); 3877 3878 cmd->vdev_id = vdev_id; 3879 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 3880 cmd->param = 3881 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 3882 3883 WMI_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 3884 cmd->param); 3885 3886 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 3887 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3888 WMI_STA_SMPS_PARAM_CMDID); 3889 if (QDF_IS_STATUS_ERROR(ret)) { 3890 WMI_LOGE("Failed to send set Mimo PS ret = %d", ret); 3891 wmi_buf_free(buf); 3892 } 3893 3894 return ret; 3895 } 3896 3897 /** 3898 * send_get_temperature_cmd_tlv() - get pdev temperature req 3899 * @wmi_handle: wmi handle 3900 * 3901 * Return: QDF_STATUS_SUCCESS for success or error code. 3902 */ 3903 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 3904 { 3905 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 3906 wmi_buf_t wmi_buf; 3907 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 3908 uint8_t *buf_ptr; 3909 3910 if (!wmi_handle) { 3911 WMI_LOGE(FL("WMI is closed, can not issue cmd")); 3912 return QDF_STATUS_E_INVAL; 3913 } 3914 3915 wmi_buf = wmi_buf_alloc(wmi_handle, len); 3916 if (!wmi_buf) 3917 return QDF_STATUS_E_NOMEM; 3918 3919 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3920 3921 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 3922 WMITLV_SET_HDR(&cmd->tlv_header, 3923 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 3924 WMITLV_GET_STRUCT_TLVLEN 3925 (wmi_pdev_get_temperature_cmd_fixed_param)); 3926 3927 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 3928 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 3929 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 3930 WMI_LOGE(FL("failed to send get temperature command")); 3931 wmi_buf_free(wmi_buf); 3932 return QDF_STATUS_E_FAILURE; 3933 } 3934 3935 return QDF_STATUS_SUCCESS; 3936 } 3937 3938 /** 3939 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 3940 * @wmi_handle: wmi handle 3941 * @vdevid: vdev id 3942 * @peer_addr: peer mac address 3943 * @auto_triggerparam: auto trigger parameters 3944 * @num_ac: number of access category 3945 * 3946 * This function sets the trigger 3947 * uapsd params such as service interval, delay interval 3948 * and suspend interval which will be used by the firmware 3949 * to send trigger frames periodically when there is no 3950 * traffic on the transmit side. 3951 * 3952 * Return: QDF_STATUS_SUCCESS for success or error code. 3953 */ 3954 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 3955 struct sta_uapsd_trig_params *param) 3956 { 3957 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 3958 QDF_STATUS ret; 3959 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 3960 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 3961 uint32_t i; 3962 wmi_buf_t buf; 3963 uint8_t *buf_ptr; 3964 struct sta_uapsd_params *uapsd_param; 3965 wmi_sta_uapsd_auto_trig_param *trig_param; 3966 3967 buf = wmi_buf_alloc(wmi_handle, cmd_len); 3968 if (!buf) 3969 return QDF_STATUS_E_NOMEM; 3970 3971 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3972 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 3973 WMITLV_SET_HDR(&cmd->tlv_header, 3974 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 3975 WMITLV_GET_STRUCT_TLVLEN 3976 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 3977 cmd->vdev_id = param->vdevid; 3978 cmd->num_ac = param->num_ac; 3979 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 3980 3981 /* TLV indicating array of structures to follow */ 3982 buf_ptr += sizeof(*cmd); 3983 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 3984 3985 buf_ptr += WMI_TLV_HDR_SIZE; 3986 3987 /* 3988 * Update tag and length for uapsd auto trigger params (this will take 3989 * care of updating tag and length if it is not pre-filled by caller). 3990 */ 3991 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 3992 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 3993 for (i = 0; i < param->num_ac; i++) { 3994 WMITLV_SET_HDR((buf_ptr + 3995 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 3996 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 3997 WMITLV_GET_STRUCT_TLVLEN 3998 (wmi_sta_uapsd_auto_trig_param)); 3999 trig_param->wmm_ac = uapsd_param->wmm_ac; 4000 trig_param->user_priority = uapsd_param->user_priority; 4001 trig_param->service_interval = uapsd_param->service_interval; 4002 trig_param->suspend_interval = uapsd_param->suspend_interval; 4003 trig_param->delay_interval = uapsd_param->delay_interval; 4004 trig_param++; 4005 uapsd_param++; 4006 } 4007 4008 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 4009 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4010 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 4011 if (QDF_IS_STATUS_ERROR(ret)) { 4012 WMI_LOGE("Failed to send set uapsd param ret = %d", ret); 4013 wmi_buf_free(buf); 4014 } 4015 4016 return ret; 4017 } 4018 4019 /** 4020 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 4021 * @wmi_handle: Pointer to wmi handle 4022 * @thermal_info: Thermal command information 4023 * 4024 * This function sends the thermal management command 4025 * to the firmware 4026 * 4027 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4028 */ 4029 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4030 struct thermal_cmd_params *thermal_info) 4031 { 4032 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 4033 wmi_buf_t buf = NULL; 4034 QDF_STATUS status; 4035 uint32_t len = 0; 4036 4037 len = sizeof(*cmd); 4038 4039 buf = wmi_buf_alloc(wmi_handle, len); 4040 if (!buf) 4041 return QDF_STATUS_E_FAILURE; 4042 4043 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 4044 4045 WMITLV_SET_HDR(&cmd->tlv_header, 4046 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 4047 WMITLV_GET_STRUCT_TLVLEN 4048 (wmi_thermal_mgmt_cmd_fixed_param)); 4049 4050 cmd->lower_thresh_degreeC = thermal_info->min_temp; 4051 cmd->upper_thresh_degreeC = thermal_info->max_temp; 4052 cmd->enable = thermal_info->thermal_enable; 4053 4054 WMI_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", 4055 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); 4056 4057 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 4058 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4059 WMI_THERMAL_MGMT_CMDID); 4060 if (QDF_IS_STATUS_ERROR(status)) { 4061 wmi_buf_free(buf); 4062 WMI_LOGE("%s:Failed to send thermal mgmt command", __func__); 4063 } 4064 4065 return status; 4066 } 4067 4068 /** 4069 * send_lro_config_cmd_tlv() - process the LRO config command 4070 * @wmi_handle: Pointer to WMI handle 4071 * @wmi_lro_cmd: Pointer to LRO configuration parameters 4072 * 4073 * This function sends down the LRO configuration parameters to 4074 * the firmware to enable LRO, sets the TCP flags and sets the 4075 * seed values for the toeplitz hash generation 4076 * 4077 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4078 */ 4079 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 4080 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 4081 { 4082 wmi_lro_info_cmd_fixed_param *cmd; 4083 wmi_buf_t buf; 4084 QDF_STATUS status; 4085 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 4086 4087 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 4088 if (!buf) 4089 return QDF_STATUS_E_FAILURE; 4090 4091 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 4092 4093 WMITLV_SET_HDR(&cmd->tlv_header, 4094 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 4095 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 4096 4097 cmd->lro_enable = wmi_lro_cmd->lro_enable; 4098 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 4099 wmi_lro_cmd->tcp_flag); 4100 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 4101 wmi_lro_cmd->tcp_flag_mask); 4102 cmd->toeplitz_hash_ipv4_0_3 = 4103 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 4104 cmd->toeplitz_hash_ipv4_4_7 = 4105 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 4106 cmd->toeplitz_hash_ipv4_8_11 = 4107 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 4108 cmd->toeplitz_hash_ipv4_12_15 = 4109 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 4110 cmd->toeplitz_hash_ipv4_16 = 4111 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 4112 4113 cmd->toeplitz_hash_ipv6_0_3 = 4114 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 4115 cmd->toeplitz_hash_ipv6_4_7 = 4116 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 4117 cmd->toeplitz_hash_ipv6_8_11 = 4118 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 4119 cmd->toeplitz_hash_ipv6_12_15 = 4120 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 4121 cmd->toeplitz_hash_ipv6_16_19 = 4122 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 4123 cmd->toeplitz_hash_ipv6_20_23 = 4124 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 4125 cmd->toeplitz_hash_ipv6_24_27 = 4126 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 4127 cmd->toeplitz_hash_ipv6_28_31 = 4128 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 4129 cmd->toeplitz_hash_ipv6_32_35 = 4130 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 4131 cmd->toeplitz_hash_ipv6_36_39 = 4132 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 4133 cmd->toeplitz_hash_ipv6_40 = 4134 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 4135 4136 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4137 wmi_handle, 4138 pdev_id); 4139 WMI_LOGD("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 4140 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 4141 4142 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 4143 status = wmi_unified_cmd_send(wmi_handle, buf, 4144 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 4145 if (QDF_IS_STATUS_ERROR(status)) { 4146 wmi_buf_free(buf); 4147 WMI_LOGE("%s:Failed to send WMI_LRO_CONFIG_CMDID", __func__); 4148 } 4149 4150 return status; 4151 } 4152 4153 /** 4154 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 4155 * @wmi_handle: Pointer to wmi handle 4156 * @rate_report_params: Pointer to peer rate report parameters 4157 * 4158 * 4159 * Return: QDF_STATUS_SUCCESS for success otherwise failure 4160 */ 4161 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 4162 struct wmi_peer_rate_report_params *rate_report_params) 4163 { 4164 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 4165 wmi_buf_t buf = NULL; 4166 QDF_STATUS status = 0; 4167 uint32_t len = 0; 4168 uint32_t i, j; 4169 4170 len = sizeof(*cmd); 4171 4172 buf = wmi_buf_alloc(wmi_handle, len); 4173 if (!buf) 4174 return QDF_STATUS_E_FAILURE; 4175 4176 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 4177 wmi_buf_data(buf); 4178 4179 WMITLV_SET_HDR( 4180 &cmd->tlv_header, 4181 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 4182 WMITLV_GET_STRUCT_TLVLEN( 4183 wmi_peer_set_rate_report_condition_fixed_param)); 4184 4185 cmd->enable_rate_report = rate_report_params->rate_report_enable; 4186 cmd->report_backoff_time = rate_report_params->backoff_time; 4187 cmd->report_timer_period = rate_report_params->timer_period; 4188 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 4189 cmd->cond_per_phy[i].val_cond_flags = 4190 rate_report_params->report_per_phy[i].cond_flags; 4191 cmd->cond_per_phy[i].rate_delta.min_delta = 4192 rate_report_params->report_per_phy[i].delta.delta_min; 4193 cmd->cond_per_phy[i].rate_delta.percentage = 4194 rate_report_params->report_per_phy[i].delta.percent; 4195 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 4196 cmd->cond_per_phy[i].rate_threshold[j] = 4197 rate_report_params->report_per_phy[i]. 4198 report_rate_threshold[j]; 4199 } 4200 } 4201 4202 WMI_LOGE("%s enable %d backoff_time %d period %d", __func__, 4203 cmd->enable_rate_report, 4204 cmd->report_backoff_time, cmd->report_timer_period); 4205 4206 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 4207 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4208 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 4209 if (QDF_IS_STATUS_ERROR(status)) { 4210 wmi_buf_free(buf); 4211 WMI_LOGE("%s:Failed to send peer_set_report_cond command", 4212 __func__); 4213 } 4214 return status; 4215 } 4216 4217 /** 4218 * send_process_update_edca_param_cmd_tlv() - update EDCA params 4219 * @wmi_handle: wmi handle 4220 * @vdev_id: vdev id. 4221 * @wmm_vparams: edca parameters 4222 * 4223 * This function updates EDCA parameters to the target 4224 * 4225 * Return: CDF Status 4226 */ 4227 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 4228 uint8_t vdev_id, bool mu_edca_param, 4229 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 4230 { 4231 uint8_t *buf_ptr; 4232 wmi_buf_t buf; 4233 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 4234 wmi_wmm_vparams *wmm_param; 4235 struct wmi_host_wme_vparams *twmm_param; 4236 int len = sizeof(*cmd); 4237 int ac; 4238 4239 buf = wmi_buf_alloc(wmi_handle, len); 4240 4241 if (!buf) 4242 return QDF_STATUS_E_NOMEM; 4243 4244 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4245 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 4246 WMITLV_SET_HDR(&cmd->tlv_header, 4247 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4248 WMITLV_GET_STRUCT_TLVLEN 4249 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 4250 cmd->vdev_id = vdev_id; 4251 cmd->wmm_param_type = mu_edca_param; 4252 4253 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 4254 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 4255 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 4256 WMITLV_SET_HDR(&wmm_param->tlv_header, 4257 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 4258 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 4259 wmm_param->cwmin = twmm_param->cwmin; 4260 wmm_param->cwmax = twmm_param->cwmax; 4261 wmm_param->aifs = twmm_param->aifs; 4262 if (mu_edca_param) 4263 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 4264 else 4265 wmm_param->txoplimit = twmm_param->txoplimit; 4266 wmm_param->acm = twmm_param->acm; 4267 wmm_param->no_ack = twmm_param->noackpolicy; 4268 } 4269 4270 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 4271 if (wmi_unified_cmd_send(wmi_handle, buf, len, 4272 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 4273 goto fail; 4274 4275 return QDF_STATUS_SUCCESS; 4276 4277 fail: 4278 wmi_buf_free(buf); 4279 WMI_LOGE("%s: Failed to set WMM Paremeters", __func__); 4280 return QDF_STATUS_E_FAILURE; 4281 } 4282 4283 /** 4284 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 4285 * @wmi_handle: wmi handle 4286 * @vdev_id: vdev id 4287 * @probe_rsp_info: probe response info 4288 * 4289 * Return: QDF_STATUS_SUCCESS for success or error code 4290 */ 4291 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 4292 uint8_t vdev_id, 4293 struct wmi_probe_resp_params *probe_rsp_info) 4294 { 4295 wmi_prb_tmpl_cmd_fixed_param *cmd; 4296 wmi_bcn_prb_info *bcn_prb_info; 4297 wmi_buf_t wmi_buf; 4298 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 4299 uint8_t *buf_ptr; 4300 QDF_STATUS ret; 4301 4302 WMI_LOGD(FL("Send probe response template for vdev %d"), vdev_id); 4303 4304 tmpl_len = probe_rsp_info->prb_rsp_template_len; 4305 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 4306 4307 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 4308 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 4309 tmpl_len_aligned; 4310 4311 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 4312 WMI_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), 4313 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 4314 return QDF_STATUS_E_INVAL; 4315 } 4316 4317 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4318 if (!wmi_buf) 4319 return QDF_STATUS_E_NOMEM; 4320 4321 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4322 4323 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 4324 WMITLV_SET_HDR(&cmd->tlv_header, 4325 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 4326 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 4327 cmd->vdev_id = vdev_id; 4328 cmd->buf_len = tmpl_len; 4329 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 4330 4331 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 4332 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 4333 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 4334 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 4335 bcn_prb_info->caps = 0; 4336 bcn_prb_info->erp = 0; 4337 buf_ptr += sizeof(wmi_bcn_prb_info); 4338 4339 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 4340 buf_ptr += WMI_TLV_HDR_SIZE; 4341 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 4342 4343 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 4344 ret = wmi_unified_cmd_send(wmi_handle, 4345 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 4346 if (QDF_IS_STATUS_ERROR(ret)) { 4347 WMI_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); 4348 wmi_buf_free(wmi_buf); 4349 } 4350 4351 return ret; 4352 } 4353 4354 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4355 #define WPI_IV_LEN 16 4356 4357 /** 4358 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 4359 * 4360 * @dest_tx: destination address of tsc key counter 4361 * @src_tx: source address of tsc key counter 4362 * @dest_rx: destination address of rsc key counter 4363 * @src_rx: source address of rsc key counter 4364 * 4365 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 4366 * 4367 * Return: None 4368 * 4369 */ 4370 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4371 uint8_t *dest_rx, uint8_t *src_rx) 4372 { 4373 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 4374 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 4375 } 4376 #else 4377 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 4378 uint8_t *dest_rx, uint8_t *src_rx) 4379 { 4380 return; 4381 } 4382 #endif 4383 4384 /** 4385 * send_setup_install_key_cmd_tlv() - set key parameters 4386 * @wmi_handle: wmi handle 4387 * @key_params: key parameters 4388 * 4389 * This function fills structure from information 4390 * passed in key_params. 4391 * 4392 * Return: QDF_STATUS_SUCCESS - success 4393 * QDF_STATUS_E_FAILURE - failure 4394 * QDF_STATUS_E_NOMEM - not able to allocate buffer 4395 */ 4396 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 4397 struct set_key_params *key_params) 4398 { 4399 wmi_vdev_install_key_cmd_fixed_param *cmd; 4400 wmi_buf_t buf; 4401 uint8_t *buf_ptr; 4402 uint32_t len; 4403 uint8_t *key_data; 4404 QDF_STATUS status; 4405 4406 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 4407 WMI_TLV_HDR_SIZE; 4408 4409 buf = wmi_buf_alloc(wmi_handle, len); 4410 if (!buf) 4411 return QDF_STATUS_E_NOMEM; 4412 4413 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4414 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 4415 WMITLV_SET_HDR(&cmd->tlv_header, 4416 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 4417 WMITLV_GET_STRUCT_TLVLEN 4418 (wmi_vdev_install_key_cmd_fixed_param)); 4419 cmd->vdev_id = key_params->vdev_id; 4420 cmd->key_ix = key_params->key_idx; 4421 if (key_params->group_key_idx) { 4422 cmd->is_group_key_ix_valid = 1; 4423 cmd->group_key_ix = key_params->group_key_idx; 4424 } 4425 4426 4427 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 4428 cmd->key_flags |= key_params->key_flags; 4429 cmd->key_cipher = key_params->key_cipher; 4430 if ((key_params->key_txmic_len) && 4431 (key_params->key_rxmic_len)) { 4432 cmd->key_txmic_len = key_params->key_txmic_len; 4433 cmd->key_rxmic_len = key_params->key_rxmic_len; 4434 } 4435 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 4436 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 4437 key_params->tx_iv, 4438 cmd->wpi_key_rsc_counter, 4439 key_params->rx_iv); 4440 #endif 4441 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 4442 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 4443 roundup(key_params->key_len, sizeof(uint32_t))); 4444 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4445 qdf_mem_copy((void *)key_data, 4446 (const void *)key_params->key_data, key_params->key_len); 4447 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr, 4448 sizeof(wmi_key_seq_counter)); 4449 cmd->key_len = key_params->key_len; 4450 4451 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 4452 sizeof(wmi_key_seq_counter)); 4453 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 4454 status = wmi_unified_cmd_send(wmi_handle, buf, len, 4455 WMI_VDEV_INSTALL_KEY_CMDID); 4456 if (QDF_IS_STATUS_ERROR(status)) { 4457 qdf_mem_zero(wmi_buf_data(buf), len); 4458 wmi_buf_free(buf); 4459 } 4460 return status; 4461 } 4462 4463 /** 4464 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 4465 * @wmi_handle: wmi handle 4466 * @vdev_id: vdev id 4467 * @p2p_ie: p2p IE 4468 * 4469 * Return: QDF_STATUS_SUCCESS for success or error code 4470 */ 4471 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 4472 uint32_t vdev_id, uint8_t *p2p_ie) 4473 { 4474 QDF_STATUS ret; 4475 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 4476 wmi_buf_t wmi_buf; 4477 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 4478 uint8_t *buf_ptr; 4479 4480 ie_len = (uint32_t) (p2p_ie[1] + 2); 4481 4482 /* More than one P2P IE may be included in a single frame. 4483 If multiple P2P IEs are present, the complete P2P attribute 4484 data consists of the concatenation of the P2P Attribute 4485 fields of the P2P IEs. The P2P Attributes field of each 4486 P2P IE may be any length up to the maximum (251 octets). 4487 In this case host sends one P2P IE to firmware so the length 4488 should not exceed more than 251 bytes 4489 */ 4490 if (ie_len > 251) { 4491 WMI_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); 4492 return QDF_STATUS_E_INVAL; 4493 } 4494 4495 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 4496 4497 wmi_buf_len = 4498 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 4499 WMI_TLV_HDR_SIZE; 4500 4501 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 4502 if (!wmi_buf) 4503 return QDF_STATUS_E_NOMEM; 4504 4505 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4506 4507 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 4508 WMITLV_SET_HDR(&cmd->tlv_header, 4509 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 4510 WMITLV_GET_STRUCT_TLVLEN 4511 (wmi_p2p_go_set_beacon_ie_fixed_param)); 4512 cmd->vdev_id = vdev_id; 4513 cmd->ie_buf_len = ie_len; 4514 4515 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 4516 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 4517 buf_ptr += WMI_TLV_HDR_SIZE; 4518 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 4519 4520 WMI_LOGD("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); 4521 4522 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 4523 ret = wmi_unified_cmd_send(wmi_handle, 4524 wmi_buf, wmi_buf_len, 4525 WMI_P2P_GO_SET_BEACON_IE); 4526 if (QDF_IS_STATUS_ERROR(ret)) { 4527 WMI_LOGE("Failed to send bcn tmpl: %d", ret); 4528 wmi_buf_free(wmi_buf); 4529 } 4530 4531 WMI_LOGD("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); 4532 return ret; 4533 } 4534 4535 /** 4536 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 4537 * @wmi_handle: wmi handle 4538 * @psetoui: OUI parameters 4539 * 4540 * set scan probe OUI parameters in firmware 4541 * 4542 * Return: CDF status 4543 */ 4544 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 4545 struct scan_mac_oui *psetoui) 4546 { 4547 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 4548 wmi_buf_t wmi_buf; 4549 uint32_t len; 4550 uint8_t *buf_ptr; 4551 uint32_t *oui_buf; 4552 struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist; 4553 4554 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 4555 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); 4556 4557 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4558 if (!wmi_buf) 4559 return QDF_STATUS_E_NOMEM; 4560 4561 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4562 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 4563 WMITLV_SET_HDR(&cmd->tlv_header, 4564 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 4565 WMITLV_GET_STRUCT_TLVLEN 4566 (wmi_scan_prob_req_oui_cmd_fixed_param)); 4567 4568 oui_buf = &cmd->prob_req_oui; 4569 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 4570 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 4571 | psetoui->oui[2]; 4572 WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, 4573 cmd->prob_req_oui); 4574 4575 cmd->vdev_id = psetoui->vdev_id; 4576 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 4577 if (psetoui->enb_probe_req_sno_randomization) 4578 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 4579 4580 if (ie_whitelist->white_list) { 4581 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4582 &cmd->num_vendor_oui, 4583 ie_whitelist); 4584 cmd->flags |= 4585 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4586 } 4587 4588 buf_ptr += sizeof(*cmd); 4589 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4590 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4591 buf_ptr += WMI_TLV_HDR_SIZE; 4592 4593 if (cmd->num_vendor_oui != 0) { 4594 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4595 ie_whitelist->voui); 4596 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4597 } 4598 4599 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 4600 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4601 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 4602 WMI_LOGE("%s: failed to send command", __func__); 4603 wmi_buf_free(wmi_buf); 4604 return QDF_STATUS_E_FAILURE; 4605 } 4606 return QDF_STATUS_SUCCESS; 4607 } 4608 4609 #ifdef IPA_OFFLOAD 4610 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 4611 * @wmi_handle: wmi handle 4612 * @ipa_offload: ipa offload control parameter 4613 * 4614 * Returns: 0 on success, error number otherwise 4615 */ 4616 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 4617 struct ipa_uc_offload_control_params *ipa_offload) 4618 { 4619 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 4620 wmi_buf_t wmi_buf; 4621 uint32_t len; 4622 u_int8_t *buf_ptr; 4623 4624 len = sizeof(*cmd); 4625 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4626 if (!wmi_buf) 4627 return QDF_STATUS_E_NOMEM; 4628 4629 WMI_LOGD("%s: offload_type=%d, enable=%d", __func__, 4630 ipa_offload->offload_type, ipa_offload->enable); 4631 4632 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 4633 4634 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 4635 WMITLV_SET_HDR(&cmd->tlv_header, 4636 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 4637 WMITLV_GET_STRUCT_TLVLEN( 4638 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 4639 4640 cmd->offload_type = ipa_offload->offload_type; 4641 cmd->vdev_id = ipa_offload->vdev_id; 4642 cmd->enable = ipa_offload->enable; 4643 4644 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 4645 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 4646 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 4647 WMI_LOGE("%s: failed to command", __func__); 4648 wmi_buf_free(wmi_buf); 4649 return QDF_STATUS_E_FAILURE; 4650 } 4651 4652 return QDF_STATUS_SUCCESS; 4653 } 4654 #endif 4655 4656 /** 4657 * send_pno_stop_cmd_tlv() - PNO stop request 4658 * @wmi_handle: wmi handle 4659 * @vdev_id: vdev id 4660 * 4661 * This function request FW to stop ongoing PNO operation. 4662 * 4663 * Return: CDF status 4664 */ 4665 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 4666 { 4667 wmi_nlo_config_cmd_fixed_param *cmd; 4668 int32_t len = sizeof(*cmd); 4669 wmi_buf_t buf; 4670 uint8_t *buf_ptr; 4671 int ret; 4672 4673 /* 4674 * TLV place holder for array of structures nlo_configured_parameters 4675 * TLV place holder for array of uint32_t channel_list 4676 * TLV place holder for chnl prediction cfg 4677 */ 4678 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4679 buf = wmi_buf_alloc(wmi_handle, len); 4680 if (!buf) 4681 return QDF_STATUS_E_NOMEM; 4682 4683 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4684 buf_ptr = (uint8_t *) cmd; 4685 4686 WMITLV_SET_HDR(&cmd->tlv_header, 4687 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4688 WMITLV_GET_STRUCT_TLVLEN 4689 (wmi_nlo_config_cmd_fixed_param)); 4690 4691 cmd->vdev_id = vdev_id; 4692 cmd->flags = WMI_NLO_CONFIG_STOP; 4693 buf_ptr += sizeof(*cmd); 4694 4695 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4696 buf_ptr += WMI_TLV_HDR_SIZE; 4697 4698 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 4699 buf_ptr += WMI_TLV_HDR_SIZE; 4700 4701 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 4702 buf_ptr += WMI_TLV_HDR_SIZE; 4703 4704 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 4705 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4706 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 4707 if (ret) { 4708 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 4709 wmi_buf_free(buf); 4710 return QDF_STATUS_E_FAILURE; 4711 } 4712 4713 return QDF_STATUS_SUCCESS; 4714 } 4715 4716 /** 4717 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 4718 * @buf_ptr: Buffer passed by upper layers 4719 * @pno: Buffer to be sent to the firmware 4720 * 4721 * Copy the PNO Channel prediction configuration parameters 4722 * passed by the upper layers to a WMI format TLV and send it 4723 * down to the firmware. 4724 * 4725 * Return: None 4726 */ 4727 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 4728 struct pno_scan_req_params *pno) 4729 { 4730 nlo_channel_prediction_cfg *channel_prediction_cfg = 4731 (nlo_channel_prediction_cfg *) buf_ptr; 4732 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 4733 WMITLV_TAG_ARRAY_BYTE, 4734 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 4735 #ifdef FEATURE_WLAN_SCAN_PNO 4736 channel_prediction_cfg->enable = pno->pno_channel_prediction; 4737 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 4738 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 4739 channel_prediction_cfg->full_scan_period_ms = 4740 pno->channel_prediction_full_scan; 4741 #endif 4742 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4743 WMI_LOGD("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 4744 channel_prediction_cfg->enable, 4745 channel_prediction_cfg->top_k_num, 4746 channel_prediction_cfg->stationary_threshold, 4747 channel_prediction_cfg->full_scan_period_ms); 4748 } 4749 4750 /** 4751 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 4752 * @wmi_handle: wmi handle 4753 * @params: configuration parameters 4754 * 4755 * Return: QDF_STATUS 4756 */ 4757 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 4758 struct nlo_mawc_params *params) 4759 { 4760 wmi_buf_t buf = NULL; 4761 QDF_STATUS status; 4762 int len; 4763 uint8_t *buf_ptr; 4764 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 4765 4766 len = sizeof(*wmi_nlo_mawc_params); 4767 buf = wmi_buf_alloc(wmi_handle, len); 4768 if (!buf) 4769 return QDF_STATUS_E_NOMEM; 4770 4771 buf_ptr = (uint8_t *) wmi_buf_data(buf); 4772 wmi_nlo_mawc_params = 4773 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 4774 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 4775 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 4776 WMITLV_GET_STRUCT_TLVLEN 4777 (wmi_nlo_configure_mawc_cmd_fixed_param)); 4778 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 4779 if (params->enable) 4780 wmi_nlo_mawc_params->enable = 1; 4781 else 4782 wmi_nlo_mawc_params->enable = 0; 4783 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 4784 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 4785 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 4786 WMI_LOGD(FL("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d"), 4787 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 4788 wmi_nlo_mawc_params->exp_backoff_ratio, 4789 wmi_nlo_mawc_params->init_scan_interval, 4790 wmi_nlo_mawc_params->max_scan_interval); 4791 4792 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 4793 status = wmi_unified_cmd_send(wmi_handle, buf, 4794 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 4795 if (QDF_IS_STATUS_ERROR(status)) { 4796 WMI_LOGE("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 4797 status); 4798 wmi_buf_free(buf); 4799 return QDF_STATUS_E_FAILURE; 4800 } 4801 4802 return QDF_STATUS_SUCCESS; 4803 } 4804 4805 /** 4806 * send_pno_start_cmd_tlv() - PNO start request 4807 * @wmi_handle: wmi handle 4808 * @pno: PNO request 4809 * 4810 * This function request FW to start PNO request. 4811 * Request: CDF status 4812 */ 4813 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 4814 struct pno_scan_req_params *pno) 4815 { 4816 wmi_nlo_config_cmd_fixed_param *cmd; 4817 nlo_configured_parameters *nlo_list; 4818 uint32_t *channel_list; 4819 int32_t len; 4820 wmi_buf_t buf; 4821 uint8_t *buf_ptr; 4822 uint8_t i; 4823 int ret; 4824 struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist; 4825 connected_nlo_rssi_params *nlo_relative_rssi; 4826 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 4827 4828 /* 4829 * TLV place holder for array nlo_configured_parameters(nlo_list) 4830 * TLV place holder for array of uint32_t channel_list 4831 * TLV place holder for chnnl prediction cfg 4832 * TLV place holder for array of wmi_vendor_oui 4833 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 4834 */ 4835 len = sizeof(*cmd) + 4836 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 4837 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 4838 4839 len += sizeof(uint32_t) * pno->networks_list[0].channel_cnt; 4840 len += sizeof(nlo_configured_parameters) * 4841 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4842 len += sizeof(nlo_channel_prediction_cfg); 4843 len += sizeof(enlo_candidate_score_params); 4844 len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui; 4845 len += sizeof(connected_nlo_rssi_params); 4846 len += sizeof(connected_nlo_bss_band_rssi_pref); 4847 4848 buf = wmi_buf_alloc(wmi_handle, len); 4849 if (!buf) 4850 return QDF_STATUS_E_NOMEM; 4851 4852 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 4853 4854 buf_ptr = (uint8_t *) cmd; 4855 WMITLV_SET_HDR(&cmd->tlv_header, 4856 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 4857 WMITLV_GET_STRUCT_TLVLEN 4858 (wmi_nlo_config_cmd_fixed_param)); 4859 cmd->vdev_id = pno->vdev_id; 4860 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 4861 4862 #ifdef FEATURE_WLAN_SCAN_PNO 4863 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 4864 pno->adaptive_dwell_mode); 4865 #endif 4866 /* Current FW does not support min-max range for dwell time */ 4867 cmd->active_dwell_time = pno->active_dwell_time; 4868 cmd->passive_dwell_time = pno->passive_dwell_time; 4869 4870 if (pno->do_passive_scan) 4871 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 4872 /* Copy scan interval */ 4873 cmd->fast_scan_period = pno->fast_scan_period; 4874 cmd->slow_scan_period = pno->slow_scan_period; 4875 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 4876 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 4877 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 4878 4879 /* mac randomization attributes */ 4880 if (pno->scan_random.randomize) { 4881 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 4882 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 4883 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 4884 pno->scan_random.mac_mask, 4885 &cmd->mac_addr, 4886 &cmd->mac_mask); 4887 } 4888 4889 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 4890 4891 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 4892 4893 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4894 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 4895 buf_ptr += WMI_TLV_HDR_SIZE; 4896 4897 nlo_list = (nlo_configured_parameters *) buf_ptr; 4898 for (i = 0; i < cmd->no_of_ssids; i++) { 4899 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 4900 WMITLV_TAG_ARRAY_BYTE, 4901 WMITLV_GET_STRUCT_TLVLEN 4902 (nlo_configured_parameters)); 4903 /* Copy ssid and it's length */ 4904 nlo_list[i].ssid.valid = true; 4905 nlo_list[i].ssid.ssid.ssid_len = 4906 pno->networks_list[i].ssid.length; 4907 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 4908 pno->networks_list[i].ssid.ssid, 4909 nlo_list[i].ssid.ssid.ssid_len); 4910 4911 /* Copy rssi threshold */ 4912 if (pno->networks_list[i].rssi_thresh && 4913 pno->networks_list[i].rssi_thresh > 4914 WMI_RSSI_THOLD_DEFAULT) { 4915 nlo_list[i].rssi_cond.valid = true; 4916 nlo_list[i].rssi_cond.rssi = 4917 pno->networks_list[i].rssi_thresh; 4918 } 4919 nlo_list[i].bcast_nw_type.valid = true; 4920 nlo_list[i].bcast_nw_type.bcast_nw_type = 4921 pno->networks_list[i].bc_new_type; 4922 } 4923 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 4924 4925 /* Copy channel info */ 4926 cmd->num_of_channels = pno->networks_list[0].channel_cnt; 4927 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 4928 (cmd->num_of_channels * sizeof(uint32_t))); 4929 buf_ptr += WMI_TLV_HDR_SIZE; 4930 4931 channel_list = (uint32_t *) buf_ptr; 4932 for (i = 0; i < cmd->num_of_channels; i++) { 4933 channel_list[i] = pno->networks_list[0].channels[i]; 4934 4935 if (channel_list[i] < WMI_NLO_FREQ_THRESH) 4936 channel_list[i] = 4937 wlan_chan_to_freq(pno-> 4938 networks_list[0].channels[i]); 4939 } 4940 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 4941 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4942 sizeof(nlo_channel_prediction_cfg)); 4943 buf_ptr += WMI_TLV_HDR_SIZE; 4944 wmi_set_pno_channel_prediction(buf_ptr, pno); 4945 buf_ptr += sizeof(nlo_channel_prediction_cfg); 4946 /** TODO: Discrete firmware doesn't have command/option to configure 4947 * App IE which comes from wpa_supplicant as of part PNO start request. 4948 */ 4949 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 4950 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 4951 buf_ptr += sizeof(enlo_candidate_score_params); 4952 4953 if (ie_whitelist->white_list) { 4954 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 4955 wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap, 4956 &cmd->num_vendor_oui, 4957 ie_whitelist); 4958 } 4959 4960 /* ie white list */ 4961 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4962 ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4963 buf_ptr += WMI_TLV_HDR_SIZE; 4964 if (cmd->num_vendor_oui != 0) { 4965 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4966 ie_whitelist->voui); 4967 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4968 } 4969 4970 if (pno->relative_rssi_set) 4971 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 4972 4973 /* 4974 * Firmware calculation using connected PNO params: 4975 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 4976 * deduction of rssi_pref for chosen band_pref and 4977 * addition of rssi_pref for remaining bands (other than chosen band). 4978 */ 4979 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 4980 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 4981 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 4982 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 4983 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 4984 buf_ptr += sizeof(*nlo_relative_rssi); 4985 4986 /* 4987 * As of now Kernel and Host supports one band and rssi preference. 4988 * Firmware supports array of band and rssi preferences 4989 */ 4990 cmd->num_cnlo_band_pref = 1; 4991 WMITLV_SET_HDR(buf_ptr, 4992 WMITLV_TAG_ARRAY_STRUC, 4993 cmd->num_cnlo_band_pref * 4994 sizeof(connected_nlo_bss_band_rssi_pref)); 4995 buf_ptr += WMI_TLV_HDR_SIZE; 4996 4997 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 4998 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 4999 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 5000 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 5001 WMITLV_GET_STRUCT_TLVLEN( 5002 connected_nlo_bss_band_rssi_pref)); 5003 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 5004 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 5005 } 5006 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 5007 5008 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 5009 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5010 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 5011 if (ret) { 5012 WMI_LOGE("%s: Failed to send nlo wmi cmd", __func__); 5013 wmi_buf_free(buf); 5014 return QDF_STATUS_E_FAILURE; 5015 } 5016 5017 return QDF_STATUS_SUCCESS; 5018 } 5019 5020 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 5021 /** 5022 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 5023 * @wmi_handle: wmi handle 5024 * @clear_req: ll stats clear request command params 5025 * 5026 * Return: QDF_STATUS_SUCCESS for success or error code 5027 */ 5028 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 5029 const struct ll_stats_clear_params *clear_req) 5030 { 5031 wmi_clear_link_stats_cmd_fixed_param *cmd; 5032 int32_t len; 5033 wmi_buf_t buf; 5034 uint8_t *buf_ptr; 5035 int ret; 5036 5037 len = sizeof(*cmd); 5038 buf = wmi_buf_alloc(wmi_handle, len); 5039 5040 if (!buf) 5041 return QDF_STATUS_E_NOMEM; 5042 5043 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5044 qdf_mem_zero(buf_ptr, len); 5045 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 5046 5047 WMITLV_SET_HDR(&cmd->tlv_header, 5048 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 5049 WMITLV_GET_STRUCT_TLVLEN 5050 (wmi_clear_link_stats_cmd_fixed_param)); 5051 5052 cmd->stop_stats_collection_req = clear_req->stop_req; 5053 cmd->vdev_id = clear_req->vdev_id; 5054 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 5055 5056 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 5057 &cmd->peer_macaddr); 5058 5059 WMI_LOGD("LINK_LAYER_STATS - Clear Request Params"); 5060 WMI_LOGD("StopReq: %d", cmd->stop_stats_collection_req); 5061 WMI_LOGD("Vdev Id: %d", cmd->vdev_id); 5062 WMI_LOGD("Clear Stat Mask: %d", cmd->stats_clear_req_mask); 5063 WMI_LOGD("Peer MAC Addr: %pM", clear_req->peer_macaddr.bytes); 5064 5065 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 5066 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5067 WMI_CLEAR_LINK_STATS_CMDID); 5068 if (ret) { 5069 WMI_LOGE("%s: Failed to send clear link stats req", __func__); 5070 wmi_buf_free(buf); 5071 return QDF_STATUS_E_FAILURE; 5072 } 5073 5074 WMI_LOGD("Clear Link Layer Stats request sent successfully"); 5075 return QDF_STATUS_SUCCESS; 5076 } 5077 5078 /** 5079 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 5080 * @wmi_handle: wmi handle 5081 * @set_req: ll stats set request command params 5082 * 5083 * Return: QDF_STATUS_SUCCESS for success or error code 5084 */ 5085 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 5086 const struct ll_stats_set_params *set_req) 5087 { 5088 wmi_start_link_stats_cmd_fixed_param *cmd; 5089 int32_t len; 5090 wmi_buf_t buf; 5091 uint8_t *buf_ptr; 5092 int ret; 5093 5094 len = sizeof(*cmd); 5095 buf = wmi_buf_alloc(wmi_handle, len); 5096 5097 if (!buf) 5098 return QDF_STATUS_E_NOMEM; 5099 5100 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5101 qdf_mem_zero(buf_ptr, len); 5102 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 5103 5104 WMITLV_SET_HDR(&cmd->tlv_header, 5105 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 5106 WMITLV_GET_STRUCT_TLVLEN 5107 (wmi_start_link_stats_cmd_fixed_param)); 5108 5109 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 5110 cmd->aggressive_statistics_gathering = 5111 set_req->aggressive_statistics_gathering; 5112 5113 WMI_LOGD("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 5114 cmd->mpdu_size_threshold, 5115 cmd->aggressive_statistics_gathering); 5116 5117 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 5118 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5119 WMI_START_LINK_STATS_CMDID); 5120 if (ret) { 5121 WMI_LOGE("%s: Failed to send set link stats request", __func__); 5122 wmi_buf_free(buf); 5123 return QDF_STATUS_E_FAILURE; 5124 } 5125 5126 return QDF_STATUS_SUCCESS; 5127 } 5128 5129 /** 5130 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 5131 * @wmi_handle: wmi handle 5132 * @get_req: ll stats get request command params 5133 * 5134 * Return: QDF_STATUS_SUCCESS for success or error code 5135 */ 5136 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 5137 const struct ll_stats_get_params *get_req) 5138 { 5139 wmi_request_link_stats_cmd_fixed_param *cmd; 5140 int32_t len; 5141 wmi_buf_t buf; 5142 uint8_t *buf_ptr; 5143 int ret; 5144 5145 len = sizeof(*cmd); 5146 buf = wmi_buf_alloc(wmi_handle, len); 5147 5148 if (!buf) 5149 return QDF_STATUS_E_NOMEM; 5150 5151 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5152 qdf_mem_zero(buf_ptr, len); 5153 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 5154 5155 WMITLV_SET_HDR(&cmd->tlv_header, 5156 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 5157 WMITLV_GET_STRUCT_TLVLEN 5158 (wmi_request_link_stats_cmd_fixed_param)); 5159 5160 cmd->request_id = get_req->req_id; 5161 cmd->stats_type = get_req->param_id_mask; 5162 cmd->vdev_id = get_req->vdev_id; 5163 5164 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 5165 &cmd->peer_macaddr); 5166 5167 WMI_LOGD("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: %pM", 5168 cmd->request_id, cmd->stats_type, cmd->vdev_id, 5169 get_req->peer_macaddr.bytes); 5170 5171 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 5172 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 5173 WMI_REQUEST_LINK_STATS_CMDID); 5174 if (ret) { 5175 WMI_LOGE("%s: Failed to send get link stats request", __func__); 5176 wmi_buf_free(buf); 5177 return QDF_STATUS_E_FAILURE; 5178 } 5179 5180 return QDF_STATUS_SUCCESS; 5181 } 5182 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 5183 5184 /** 5185 * send_congestion_cmd_tlv() - send request to fw to get CCA 5186 * @wmi_handle: wmi handle 5187 * @vdev_id: vdev id 5188 * 5189 * Return: CDF status 5190 */ 5191 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 5192 uint8_t vdev_id) 5193 { 5194 wmi_buf_t buf; 5195 wmi_request_stats_cmd_fixed_param *cmd; 5196 uint8_t len; 5197 uint8_t *buf_ptr; 5198 5199 len = sizeof(*cmd); 5200 buf = wmi_buf_alloc(wmi_handle, len); 5201 if (!buf) 5202 return QDF_STATUS_E_FAILURE; 5203 5204 buf_ptr = wmi_buf_data(buf); 5205 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 5206 WMITLV_SET_HDR(&cmd->tlv_header, 5207 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5208 WMITLV_GET_STRUCT_TLVLEN 5209 (wmi_request_stats_cmd_fixed_param)); 5210 5211 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 5212 cmd->vdev_id = vdev_id; 5213 WMI_LOGD("STATS REQ VDEV_ID:%d stats_id %d -->", 5214 cmd->vdev_id, cmd->stats_id); 5215 5216 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5217 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5218 WMI_REQUEST_STATS_CMDID)) { 5219 WMI_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", 5220 __func__); 5221 wmi_buf_free(buf); 5222 return QDF_STATUS_E_FAILURE; 5223 } 5224 5225 return QDF_STATUS_SUCCESS; 5226 } 5227 5228 /** 5229 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 5230 * @wmi_handle: wmi handle 5231 * @rssi_req: get RSSI request 5232 * 5233 * Return: CDF status 5234 */ 5235 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 5236 { 5237 wmi_buf_t buf; 5238 wmi_request_stats_cmd_fixed_param *cmd; 5239 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5240 5241 buf = wmi_buf_alloc(wmi_handle, len); 5242 if (!buf) 5243 return QDF_STATUS_E_FAILURE; 5244 5245 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5246 WMITLV_SET_HDR(&cmd->tlv_header, 5247 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5248 WMITLV_GET_STRUCT_TLVLEN 5249 (wmi_request_stats_cmd_fixed_param)); 5250 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5251 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5252 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5253 WMI_REQUEST_STATS_CMDID)) { 5254 WMI_LOGE("Failed to send host stats request to fw"); 5255 wmi_buf_free(buf); 5256 return QDF_STATUS_E_FAILURE; 5257 } 5258 5259 return QDF_STATUS_SUCCESS; 5260 } 5261 5262 /** 5263 * send_snr_cmd_tlv() - get RSSI from fw 5264 * @wmi_handle: wmi handle 5265 * @vdev_id: vdev id 5266 * 5267 * Return: CDF status 5268 */ 5269 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 5270 { 5271 wmi_buf_t buf; 5272 wmi_request_stats_cmd_fixed_param *cmd; 5273 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5274 5275 buf = wmi_buf_alloc(wmi_handle, len); 5276 if (!buf) 5277 return QDF_STATUS_E_FAILURE; 5278 5279 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5280 cmd->vdev_id = vdev_id; 5281 5282 WMITLV_SET_HDR(&cmd->tlv_header, 5283 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5284 WMITLV_GET_STRUCT_TLVLEN 5285 (wmi_request_stats_cmd_fixed_param)); 5286 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 5287 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5288 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5289 WMI_REQUEST_STATS_CMDID)) { 5290 WMI_LOGE("Failed to send host stats request to fw"); 5291 wmi_buf_free(buf); 5292 return QDF_STATUS_E_FAILURE; 5293 } 5294 5295 return QDF_STATUS_SUCCESS; 5296 } 5297 5298 /** 5299 * send_link_status_req_cmd_tlv() - process link status request from UMAC 5300 * @wmi_handle: wmi handle 5301 * @link_status: get link params 5302 * 5303 * Return: CDF status 5304 */ 5305 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 5306 struct link_status_params *link_status) 5307 { 5308 wmi_buf_t buf; 5309 wmi_request_stats_cmd_fixed_param *cmd; 5310 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 5311 5312 buf = wmi_buf_alloc(wmi_handle, len); 5313 if (!buf) 5314 return QDF_STATUS_E_FAILURE; 5315 5316 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 5317 WMITLV_SET_HDR(&cmd->tlv_header, 5318 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 5319 WMITLV_GET_STRUCT_TLVLEN 5320 (wmi_request_stats_cmd_fixed_param)); 5321 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 5322 cmd->vdev_id = link_status->vdev_id; 5323 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 5324 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5325 WMI_REQUEST_STATS_CMDID)) { 5326 WMI_LOGE("Failed to send WMI link status request to fw"); 5327 wmi_buf_free(buf); 5328 return QDF_STATUS_E_FAILURE; 5329 } 5330 5331 return QDF_STATUS_SUCCESS; 5332 } 5333 5334 #ifdef WLAN_SUPPORT_GREEN_AP 5335 /** 5336 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 5337 * @wmi_handle: wmi handler 5338 * @egap_params: pointer to egap_params 5339 * 5340 * Return: 0 for success, otherwise appropriate error code 5341 */ 5342 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 5343 struct wlan_green_ap_egap_params *egap_params) 5344 { 5345 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 5346 wmi_buf_t buf; 5347 int32_t err; 5348 5349 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5350 if (!buf) 5351 return QDF_STATUS_E_NOMEM; 5352 5353 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 5354 WMITLV_SET_HDR(&cmd->tlv_header, 5355 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 5356 WMITLV_GET_STRUCT_TLVLEN( 5357 wmi_ap_ps_egap_param_cmd_fixed_param)); 5358 5359 cmd->enable = egap_params->host_enable_egap; 5360 cmd->inactivity_time = egap_params->egap_inactivity_time; 5361 cmd->wait_time = egap_params->egap_wait_time; 5362 cmd->flags = egap_params->egap_feature_flags; 5363 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 5364 err = wmi_unified_cmd_send(wmi_handle, buf, 5365 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 5366 if (err) { 5367 WMI_LOGE("Failed to send ap_ps_egap cmd"); 5368 wmi_buf_free(buf); 5369 return QDF_STATUS_E_FAILURE; 5370 } 5371 5372 return QDF_STATUS_SUCCESS; 5373 } 5374 #endif 5375 5376 /** 5377 * wmi_unified_csa_offload_enable() - sen CSA offload enable command 5378 * @wmi_handle: wmi handle 5379 * @vdev_id: vdev id 5380 * 5381 * Return: QDF_STATUS_SUCCESS for success or error code 5382 */ 5383 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 5384 uint8_t vdev_id) 5385 { 5386 wmi_csa_offload_enable_cmd_fixed_param *cmd; 5387 wmi_buf_t buf; 5388 int32_t len = sizeof(*cmd); 5389 5390 WMI_LOGD("%s: vdev_id %d", __func__, vdev_id); 5391 buf = wmi_buf_alloc(wmi_handle, len); 5392 if (!buf) 5393 return QDF_STATUS_E_NOMEM; 5394 5395 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 5396 WMITLV_SET_HDR(&cmd->tlv_header, 5397 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 5398 WMITLV_GET_STRUCT_TLVLEN 5399 (wmi_csa_offload_enable_cmd_fixed_param)); 5400 cmd->vdev_id = vdev_id; 5401 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 5402 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 5403 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5404 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 5405 WMI_LOGP("%s: Failed to send CSA offload enable command", 5406 __func__); 5407 wmi_buf_free(buf); 5408 return QDF_STATUS_E_FAILURE; 5409 } 5410 5411 return 0; 5412 } 5413 5414 #ifdef WLAN_FEATURE_CIF_CFR 5415 /** 5416 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 5417 * @wmi_handle: wmi handle 5418 * @data_len: len of dma cfg req 5419 * @data: dma cfg req 5420 * 5421 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 5422 */ 5423 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 5424 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 5425 { 5426 wmi_buf_t buf; 5427 uint8_t *cmd; 5428 QDF_STATUS ret; 5429 5430 WMITLV_SET_HDR(cfg, 5431 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 5432 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 5433 5434 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 5435 if (!buf) 5436 return QDF_STATUS_E_FAILURE; 5437 5438 cmd = (uint8_t *) wmi_buf_data(buf); 5439 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 5440 WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"), 5441 sizeof(*cfg)); 5442 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 5443 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 5444 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 5445 if (QDF_IS_STATUS_ERROR(ret)) { 5446 WMI_LOGE(FL(":wmi cmd send failed")); 5447 wmi_buf_free(buf); 5448 } 5449 5450 return ret; 5451 } 5452 #endif 5453 5454 /** 5455 * send_start_11d_scan_cmd_tlv() - start 11d scan request 5456 * @wmi_handle: wmi handle 5457 * @start_11d_scan: 11d scan start request parameters 5458 * 5459 * This function request FW to start 11d scan. 5460 * 5461 * Return: QDF status 5462 */ 5463 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5464 struct reg_start_11d_scan_req *start_11d_scan) 5465 { 5466 wmi_11d_scan_start_cmd_fixed_param *cmd; 5467 int32_t len; 5468 wmi_buf_t buf; 5469 int ret; 5470 5471 len = sizeof(*cmd); 5472 buf = wmi_buf_alloc(wmi_handle, len); 5473 if (!buf) 5474 return QDF_STATUS_E_NOMEM; 5475 5476 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 5477 5478 WMITLV_SET_HDR(&cmd->tlv_header, 5479 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 5480 WMITLV_GET_STRUCT_TLVLEN 5481 (wmi_11d_scan_start_cmd_fixed_param)); 5482 5483 cmd->vdev_id = start_11d_scan->vdev_id; 5484 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 5485 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 5486 5487 WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id); 5488 5489 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 5490 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5491 WMI_11D_SCAN_START_CMDID); 5492 if (ret) { 5493 WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__); 5494 wmi_buf_free(buf); 5495 return QDF_STATUS_E_FAILURE; 5496 } 5497 5498 return QDF_STATUS_SUCCESS; 5499 } 5500 5501 /** 5502 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 5503 * @wmi_handle: wmi handle 5504 * @start_11d_scan: 11d scan stop request parameters 5505 * 5506 * This function request FW to stop 11d scan. 5507 * 5508 * Return: QDF status 5509 */ 5510 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 5511 struct reg_stop_11d_scan_req *stop_11d_scan) 5512 { 5513 wmi_11d_scan_stop_cmd_fixed_param *cmd; 5514 int32_t len; 5515 wmi_buf_t buf; 5516 int ret; 5517 5518 len = sizeof(*cmd); 5519 buf = wmi_buf_alloc(wmi_handle, len); 5520 if (!buf) 5521 return QDF_STATUS_E_NOMEM; 5522 5523 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 5524 5525 WMITLV_SET_HDR(&cmd->tlv_header, 5526 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 5527 WMITLV_GET_STRUCT_TLVLEN 5528 (wmi_11d_scan_stop_cmd_fixed_param)); 5529 5530 cmd->vdev_id = stop_11d_scan->vdev_id; 5531 5532 WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id); 5533 5534 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 5535 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5536 WMI_11D_SCAN_STOP_CMDID); 5537 if (ret) { 5538 WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__); 5539 wmi_buf_free(buf); 5540 return QDF_STATUS_E_FAILURE; 5541 } 5542 5543 return QDF_STATUS_SUCCESS; 5544 } 5545 5546 /** 5547 * send_start_oem_data_cmd_tlv() - start OEM data request to target 5548 * @wmi_handle: wmi handle 5549 * @data_len: the length of @data 5550 * @data: the pointer to data buf 5551 * 5552 * Return: CDF status 5553 */ 5554 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 5555 uint32_t data_len, 5556 uint8_t *data) 5557 { 5558 wmi_buf_t buf; 5559 uint8_t *cmd; 5560 QDF_STATUS ret; 5561 5562 buf = wmi_buf_alloc(wmi_handle, 5563 (data_len + WMI_TLV_HDR_SIZE)); 5564 if (!buf) 5565 return QDF_STATUS_E_FAILURE; 5566 5567 cmd = (uint8_t *) wmi_buf_data(buf); 5568 5569 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 5570 cmd += WMI_TLV_HDR_SIZE; 5571 qdf_mem_copy(cmd, data, 5572 data_len); 5573 5574 WMI_LOGD(FL("Sending OEM Data Request to target, data len %d"), 5575 data_len); 5576 5577 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 5578 ret = wmi_unified_cmd_send(wmi_handle, buf, 5579 (data_len + 5580 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 5581 5582 if (QDF_IS_STATUS_ERROR(ret)) { 5583 WMI_LOGE(FL(":wmi cmd send failed")); 5584 wmi_buf_free(buf); 5585 } 5586 5587 return ret; 5588 } 5589 5590 #ifdef FEATURE_OEM_DATA 5591 /** 5592 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 5593 * @wmi_handle: wmi handle 5594 * @oem_data: the pointer to oem data 5595 * 5596 * Return: QDF status 5597 */ 5598 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 5599 struct oem_data *oem_data) 5600 { 5601 QDF_STATUS ret; 5602 wmi_oem_data_cmd_fixed_param *cmd; 5603 struct wmi_ops *ops; 5604 wmi_buf_t buf; 5605 uint16_t len = sizeof(*cmd); 5606 uint16_t oem_data_len_aligned; 5607 uint8_t *buf_ptr; 5608 uint32_t pdev_id = oem_data->pdev_id; 5609 5610 if (!oem_data || !oem_data->data) { 5611 wmi_err_rl("oem data is not valid"); 5612 return QDF_STATUS_E_FAILURE; 5613 } 5614 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 5615 if (oem_data_len_aligned < oem_data->data_len) { 5616 wmi_err_rl("integer overflow while rounding up data_len"); 5617 return QDF_STATUS_E_FAILURE; 5618 } 5619 5620 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 5621 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 5622 return QDF_STATUS_E_FAILURE; 5623 } 5624 5625 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 5626 buf = wmi_buf_alloc(wmi_handle, len); 5627 if (!buf) 5628 return QDF_STATUS_E_NOMEM; 5629 5630 buf_ptr = (uint8_t *)wmi_buf_data(buf); 5631 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 5632 WMITLV_SET_HDR(&cmd->tlv_header, 5633 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 5634 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 5635 5636 if (oem_data->pdev_vdev_flag) { 5637 ops = wmi_handle->ops; 5638 if (oem_data->is_host_pdev_id) 5639 pdev_id = 5640 ops->convert_host_pdev_id_to_target(wmi_handle, 5641 pdev_id); 5642 else 5643 pdev_id = 5644 ops->convert_pdev_id_host_to_target(wmi_handle, 5645 pdev_id); 5646 } 5647 5648 cmd->vdev_id = oem_data->vdev_id; 5649 cmd->data_len = oem_data->data_len; 5650 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 5651 cmd->pdev_id = pdev_id; 5652 5653 buf_ptr += sizeof(*cmd); 5654 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 5655 buf_ptr += WMI_TLV_HDR_SIZE; 5656 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 5657 5658 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 5659 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 5660 if (QDF_IS_STATUS_ERROR(ret)) { 5661 wmi_err_rl("Failed with ret = %d", ret); 5662 wmi_buf_free(buf); 5663 } 5664 5665 return ret; 5666 } 5667 #endif 5668 5669 /** 5670 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 5671 * @wmi_handle: wmi handle 5672 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 5673 * 5674 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 5675 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 5676 * to firmware based on phyerr filtering 5677 * offload status. 5678 * 5679 * Return: 1 success, 0 failure 5680 */ 5681 static QDF_STATUS 5682 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 5683 bool dfs_phyerr_filter_offload) 5684 { 5685 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 5686 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 5687 wmi_buf_t buf; 5688 uint16_t len; 5689 QDF_STATUS ret; 5690 5691 5692 if (false == dfs_phyerr_filter_offload) { 5693 WMI_LOGD("%s:Phyerror Filtering offload is Disabled in ini", 5694 __func__); 5695 len = sizeof(*disable_phyerr_offload_cmd); 5696 buf = wmi_buf_alloc(wmi_handle, len); 5697 if (!buf) 5698 return 0; 5699 5700 disable_phyerr_offload_cmd = 5701 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 5702 wmi_buf_data(buf); 5703 5704 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 5705 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 5706 WMITLV_GET_STRUCT_TLVLEN 5707 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 5708 5709 /* 5710 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 5711 * to the firmware to disable the phyerror 5712 * filtering offload. 5713 */ 5714 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 5715 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5716 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 5717 if (QDF_IS_STATUS_ERROR(ret)) { 5718 WMI_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 5719 __func__, ret); 5720 wmi_buf_free(buf); 5721 return QDF_STATUS_E_FAILURE; 5722 } 5723 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", 5724 __func__); 5725 } else { 5726 WMI_LOGD("%s:Phyerror Filtering offload is Enabled in ini", 5727 __func__); 5728 5729 len = sizeof(*enable_phyerr_offload_cmd); 5730 buf = wmi_buf_alloc(wmi_handle, len); 5731 if (!buf) 5732 return QDF_STATUS_E_FAILURE; 5733 5734 enable_phyerr_offload_cmd = 5735 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 5736 wmi_buf_data(buf); 5737 5738 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 5739 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 5740 WMITLV_GET_STRUCT_TLVLEN 5741 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 5742 5743 /* 5744 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 5745 * to the firmware to enable the phyerror 5746 * filtering offload. 5747 */ 5748 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 5749 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5750 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 5751 5752 if (QDF_IS_STATUS_ERROR(ret)) { 5753 WMI_LOGE("%s: Failed to send DFS PHYERR CMD ret=%d", 5754 __func__, ret); 5755 wmi_buf_free(buf); 5756 return QDF_STATUS_E_FAILURE; 5757 } 5758 WMI_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", 5759 __func__); 5760 } 5761 5762 return QDF_STATUS_SUCCESS; 5763 } 5764 5765 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 5766 /** 5767 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 5768 * @wmi_handle: wmi handle 5769 * @pktlog_event: pktlog event 5770 * @cmd_id: pktlog cmd id 5771 * @user_triggered: user triggered input for PKTLOG enable mode 5772 * 5773 * Return: CDF status 5774 */ 5775 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 5776 WMI_PKTLOG_EVENT pktlog_event, 5777 WMI_CMD_ID cmd_id, uint8_t user_triggered) 5778 { 5779 WMI_PKTLOG_EVENT PKTLOG_EVENT; 5780 WMI_CMD_ID CMD_ID; 5781 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 5782 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 5783 int len = 0; 5784 wmi_buf_t buf; 5785 int32_t idx, max_idx; 5786 5787 PKTLOG_EVENT = pktlog_event; 5788 CMD_ID = cmd_id; 5789 5790 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 5791 switch (CMD_ID) { 5792 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 5793 len = sizeof(*cmd); 5794 buf = wmi_buf_alloc(wmi_handle, len); 5795 if (!buf) 5796 return QDF_STATUS_E_NOMEM; 5797 5798 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 5799 wmi_buf_data(buf); 5800 WMITLV_SET_HDR(&cmd->tlv_header, 5801 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 5802 WMITLV_GET_STRUCT_TLVLEN 5803 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 5804 cmd->evlist = 0; 5805 for (idx = 0; idx < max_idx; idx++) { 5806 if (PKTLOG_EVENT & (1 << idx)) 5807 cmd->evlist |= pktlog_event_tlv[idx]; 5808 } 5809 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 5810 : WMI_PKTLOG_ENABLE_AUTO; 5811 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5812 wmi_handle, 5813 WMI_HOST_PDEV_ID_SOC); 5814 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 5815 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5816 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 5817 WMI_LOGE("failed to send pktlog enable cmdid"); 5818 goto wmi_send_failed; 5819 } 5820 break; 5821 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 5822 len = sizeof(*disable_cmd); 5823 buf = wmi_buf_alloc(wmi_handle, len); 5824 if (!buf) 5825 return QDF_STATUS_E_NOMEM; 5826 5827 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 5828 wmi_buf_data(buf); 5829 WMITLV_SET_HDR(&disable_cmd->tlv_header, 5830 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 5831 WMITLV_GET_STRUCT_TLVLEN 5832 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 5833 disable_cmd->pdev_id = 5834 wmi_handle->ops->convert_pdev_id_host_to_target( 5835 wmi_handle, 5836 WMI_HOST_PDEV_ID_SOC); 5837 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 5838 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5839 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 5840 WMI_LOGE("failed to send pktlog disable cmdid"); 5841 goto wmi_send_failed; 5842 } 5843 break; 5844 default: 5845 WMI_LOGD("%s: invalid PKTLOG command", __func__); 5846 break; 5847 } 5848 5849 return QDF_STATUS_SUCCESS; 5850 5851 wmi_send_failed: 5852 wmi_buf_free(buf); 5853 return QDF_STATUS_E_FAILURE; 5854 } 5855 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 5856 5857 /** 5858 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 5859 * @wmi_handle: wmi handle 5860 * @preq: stats ext params 5861 * 5862 * Return: CDF status 5863 */ 5864 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 5865 struct stats_ext_params *preq) 5866 { 5867 QDF_STATUS ret; 5868 wmi_req_stats_ext_cmd_fixed_param *cmd; 5869 wmi_buf_t buf; 5870 size_t len; 5871 uint8_t *buf_ptr; 5872 5873 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len; 5874 5875 buf = wmi_buf_alloc(wmi_handle, len); 5876 if (!buf) 5877 return QDF_STATUS_E_NOMEM; 5878 5879 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5880 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 5881 5882 WMITLV_SET_HDR(&cmd->tlv_header, 5883 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 5884 WMITLV_GET_STRUCT_TLVLEN 5885 (wmi_req_stats_ext_cmd_fixed_param)); 5886 cmd->vdev_id = preq->vdev_id; 5887 cmd->data_len = preq->request_data_len; 5888 5889 WMI_LOGD("%s: The data len value is %u and vdev id set is %u ", 5890 __func__, preq->request_data_len, preq->vdev_id); 5891 5892 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 5893 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 5894 5895 buf_ptr += WMI_TLV_HDR_SIZE; 5896 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 5897 5898 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 5899 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5900 WMI_REQUEST_STATS_EXT_CMDID); 5901 if (QDF_IS_STATUS_ERROR(ret)) { 5902 WMI_LOGE("%s: Failed to send notify cmd ret = %d", __func__, 5903 ret); 5904 wmi_buf_free(buf); 5905 } 5906 5907 return ret; 5908 } 5909 5910 /** 5911 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 5912 * @wmi_handle: wmi handle 5913 * @params: DHCP server offload info 5914 * 5915 * Return: QDF_STATUS_SUCCESS for success or error code 5916 */ 5917 static QDF_STATUS 5918 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 5919 struct dhcp_offload_info_params *params) 5920 { 5921 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 5922 wmi_buf_t buf; 5923 QDF_STATUS status; 5924 5925 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5926 if (!buf) 5927 return QDF_STATUS_E_NOMEM; 5928 5929 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 5930 5931 WMITLV_SET_HDR(&cmd->tlv_header, 5932 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 5933 WMITLV_GET_STRUCT_TLVLEN 5934 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 5935 cmd->vdev_id = params->vdev_id; 5936 cmd->enable = params->dhcp_offload_enabled; 5937 cmd->num_client = params->dhcp_client_num; 5938 cmd->srv_ipv4 = params->dhcp_srv_addr; 5939 cmd->start_lsb = 0; 5940 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 5941 status = wmi_unified_cmd_send(wmi_handle, buf, 5942 sizeof(*cmd), 5943 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 5944 if (QDF_IS_STATUS_ERROR(status)) { 5945 WMI_LOGE("Failed to send set_dhcp_server_offload cmd"); 5946 wmi_buf_free(buf); 5947 return QDF_STATUS_E_FAILURE; 5948 } 5949 WMI_LOGD("Set dhcp server offload to vdevId %d", 5950 params->vdev_id); 5951 5952 return status; 5953 } 5954 5955 /** 5956 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 5957 * @wmi_handle: wmi handle 5958 * @param: pointer to pdev regdomain params 5959 * 5960 * Return: 0 for success or error code 5961 */ 5962 static QDF_STATUS 5963 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 5964 struct pdev_set_regdomain_params *param) 5965 { 5966 wmi_buf_t buf; 5967 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 5968 int32_t len = sizeof(*cmd); 5969 5970 buf = wmi_buf_alloc(wmi_handle, len); 5971 if (!buf) 5972 return QDF_STATUS_E_NOMEM; 5973 5974 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 5975 WMITLV_SET_HDR(&cmd->tlv_header, 5976 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 5977 WMITLV_GET_STRUCT_TLVLEN 5978 (wmi_pdev_set_regdomain_cmd_fixed_param)); 5979 5980 cmd->reg_domain = param->currentRDinuse; 5981 cmd->reg_domain_2G = param->currentRD2G; 5982 cmd->reg_domain_5G = param->currentRD5G; 5983 cmd->conformance_test_limit_2G = param->ctl_2G; 5984 cmd->conformance_test_limit_5G = param->ctl_5G; 5985 cmd->dfs_domain = param->dfsDomain; 5986 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5987 wmi_handle, 5988 param->pdev_id); 5989 5990 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 5991 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5992 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 5993 WMI_LOGE("%s: Failed to send pdev set regdomain command", 5994 __func__); 5995 wmi_buf_free(buf); 5996 return QDF_STATUS_E_FAILURE; 5997 } 5998 5999 return QDF_STATUS_SUCCESS; 6000 } 6001 6002 /** 6003 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 6004 * @wmi_handle: wmi handle 6005 * @reg_dmn: reg domain 6006 * @regdmn2G: 2G reg domain 6007 * @regdmn5G: 5G reg domain 6008 * @ctl2G: 2G test limit 6009 * @ctl5G: 5G test limit 6010 * 6011 * Return: none 6012 */ 6013 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 6014 uint32_t reg_dmn, uint16_t regdmn2G, 6015 uint16_t regdmn5G, uint8_t ctl2G, 6016 uint8_t ctl5G) 6017 { 6018 wmi_buf_t buf; 6019 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 6020 int32_t len = sizeof(*cmd); 6021 6022 6023 buf = wmi_buf_alloc(wmi_handle, len); 6024 if (!buf) 6025 return QDF_STATUS_E_NOMEM; 6026 6027 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 6028 WMITLV_SET_HDR(&cmd->tlv_header, 6029 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 6030 WMITLV_GET_STRUCT_TLVLEN 6031 (wmi_pdev_set_regdomain_cmd_fixed_param)); 6032 cmd->reg_domain = reg_dmn; 6033 cmd->reg_domain_2G = regdmn2G; 6034 cmd->reg_domain_5G = regdmn5G; 6035 cmd->conformance_test_limit_2G = ctl2G; 6036 cmd->conformance_test_limit_5G = ctl5G; 6037 6038 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 6039 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 6040 cmd->conformance_test_limit_2G, 6041 cmd->conformance_test_limit_5G); 6042 6043 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 6044 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6045 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 6046 WMI_LOGP("%s: Failed to send pdev set regdomain command", 6047 __func__); 6048 wmi_buf_free(buf); 6049 return QDF_STATUS_E_FAILURE; 6050 } 6051 6052 return QDF_STATUS_SUCCESS; 6053 } 6054 6055 /** 6056 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 6057 * @param: param sent from the host side 6058 * @cmd: param to be sent to the fw side 6059 */ 6060 static inline void copy_custom_aggr_bitmap( 6061 struct set_custom_aggr_size_params *param, 6062 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 6063 { 6064 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 6065 param->ac); 6066 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 6067 param->aggr_type); 6068 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6069 param->tx_aggr_size_disable); 6070 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 6071 param->rx_aggr_size_disable); 6072 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 6073 param->tx_ac_enable); 6074 } 6075 6076 /** 6077 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 6078 * @wmi_handle: wmi handle 6079 * @param: pointer to hold custom aggr size params 6080 * 6081 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6082 */ 6083 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 6084 wmi_unified_t wmi_handle, 6085 struct set_custom_aggr_size_params *param) 6086 { 6087 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 6088 wmi_buf_t buf; 6089 int32_t len = sizeof(*cmd); 6090 6091 buf = wmi_buf_alloc(wmi_handle, len); 6092 if (!buf) 6093 return QDF_STATUS_E_FAILURE; 6094 6095 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 6096 wmi_buf_data(buf); 6097 WMITLV_SET_HDR(&cmd->tlv_header, 6098 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 6099 WMITLV_GET_STRUCT_TLVLEN( 6100 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 6101 cmd->vdev_id = param->vdev_id; 6102 cmd->tx_aggr_size = param->tx_aggr_size; 6103 cmd->rx_aggr_size = param->rx_aggr_size; 6104 copy_custom_aggr_bitmap(param, cmd); 6105 6106 WMI_LOGD("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 6107 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 6108 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 6109 "tx_ac_enable=0x%X", 6110 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 6111 param->ac, param->aggr_type, param->tx_aggr_size_disable, 6112 param->rx_aggr_size_disable, param->tx_ac_enable); 6113 6114 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 6115 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6116 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 6117 WMI_LOGE("Seting custom aggregation size failed"); 6118 wmi_buf_free(buf); 6119 return QDF_STATUS_E_FAILURE; 6120 } 6121 6122 return QDF_STATUS_SUCCESS; 6123 } 6124 6125 /** 6126 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 6127 * @param wmi_handle : handle to WMI. 6128 * @param param : pointer to tx antenna param 6129 * 6130 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6131 */ 6132 6133 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 6134 struct set_qdepth_thresh_params *param) 6135 { 6136 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 6137 wmi_msduq_qdepth_thresh_update *cmd_update; 6138 wmi_buf_t buf; 6139 int32_t len = 0; 6140 int i; 6141 uint8_t *buf_ptr; 6142 QDF_STATUS ret; 6143 6144 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 6145 WMI_LOGE("%s: Invalid Update Count!", __func__); 6146 return QDF_STATUS_E_INVAL; 6147 } 6148 6149 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 6150 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 6151 param->num_of_msduq_updates); 6152 buf = wmi_buf_alloc(wmi_handle, len); 6153 6154 if (!buf) 6155 return QDF_STATUS_E_NOMEM; 6156 6157 buf_ptr = (uint8_t *)wmi_buf_data(buf); 6158 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 6159 buf_ptr; 6160 6161 WMITLV_SET_HDR(&cmd->tlv_header, 6162 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 6163 , WMITLV_GET_STRUCT_TLVLEN( 6164 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 6165 6166 cmd->pdev_id = 6167 wmi_handle->ops->convert_pdev_id_host_to_target( 6168 wmi_handle, 6169 param->pdev_id); 6170 cmd->vdev_id = param->vdev_id; 6171 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 6172 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 6173 6174 buf_ptr += sizeof( 6175 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 6176 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6177 param->num_of_msduq_updates * 6178 sizeof(wmi_msduq_qdepth_thresh_update)); 6179 buf_ptr += WMI_TLV_HDR_SIZE; 6180 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 6181 6182 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 6183 WMITLV_SET_HDR(&cmd_update->tlv_header, 6184 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 6185 WMITLV_GET_STRUCT_TLVLEN( 6186 wmi_msduq_qdepth_thresh_update)); 6187 cmd_update->tid_num = param->update_params[i].tid_num; 6188 cmd_update->msduq_update_mask = 6189 param->update_params[i].msduq_update_mask; 6190 cmd_update->qdepth_thresh_value = 6191 param->update_params[i].qdepth_thresh_value; 6192 WMI_LOGD("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 6193 "mac_addr_upper4=%X, mac_addr_lower2:%X," 6194 " update mask=0x%X thresh val=0x%X", 6195 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 6196 cmd->peer_mac_address.mac_addr31to0, 6197 cmd->peer_mac_address.mac_addr47to32, 6198 cmd_update->msduq_update_mask, 6199 cmd_update->qdepth_thresh_value); 6200 cmd_update++; 6201 } 6202 6203 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 6204 cmd->vdev_id, 0); 6205 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6206 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 6207 6208 if (ret != 0) { 6209 WMI_LOGE(" %s :WMI Failed", __func__); 6210 wmi_buf_free(buf); 6211 } 6212 6213 return ret; 6214 } 6215 6216 /** 6217 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 6218 * @wmi_handle: wmi handle 6219 * @param: pointer to hold vap dscp tid map param 6220 * 6221 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6222 */ 6223 static QDF_STATUS 6224 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 6225 struct vap_dscp_tid_map_params *param) 6226 { 6227 wmi_buf_t buf; 6228 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 6229 int32_t len = sizeof(*cmd); 6230 6231 buf = wmi_buf_alloc(wmi_handle, len); 6232 if (!buf) 6233 return QDF_STATUS_E_FAILURE; 6234 6235 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 6236 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 6237 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 6238 6239 cmd->vdev_id = param->vdev_id; 6240 cmd->enable_override = 0; 6241 6242 WMI_LOGI("Setting dscp for vap id: %d", cmd->vdev_id); 6243 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 6244 if (wmi_unified_cmd_send(wmi_handle, buf, len, 6245 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 6246 WMI_LOGE("Failed to set dscp cmd"); 6247 wmi_buf_free(buf); 6248 return QDF_STATUS_E_FAILURE; 6249 } 6250 6251 return QDF_STATUS_SUCCESS; 6252 } 6253 6254 /** 6255 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 6256 * @wmi_handle: wmi handle 6257 * @param: pointer to hold fwtest param 6258 * 6259 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6260 */ 6261 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 6262 struct set_fwtest_params *param) 6263 { 6264 wmi_fwtest_set_param_cmd_fixed_param *cmd; 6265 wmi_buf_t buf; 6266 int32_t len = sizeof(*cmd); 6267 6268 buf = wmi_buf_alloc(wmi_handle, len); 6269 6270 if (!buf) 6271 return QDF_STATUS_E_FAILURE; 6272 6273 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 6274 WMITLV_SET_HDR(&cmd->tlv_header, 6275 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 6276 WMITLV_GET_STRUCT_TLVLEN( 6277 wmi_fwtest_set_param_cmd_fixed_param)); 6278 cmd->param_id = param->arg; 6279 cmd->param_value = param->value; 6280 6281 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 6282 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 6283 WMI_LOGE("Setting FW test param failed"); 6284 wmi_buf_free(buf); 6285 return QDF_STATUS_E_FAILURE; 6286 } 6287 6288 return QDF_STATUS_SUCCESS; 6289 } 6290 6291 /** 6292 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 6293 * 6294 * @param wmi_handle : handle to WMI. 6295 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6296 */ 6297 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 6298 { 6299 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 6300 wmi_buf_t buf; 6301 QDF_STATUS ret; 6302 int32_t len; 6303 6304 len = sizeof(*cmd); 6305 6306 buf = wmi_buf_alloc(wmi_handle, len); 6307 if (!buf) 6308 return QDF_STATUS_E_FAILURE; 6309 6310 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 6311 WMITLV_SET_HDR(&cmd->tlv_header, 6312 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 6313 WMITLV_GET_STRUCT_TLVLEN( 6314 wmi_pdev_dfs_disable_cmd_fixed_param)); 6315 /* Filling it with WMI_PDEV_ID_SOC for now */ 6316 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6317 wmi_handle, 6318 WMI_HOST_PDEV_ID_SOC); 6319 6320 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 6321 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6322 WMI_PDEV_DFS_DISABLE_CMDID); 6323 6324 if (ret != 0) { 6325 WMI_LOGE("Sending PDEV DFS disable cmd failed"); 6326 wmi_buf_free(buf); 6327 } 6328 6329 return ret; 6330 } 6331 6332 /** 6333 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 6334 * 6335 * @param wmi_handle : handle to WMI. 6336 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6337 */ 6338 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 6339 { 6340 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 6341 wmi_buf_t buf; 6342 QDF_STATUS ret; 6343 int32_t len; 6344 6345 len = sizeof(*cmd); 6346 6347 buf = wmi_buf_alloc(wmi_handle, len); 6348 if (!buf) 6349 return QDF_STATUS_E_FAILURE; 6350 6351 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 6352 WMITLV_SET_HDR(&cmd->tlv_header, 6353 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 6354 WMITLV_GET_STRUCT_TLVLEN( 6355 wmi_pdev_dfs_enable_cmd_fixed_param)); 6356 /* Reserved for future use */ 6357 cmd->reserved0 = 0; 6358 6359 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 6360 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6361 WMI_PDEV_DFS_ENABLE_CMDID); 6362 6363 if (ret != 0) { 6364 WMI_LOGE("Sending PDEV DFS enable cmd failed"); 6365 wmi_buf_free(buf); 6366 } 6367 6368 return ret; 6369 } 6370 6371 /** 6372 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 6373 * to fw 6374 * @wmi_handle: wmi handle 6375 * @param: pointer to hold periodic chan stats param 6376 * 6377 * Return: 0 for success or error code 6378 */ 6379 static QDF_STATUS 6380 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 6381 struct periodic_chan_stats_params *param) 6382 { 6383 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 6384 wmi_buf_t buf; 6385 QDF_STATUS ret; 6386 int32_t len; 6387 6388 len = sizeof(*cmd); 6389 6390 buf = wmi_buf_alloc(wmi_handle, len); 6391 if (!buf) 6392 return QDF_STATUS_E_FAILURE; 6393 6394 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 6395 wmi_buf_data(buf); 6396 WMITLV_SET_HDR(&cmd->tlv_header, 6397 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 6398 WMITLV_GET_STRUCT_TLVLEN( 6399 wmi_set_periodic_channel_stats_config_fixed_param)); 6400 cmd->enable = param->enable; 6401 cmd->stats_period = param->stats_period; 6402 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6403 wmi_handle, 6404 param->pdev_id); 6405 6406 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 6407 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 6408 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 6409 6410 if (ret != 0) { 6411 WMI_LOGE("Sending periodic chan stats config failed"); 6412 wmi_buf_free(buf); 6413 } 6414 6415 return ret; 6416 } 6417 6418 #ifdef WLAN_IOT_SIM_SUPPORT 6419 /** 6420 * send_simulation_test_cmd_tlv() - send simulation test command to fw 6421 * 6422 * @wmi_handle: wmi handle 6423 * @param: pointer to hold simulation test parameter 6424 * 6425 * Return: 0 for success or error code 6426 */ 6427 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 6428 struct simulation_test_params 6429 *param) 6430 { 6431 wmi_simulation_test_cmd_fixed_param *cmd; 6432 u32 wmi_buf_len; 6433 wmi_buf_t buf; 6434 u8 *buf_ptr; 6435 u32 aligned_len = 0; 6436 6437 wmi_buf_len = sizeof(*cmd); 6438 if (param->buf_len) { 6439 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 6440 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 6441 } 6442 6443 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6444 if (!buf) { 6445 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 6446 return QDF_STATUS_E_NOMEM; 6447 } 6448 6449 buf_ptr = wmi_buf_data(buf); 6450 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 6451 WMITLV_SET_HDR(&cmd->tlv_header, 6452 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 6453 WMITLV_GET_STRUCT_TLVLEN( 6454 wmi_simulation_test_cmd_fixed_param)); 6455 cmd->pdev_id = param->pdev_id; 6456 cmd->vdev_id = param->vdev_id; 6457 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 6458 cmd->test_cmd_type = param->test_cmd_type; 6459 cmd->test_subcmd_type = param->test_subcmd_type; 6460 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 6461 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 6462 param->frame_subtype); 6463 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 6464 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 6465 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 6466 cmd->buf_len = param->buf_len; 6467 6468 if (param->buf_len) { 6469 buf_ptr += sizeof(*cmd); 6470 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 6471 buf_ptr += WMI_TLV_HDR_SIZE; 6472 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 6473 } 6474 6475 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 6476 WMI_SIMULATION_TEST_CMDID)) { 6477 WMI_LOGE("%s: Failed to send test simulation cmd", __func__); 6478 wmi_buf_free(buf); 6479 return QDF_STATUS_E_FAILURE; 6480 } 6481 6482 return QDF_STATUS_SUCCESS; 6483 } 6484 #endif 6485 6486 /** 6487 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 6488 * command to fw 6489 * @wmi_handle: wmi handle 6490 * @param: pointer to hold spectral config parameter 6491 * 6492 * Return: 0 for success or error code 6493 */ 6494 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 6495 struct vdev_spectral_configure_params *param) 6496 { 6497 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 6498 wmi_buf_t buf; 6499 QDF_STATUS ret; 6500 int32_t len; 6501 6502 len = sizeof(*cmd); 6503 buf = wmi_buf_alloc(wmi_handle, len); 6504 if (!buf) 6505 return QDF_STATUS_E_FAILURE; 6506 6507 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 6508 WMITLV_SET_HDR(&cmd->tlv_header, 6509 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 6510 WMITLV_GET_STRUCT_TLVLEN( 6511 wmi_vdev_spectral_configure_cmd_fixed_param)); 6512 6513 cmd->vdev_id = param->vdev_id; 6514 cmd->spectral_scan_count = param->count; 6515 cmd->spectral_scan_period = param->period; 6516 cmd->spectral_scan_priority = param->spectral_pri; 6517 cmd->spectral_scan_fft_size = param->fft_size; 6518 cmd->spectral_scan_gc_ena = param->gc_enable; 6519 cmd->spectral_scan_restart_ena = param->restart_enable; 6520 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 6521 cmd->spectral_scan_init_delay = param->init_delay; 6522 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 6523 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 6524 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 6525 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 6526 cmd->spectral_scan_rssi_thr = param->rssi_thr; 6527 cmd->spectral_scan_pwr_format = param->pwr_format; 6528 cmd->spectral_scan_rpt_mode = param->rpt_mode; 6529 cmd->spectral_scan_bin_scale = param->bin_scale; 6530 cmd->spectral_scan_dBm_adj = param->dbm_adj; 6531 cmd->spectral_scan_chn_mask = param->chn_mask; 6532 cmd->spectral_scan_mode = param->mode; 6533 cmd->spectral_scan_center_freq1 = param->center_freq1; 6534 cmd->spectral_scan_center_freq2 = param->center_freq2; 6535 cmd->spectral_scan_chan_width = param->chan_width; 6536 /* Not used, fill with zeros */ 6537 cmd->spectral_scan_chan_freq = 0; 6538 6539 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 6540 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6541 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 6542 6543 if (ret != 0) { 6544 WMI_LOGE("Sending set quiet cmd failed"); 6545 wmi_buf_free(buf); 6546 } 6547 6548 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID", 6549 __func__); 6550 6551 WMI_LOGI("vdev_id = %u", param->vdev_id); 6552 WMI_LOGI("spectral_scan_count = %u", param->count); 6553 WMI_LOGI("spectral_scan_period = %u", param->period); 6554 WMI_LOGI("spectral_scan_priority = %u", param->spectral_pri); 6555 WMI_LOGI("spectral_scan_fft_size = %u", param->fft_size); 6556 WMI_LOGI("spectral_scan_gc_ena = %u", param->gc_enable); 6557 WMI_LOGI("spectral_scan_restart_ena = %u", param->restart_enable); 6558 WMI_LOGI("spectral_scan_noise_floor_ref = %u", param->noise_floor_ref); 6559 WMI_LOGI("spectral_scan_init_delay = %u", param->init_delay); 6560 WMI_LOGI("spectral_scan_nb_tone_thr = %u", param->nb_tone_thr); 6561 WMI_LOGI("spectral_scan_str_bin_thr = %u", param->str_bin_thr); 6562 WMI_LOGI("spectral_scan_wb_rpt_mode = %u", param->wb_rpt_mode); 6563 WMI_LOGI("spectral_scan_rssi_rpt_mode = %u", param->rssi_rpt_mode); 6564 WMI_LOGI("spectral_scan_rssi_thr = %u", param->rssi_thr); 6565 WMI_LOGI("spectral_scan_pwr_format = %u", param->pwr_format); 6566 WMI_LOGI("spectral_scan_rpt_mode = %u", param->rpt_mode); 6567 WMI_LOGI("spectral_scan_bin_scale = %u", param->bin_scale); 6568 WMI_LOGI("spectral_scan_dBm_adj = %u", param->dbm_adj); 6569 WMI_LOGI("spectral_scan_chn_mask = %u", param->chn_mask); 6570 WMI_LOGI("spectral_scan_mode = %u", param->mode); 6571 WMI_LOGI("spectral_scan_center_freq1 = %u", param->center_freq1); 6572 WMI_LOGI("spectral_scan_center_freq2 = %u", param->center_freq2); 6573 WMI_LOGI("spectral_scan_chan_freq = %u", param->chan_freq); 6574 WMI_LOGI("spectral_scan_chan_width = %u", param->chan_width); 6575 WMI_LOGI("%s: Status: %d", __func__, ret); 6576 6577 return ret; 6578 } 6579 6580 /** 6581 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 6582 * command to fw 6583 * @wmi_handle: wmi handle 6584 * @param: pointer to hold spectral enable parameter 6585 * 6586 * Return: 0 for success or error code 6587 */ 6588 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 6589 struct vdev_spectral_enable_params *param) 6590 { 6591 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 6592 wmi_buf_t buf; 6593 QDF_STATUS ret; 6594 int32_t len; 6595 6596 len = sizeof(*cmd); 6597 buf = wmi_buf_alloc(wmi_handle, len); 6598 if (!buf) 6599 return QDF_STATUS_E_FAILURE; 6600 6601 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 6602 WMITLV_SET_HDR(&cmd->tlv_header, 6603 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 6604 WMITLV_GET_STRUCT_TLVLEN( 6605 wmi_vdev_spectral_enable_cmd_fixed_param)); 6606 6607 cmd->vdev_id = param->vdev_id; 6608 6609 if (param->active_valid) { 6610 cmd->trigger_cmd = param->active ? 1 : 2; 6611 /* 1: Trigger, 2: Clear Trigger */ 6612 } else { 6613 cmd->trigger_cmd = 0; /* 0: Ignore */ 6614 } 6615 6616 if (param->enabled_valid) { 6617 cmd->enable_cmd = param->enabled ? 1 : 2; 6618 /* 1: Enable 2: Disable */ 6619 } else { 6620 cmd->enable_cmd = 0; /* 0: Ignore */ 6621 } 6622 cmd->spectral_scan_mode = param->mode; 6623 6624 WMI_LOGI("vdev_id = %u", cmd->vdev_id); 6625 WMI_LOGI("trigger_cmd = %u", cmd->trigger_cmd); 6626 WMI_LOGI("enable_cmd = %u", cmd->enable_cmd); 6627 WMI_LOGI("spectral_scan_mode = %u", cmd->spectral_scan_mode); 6628 6629 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 6630 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6631 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 6632 6633 if (ret != 0) { 6634 WMI_LOGE("Sending scan enable CMD failed"); 6635 wmi_buf_free(buf); 6636 } 6637 6638 WMI_LOGI("%s: Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID", __func__); 6639 6640 WMI_LOGI("%s: Status: %d", __func__, ret); 6641 6642 return ret; 6643 } 6644 6645 #ifdef WLAN_CONV_SPECTRAL_ENABLE 6646 static QDF_STATUS 6647 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 6648 wmi_unified_t wmi_handle, 6649 uint8_t *event, struct spectral_startscan_resp_params *param) 6650 { 6651 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 6652 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 6653 6654 if (!wmi_handle) { 6655 WMI_LOGE("WMI handle is null"); 6656 return QDF_STATUS_E_INVAL; 6657 } 6658 6659 if (!event) { 6660 WMI_LOGE("WMI event is null"); 6661 return QDF_STATUS_E_INVAL; 6662 } 6663 6664 if (!param) { 6665 WMI_LOGE("Spectral startscan response params is null"); 6666 return QDF_STATUS_E_INVAL; 6667 } 6668 6669 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 6670 if (!param_buf) 6671 return QDF_STATUS_E_INVAL; 6672 6673 ev = param_buf->fixed_param; 6674 if (!ev) 6675 return QDF_STATUS_E_INVAL; 6676 6677 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 6678 wmi_handle, 6679 ev->pdev_id); 6680 param->smode = ev->spectral_scan_mode; 6681 param->num_fft_bin_index = param_buf->num_fft_bin_index; 6682 WMI_LOGD("%s:pdev id %u scan mode %u num_fft_bin_index %u", __func__, 6683 param->pdev_id, param->smode, param->num_fft_bin_index); 6684 6685 return QDF_STATUS_SUCCESS; 6686 } 6687 6688 static QDF_STATUS 6689 extract_pdev_sscan_fft_bin_index_tlv( 6690 wmi_unified_t wmi_handle, uint8_t *event, 6691 struct spectral_fft_bin_markers_160_165mhz *param) 6692 { 6693 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 6694 wmi_pdev_sscan_fft_bin_index *ev; 6695 6696 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 6697 if (!param_buf) 6698 return QDF_STATUS_E_INVAL; 6699 6700 ev = param_buf->fft_bin_index; 6701 if (!ev) 6702 return QDF_STATUS_E_INVAL; 6703 6704 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 6705 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 6706 param->start_pri80 + 1; 6707 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 6708 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 6709 param->start_sec80 + 1; 6710 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 6711 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 6712 param->start_5mhz + 1; 6713 param->is_valid = true; 6714 6715 WMI_LOGD("%s:start_pri80 %u, num_pri80 %u", __func__, 6716 param->start_pri80, param->num_pri80); 6717 WMI_LOGD("%s:start_sec80 %u, num_sec80 %u", __func__, 6718 param->start_sec80, param->num_sec80); 6719 WMI_LOGD("%s:start_5mhz %u, num_5mhz %u", __func__, 6720 param->start_5mhz, param->num_5mhz); 6721 6722 return QDF_STATUS_SUCCESS; 6723 } 6724 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 6725 6726 /** 6727 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 6728 * @param wmi_handle : handle to WMI. 6729 * @param param : pointer to hold thermal mitigation param 6730 * 6731 * @return QDF_STATUS_SUCCESS on success and -ve on failure. 6732 */ 6733 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 6734 wmi_unified_t wmi_handle, 6735 struct thermal_mitigation_params *param) 6736 { 6737 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 6738 wmi_therm_throt_level_config_info *lvl_conf = NULL; 6739 wmi_buf_t buf = NULL; 6740 uint8_t *buf_ptr = NULL; 6741 int error; 6742 int32_t len; 6743 int i; 6744 6745 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 6746 param->num_thermal_conf * 6747 sizeof(wmi_therm_throt_level_config_info); 6748 6749 buf = wmi_buf_alloc(wmi_handle, len); 6750 if (!buf) 6751 return QDF_STATUS_E_NOMEM; 6752 6753 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 6754 6755 /* init fixed params */ 6756 WMITLV_SET_HDR(tt_conf, 6757 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 6758 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 6759 6760 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 6761 wmi_handle, 6762 param->pdev_id); 6763 tt_conf->enable = param->enable; 6764 tt_conf->dc = param->dc; 6765 tt_conf->dc_per_event = param->dc_per_event; 6766 tt_conf->therm_throt_levels = param->num_thermal_conf; 6767 6768 buf_ptr = (uint8_t *) ++tt_conf; 6769 /* init TLV params */ 6770 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6771 (param->num_thermal_conf * 6772 sizeof(wmi_therm_throt_level_config_info))); 6773 6774 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 6775 for (i = 0; i < param->num_thermal_conf; i++) { 6776 WMITLV_SET_HDR(&lvl_conf->tlv_header, 6777 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 6778 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 6779 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 6780 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 6781 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 6782 lvl_conf->prio = param->levelconf[i].priority; 6783 lvl_conf++; 6784 } 6785 6786 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 6787 error = wmi_unified_cmd_send(wmi_handle, buf, len, 6788 WMI_THERM_THROT_SET_CONF_CMDID); 6789 if (QDF_IS_STATUS_ERROR(error)) { 6790 wmi_buf_free(buf); 6791 WMI_LOGE("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 6792 } 6793 6794 return error; 6795 } 6796 6797 /** 6798 * send_coex_config_cmd_tlv() - send coex config command to fw 6799 * @wmi_handle: wmi handle 6800 * @param: pointer to coex config param 6801 * 6802 * Return: 0 for success or error code 6803 */ 6804 static QDF_STATUS 6805 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 6806 struct coex_config_params *param) 6807 { 6808 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 6809 wmi_buf_t buf; 6810 QDF_STATUS ret; 6811 int32_t len; 6812 6813 len = sizeof(*cmd); 6814 buf = wmi_buf_alloc(wmi_handle, len); 6815 if (!buf) 6816 return QDF_STATUS_E_FAILURE; 6817 6818 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 6819 WMITLV_SET_HDR(&cmd->tlv_header, 6820 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 6821 WMITLV_GET_STRUCT_TLVLEN( 6822 WMI_COEX_CONFIG_CMD_fixed_param)); 6823 6824 cmd->vdev_id = param->vdev_id; 6825 cmd->config_type = param->config_type; 6826 cmd->config_arg1 = param->config_arg1; 6827 cmd->config_arg2 = param->config_arg2; 6828 cmd->config_arg3 = param->config_arg3; 6829 cmd->config_arg4 = param->config_arg4; 6830 cmd->config_arg5 = param->config_arg5; 6831 cmd->config_arg6 = param->config_arg6; 6832 6833 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 6834 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6835 WMI_COEX_CONFIG_CMDID); 6836 6837 if (ret != 0) { 6838 WMI_LOGE("Sending COEX CONFIG CMD failed"); 6839 wmi_buf_free(buf); 6840 } 6841 6842 return ret; 6843 } 6844 6845 #ifdef WLAN_SUPPORT_TWT 6846 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 6847 target_resource_config *tgt_res_cfg) 6848 { 6849 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 6850 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 6851 } 6852 #else 6853 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 6854 target_resource_config *tgt_res_cfg) 6855 { 6856 resource_cfg->twt_ap_pdev_count = 0; 6857 resource_cfg->twt_ap_sta_count = 0; 6858 } 6859 #endif 6860 6861 static 6862 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 6863 target_resource_config *tgt_res_cfg) 6864 { 6865 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 6866 resource_cfg->num_peers = tgt_res_cfg->num_peers; 6867 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 6868 resource_cfg->num_offload_reorder_buffs = 6869 tgt_res_cfg->num_offload_reorder_buffs; 6870 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 6871 resource_cfg->num_tids = tgt_res_cfg->num_tids; 6872 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 6873 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 6874 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 6875 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 6876 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 6877 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 6878 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 6879 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 6880 resource_cfg->scan_max_pending_req = 6881 tgt_res_cfg->scan_max_pending_req; 6882 resource_cfg->bmiss_offload_max_vdev = 6883 tgt_res_cfg->bmiss_offload_max_vdev; 6884 resource_cfg->roam_offload_max_vdev = 6885 tgt_res_cfg->roam_offload_max_vdev; 6886 resource_cfg->roam_offload_max_ap_profiles = 6887 tgt_res_cfg->roam_offload_max_ap_profiles; 6888 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 6889 resource_cfg->num_mcast_table_elems = 6890 tgt_res_cfg->num_mcast_table_elems; 6891 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 6892 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 6893 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 6894 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 6895 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 6896 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 6897 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 6898 resource_cfg->vow_config = tgt_res_cfg->vow_config; 6899 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 6900 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 6901 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 6902 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 6903 resource_cfg->num_tdls_conn_table_entries = 6904 tgt_res_cfg->num_tdls_conn_table_entries; 6905 resource_cfg->beacon_tx_offload_max_vdev = 6906 tgt_res_cfg->beacon_tx_offload_max_vdev; 6907 resource_cfg->num_multicast_filter_entries = 6908 tgt_res_cfg->num_multicast_filter_entries; 6909 resource_cfg->num_wow_filters = 6910 tgt_res_cfg->num_wow_filters; 6911 resource_cfg->num_keep_alive_pattern = 6912 tgt_res_cfg->num_keep_alive_pattern; 6913 resource_cfg->keep_alive_pattern_size = 6914 tgt_res_cfg->keep_alive_pattern_size; 6915 resource_cfg->max_tdls_concurrent_sleep_sta = 6916 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 6917 resource_cfg->max_tdls_concurrent_buffer_sta = 6918 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 6919 resource_cfg->wmi_send_separate = 6920 tgt_res_cfg->wmi_send_separate; 6921 resource_cfg->num_ocb_vdevs = 6922 tgt_res_cfg->num_ocb_vdevs; 6923 resource_cfg->num_ocb_channels = 6924 tgt_res_cfg->num_ocb_channels; 6925 resource_cfg->num_ocb_schedules = 6926 tgt_res_cfg->num_ocb_schedules; 6927 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 6928 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 6929 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 6930 resource_cfg->max_num_dbs_scan_duty_cycle = 6931 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 6932 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 6933 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 6934 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 6935 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 6936 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 6937 /* Deferred AI: Max rnr neighbors supported in multisoc case 6938 * where in SoC can support 6ghz. During WMI init of a SoC 6939 * currently there is no way to figure if another SOC is plugged in 6940 * and it can support 6Ghz. 6941 */ 6942 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 6943 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 6944 resource_cfg->ema_max_profile_period = 6945 tgt_res_cfg->ema_max_profile_period; 6946 6947 if (tgt_res_cfg->max_ndp_sessions) 6948 resource_cfg->max_ndp_sessions = 6949 tgt_res_cfg->max_ndp_sessions; 6950 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 6951 6952 if (tgt_res_cfg->atf_config) 6953 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 6954 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 6955 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 6956 resource_cfg->flag1, 1); 6957 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 6958 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 6959 resource_cfg->flag1, 1); 6960 if (tgt_res_cfg->cce_disable) 6961 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 6962 if (tgt_res_cfg->eapol_minrate_set) { 6963 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 6964 resource_cfg->flag1, 1); 6965 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 6966 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 6967 resource_cfg->flag1, 1); 6968 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 6969 resource_cfg->flag1, 6970 tgt_res_cfg->eapol_minrate_ac_set); 6971 } 6972 } 6973 if (tgt_res_cfg->new_htt_msg_format) { 6974 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 6975 resource_cfg->flag1, 1); 6976 } 6977 6978 if (tgt_res_cfg->peer_unmap_conf_support) 6979 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 6980 resource_cfg->flag1, 1); 6981 6982 if (tgt_res_cfg->tstamp64_en) 6983 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 6984 resource_cfg->flag1, 1); 6985 6986 if (tgt_res_cfg->three_way_coex_config_legacy_en) 6987 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 6988 resource_cfg->flag1, 1); 6989 if (tgt_res_cfg->pktcapture_support) 6990 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 6991 resource_cfg->flag1, 1); 6992 6993 /* 6994 * Control padding using config param/ini of iphdr_pad_config 6995 */ 6996 if (tgt_res_cfg->iphdr_pad_config) 6997 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 6998 resource_cfg->flag1, 1); 6999 7000 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 7001 tgt_res_cfg->ipa_disable); 7002 7003 if (tgt_res_cfg->time_sync_ftm) 7004 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 7005 1); 7006 7007 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 7008 resource_cfg->peer_map_unmap_v2_support = 7009 tgt_res_cfg->peer_map_unmap_v2; 7010 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 7011 if (tgt_res_cfg->re_ul_resp) 7012 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 7013 tgt_res_cfg->re_ul_resp); 7014 7015 7016 /* 7017 * Enable ast flow override per peer 7018 */ 7019 resource_cfg->msdu_flow_override_config0 = 0; 7020 WMI_MSDU_FLOW_AST_ENABLE_SET( 7021 resource_cfg->msdu_flow_override_config0, 7022 WMI_CONFIG_MSDU_AST_INDEX_1, 7023 tgt_res_cfg->ast_1_valid_mask_enable); 7024 7025 WMI_MSDU_FLOW_AST_ENABLE_SET( 7026 resource_cfg->msdu_flow_override_config0, 7027 WMI_CONFIG_MSDU_AST_INDEX_2, 7028 tgt_res_cfg->ast_2_valid_mask_enable); 7029 7030 WMI_MSDU_FLOW_AST_ENABLE_SET( 7031 resource_cfg->msdu_flow_override_config0, 7032 WMI_CONFIG_MSDU_AST_INDEX_3, 7033 tgt_res_cfg->ast_3_valid_mask_enable); 7034 7035 /* 7036 * Enable ast flow mask and TID valid mask configurations 7037 */ 7038 resource_cfg->msdu_flow_override_config1 = 0; 7039 7040 /*Enable UDP flow for Ast index 0*/ 7041 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7042 resource_cfg->msdu_flow_override_config1, 7043 WMI_CONFIG_MSDU_AST_INDEX_0, 7044 tgt_res_cfg->ast_0_flow_mask_enable); 7045 7046 /*Enable Non UDP flow for Ast index 1*/ 7047 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7048 resource_cfg->msdu_flow_override_config1, 7049 WMI_CONFIG_MSDU_AST_INDEX_1, 7050 tgt_res_cfg->ast_1_flow_mask_enable); 7051 7052 /*Enable Hi-Priority flow for Ast index 2*/ 7053 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7054 resource_cfg->msdu_flow_override_config1, 7055 WMI_CONFIG_MSDU_AST_INDEX_2, 7056 tgt_res_cfg->ast_2_flow_mask_enable); 7057 7058 /*Enable Low-Priority flow for Ast index 3*/ 7059 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 7060 resource_cfg->msdu_flow_override_config1, 7061 WMI_CONFIG_MSDU_AST_INDEX_3, 7062 tgt_res_cfg->ast_3_flow_mask_enable); 7063 7064 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 7065 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 7066 resource_cfg->msdu_flow_override_config1, 7067 tgt_res_cfg->ast_tid_high_mask_enable); 7068 7069 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 7070 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 7071 resource_cfg->msdu_flow_override_config1, 7072 tgt_res_cfg->ast_tid_low_mask_enable); 7073 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 7074 resource_cfg->host_service_flags, 7075 tgt_res_cfg->nan_separate_iface_support); 7076 7077 } 7078 7079 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 7080 * @wmi_handle: pointer to wmi handle 7081 * @buf_ptr: pointer to current position in init command buffer 7082 * @len: pointer to length. This will be updated with current length of cmd 7083 * @param: point host parameters for init command 7084 * 7085 * Return: Updated pointer of buf_ptr. 7086 */ 7087 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 7088 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 7089 { 7090 uint16_t idx; 7091 7092 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 7093 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 7094 wmi_pdev_band_to_mac *band_to_mac; 7095 7096 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 7097 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 7098 sizeof(wmi_resource_config) + 7099 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 7100 sizeof(wlan_host_memory_chunk))); 7101 7102 WMITLV_SET_HDR(&hw_mode->tlv_header, 7103 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 7104 (WMITLV_GET_STRUCT_TLVLEN 7105 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 7106 7107 hw_mode->hw_mode_index = param->hw_mode_id; 7108 hw_mode->num_band_to_mac = param->num_band_to_mac; 7109 7110 buf_ptr = (uint8_t *) (hw_mode + 1); 7111 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 7112 WMI_TLV_HDR_SIZE); 7113 for (idx = 0; idx < param->num_band_to_mac; idx++) { 7114 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 7115 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 7116 WMITLV_GET_STRUCT_TLVLEN 7117 (wmi_pdev_band_to_mac)); 7118 band_to_mac[idx].pdev_id = 7119 wmi_handle->ops->convert_pdev_id_host_to_target( 7120 wmi_handle, 7121 param->band_to_mac[idx].pdev_id); 7122 band_to_mac[idx].start_freq = 7123 param->band_to_mac[idx].start_freq; 7124 band_to_mac[idx].end_freq = 7125 param->band_to_mac[idx].end_freq; 7126 } 7127 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 7128 (param->num_band_to_mac * 7129 sizeof(wmi_pdev_band_to_mac)) + 7130 WMI_TLV_HDR_SIZE; 7131 7132 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 7133 (param->num_band_to_mac * 7134 sizeof(wmi_pdev_band_to_mac))); 7135 } 7136 7137 return buf_ptr; 7138 } 7139 7140 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 7141 wmi_init_cmd_fixed_param *cmd) 7142 { 7143 int num_whitelist; 7144 wmi_abi_version my_vers; 7145 7146 num_whitelist = sizeof(version_whitelist) / 7147 sizeof(wmi_whitelist_version_info); 7148 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 7149 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 7150 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 7151 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 7152 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 7153 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 7154 7155 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, 7156 &my_vers, 7157 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 7158 &cmd->host_abi_vers); 7159 7160 qdf_print("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 7161 __func__, 7162 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 7163 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 7164 cmd->host_abi_vers.abi_version_ns_0, 7165 cmd->host_abi_vers.abi_version_ns_1, 7166 cmd->host_abi_vers.abi_version_ns_2, 7167 cmd->host_abi_vers.abi_version_ns_3); 7168 7169 /* Save version sent from host - 7170 * Will be used to check ready event 7171 */ 7172 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 7173 sizeof(wmi_abi_version)); 7174 } 7175 7176 /* 7177 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 7178 * @wmi_handle: Pointer to WMi handle 7179 * @ie_data: Pointer for ie data 7180 * 7181 * This function sends action frame tb ppdu cfg to FW 7182 * 7183 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7184 * 7185 */ 7186 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 7187 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 7188 { 7189 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 7190 wmi_buf_t buf; 7191 uint8_t *buf_ptr; 7192 uint32_t len, frm_len_aligned; 7193 QDF_STATUS ret; 7194 7195 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 7196 /* Allocate memory for the WMI command */ 7197 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 7198 7199 buf = wmi_buf_alloc(wmi_handle, len); 7200 if (!buf) 7201 return QDF_STATUS_E_NOMEM; 7202 7203 buf_ptr = wmi_buf_data(buf); 7204 qdf_mem_zero(buf_ptr, len); 7205 7206 /* Populate the WMI command */ 7207 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 7208 7209 WMITLV_SET_HDR(&cmd->tlv_header, 7210 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 7211 WMITLV_GET_STRUCT_TLVLEN( 7212 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 7213 cmd->enable = cfg_msg->cfg; 7214 cmd->data_len = cfg_msg->frm_len; 7215 7216 buf_ptr += sizeof(*cmd); 7217 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 7218 buf_ptr += WMI_TLV_HDR_SIZE; 7219 7220 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 7221 7222 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7223 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 7224 if (QDF_IS_STATUS_ERROR(ret)) { 7225 WMI_LOGE(FL("HE TB action frame cmnd send fail, ret %d"), ret); 7226 wmi_buf_free(buf); 7227 } 7228 7229 return ret; 7230 } 7231 7232 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 7233 { 7234 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 7235 wmi_service_ready_event_fixed_param *ev; 7236 7237 7238 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 7239 7240 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 7241 if (!ev) 7242 return QDF_STATUS_E_FAILURE; 7243 7244 /*Save fw version from service ready message */ 7245 /*This will be used while sending INIT message */ 7246 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7247 sizeof(wmi_handle->fw_abi_version)); 7248 7249 return QDF_STATUS_SUCCESS; 7250 } 7251 7252 /** 7253 * wmi_unified_save_fw_version_cmd() - save fw version 7254 * @wmi_handle: pointer to wmi handle 7255 * @res_cfg: resource config 7256 * @num_mem_chunks: no of mem chunck 7257 * @mem_chunk: pointer to mem chunck structure 7258 * 7259 * This function sends IE information to firmware 7260 * 7261 * Return: QDF_STATUS_SUCCESS for success otherwise failure 7262 * 7263 */ 7264 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 7265 void *evt_buf) 7266 { 7267 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 7268 wmi_ready_event_fixed_param *ev = NULL; 7269 7270 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 7271 ev = param_buf->fixed_param; 7272 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 7273 &wmi_handle->final_abi_vers, 7274 &ev->fw_abi_vers)) { 7275 /* 7276 * Error: Our host version and the given firmware version 7277 * are incompatible. 7278 **/ 7279 WMI_LOGD("%s: Error: Incompatible WMI version." 7280 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 7281 __func__, 7282 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 7283 abi_version_0), 7284 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 7285 abi_version_0), 7286 wmi_handle->final_abi_vers.abi_version_ns_0, 7287 wmi_handle->final_abi_vers.abi_version_ns_1, 7288 wmi_handle->final_abi_vers.abi_version_ns_2, 7289 wmi_handle->final_abi_vers.abi_version_ns_3, 7290 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 7291 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 7292 ev->fw_abi_vers.abi_version_ns_0, 7293 ev->fw_abi_vers.abi_version_ns_1, 7294 ev->fw_abi_vers.abi_version_ns_2, 7295 ev->fw_abi_vers.abi_version_ns_3); 7296 7297 return QDF_STATUS_E_FAILURE; 7298 } 7299 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 7300 sizeof(wmi_abi_version)); 7301 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 7302 sizeof(wmi_abi_version)); 7303 7304 return QDF_STATUS_SUCCESS; 7305 } 7306 7307 /** 7308 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 7309 * @handle: wmi handle 7310 * @event: Event received from FW 7311 * @len: Length of the event 7312 * 7313 * Enables the low frequency events and disables the high frequency 7314 * events. Bit 17 indicates if the event if low/high frequency. 7315 * 1 - high frequency, 0 - low frequency 7316 * 7317 * Return: 0 on successfully enabling/disabling the events 7318 */ 7319 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 7320 uint8_t *event, 7321 uint32_t len) 7322 { 7323 uint32_t num_of_diag_events_logs; 7324 wmi_diag_event_log_config_fixed_param *cmd; 7325 wmi_buf_t buf; 7326 uint8_t *buf_ptr; 7327 uint32_t *cmd_args, *evt_args; 7328 uint32_t buf_len, i; 7329 7330 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 7331 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 7332 7333 WMI_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 7334 7335 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 7336 if (!param_buf) { 7337 WMI_LOGE("Invalid log supported event buffer"); 7338 return QDF_STATUS_E_INVAL; 7339 } 7340 wmi_event = param_buf->fixed_param; 7341 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 7342 7343 if (num_of_diag_events_logs > 7344 param_buf->num_diag_events_logs_list) { 7345 WMI_LOGE("message number of events %d is more than tlv hdr content %d", 7346 num_of_diag_events_logs, 7347 param_buf->num_diag_events_logs_list); 7348 return QDF_STATUS_E_INVAL; 7349 } 7350 7351 evt_args = param_buf->diag_events_logs_list; 7352 if (!evt_args) { 7353 WMI_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d", 7354 __func__, num_of_diag_events_logs); 7355 return QDF_STATUS_E_INVAL; 7356 } 7357 7358 WMI_LOGD("%s: num_of_diag_events_logs=%d", 7359 __func__, num_of_diag_events_logs); 7360 7361 /* Free any previous allocation */ 7362 if (wmi_handle->events_logs_list) { 7363 qdf_mem_free(wmi_handle->events_logs_list); 7364 wmi_handle->events_logs_list = NULL; 7365 } 7366 7367 if (num_of_diag_events_logs > 7368 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 7369 WMI_LOGE("%s: excess num of logs:%d", __func__, 7370 num_of_diag_events_logs); 7371 QDF_ASSERT(0); 7372 return QDF_STATUS_E_INVAL; 7373 } 7374 /* Store the event list for run time enable/disable */ 7375 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 7376 sizeof(uint32_t)); 7377 if (!wmi_handle->events_logs_list) 7378 return QDF_STATUS_E_NOMEM; 7379 7380 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 7381 7382 /* Prepare the send buffer */ 7383 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7384 (num_of_diag_events_logs * sizeof(uint32_t)); 7385 7386 buf = wmi_buf_alloc(wmi_handle, buf_len); 7387 if (!buf) { 7388 qdf_mem_free(wmi_handle->events_logs_list); 7389 wmi_handle->events_logs_list = NULL; 7390 return QDF_STATUS_E_NOMEM; 7391 } 7392 7393 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7394 buf_ptr = (uint8_t *) cmd; 7395 7396 WMITLV_SET_HDR(&cmd->tlv_header, 7397 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7398 WMITLV_GET_STRUCT_TLVLEN( 7399 wmi_diag_event_log_config_fixed_param)); 7400 7401 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 7402 7403 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7404 7405 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7406 (num_of_diag_events_logs * sizeof(uint32_t))); 7407 7408 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7409 7410 /* Populate the events */ 7411 for (i = 0; i < num_of_diag_events_logs; i++) { 7412 /* Low freq (0) - Enable (1) the event 7413 * High freq (1) - Disable (0) the event 7414 */ 7415 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 7416 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 7417 /* Set the event ID */ 7418 WMI_DIAG_ID_SET(cmd_args[i], 7419 WMI_DIAG_ID_GET(evt_args[i])); 7420 /* Set the type */ 7421 WMI_DIAG_TYPE_SET(cmd_args[i], 7422 WMI_DIAG_TYPE_GET(evt_args[i])); 7423 /* Storing the event/log list in WMI */ 7424 wmi_handle->events_logs_list[i] = evt_args[i]; 7425 } 7426 7427 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7428 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 7429 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7430 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 7431 __func__); 7432 wmi_buf_free(buf); 7433 /* Not clearing events_logs_list, though wmi cmd failed. 7434 * Host can still have this list 7435 */ 7436 return QDF_STATUS_E_INVAL; 7437 } 7438 7439 return 0; 7440 } 7441 7442 /** 7443 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 7444 * @wmi_handle: wmi handle 7445 * @start_log: Start logging related parameters 7446 * 7447 * Send the command to the FW based on which specific logging of diag 7448 * event/log id can be started/stopped 7449 * 7450 * Return: None 7451 */ 7452 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 7453 struct wmi_wifi_start_log *start_log) 7454 { 7455 wmi_diag_event_log_config_fixed_param *cmd; 7456 wmi_buf_t buf; 7457 uint8_t *buf_ptr; 7458 uint32_t len, count, log_level, i; 7459 uint32_t *cmd_args; 7460 uint32_t total_len; 7461 count = 0; 7462 7463 if (!wmi_handle->events_logs_list) { 7464 WMI_LOGD("%s: Not received event/log list from FW, yet", 7465 __func__); 7466 return QDF_STATUS_E_NOMEM; 7467 } 7468 /* total_len stores the number of events where BITS 17 and 18 are set. 7469 * i.e., events of high frequency (17) and for extended debugging (18) 7470 */ 7471 total_len = 0; 7472 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 7473 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 7474 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 7475 total_len++; 7476 } 7477 7478 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 7479 (total_len * sizeof(uint32_t)); 7480 7481 buf = wmi_buf_alloc(wmi_handle, len); 7482 if (!buf) 7483 return QDF_STATUS_E_NOMEM; 7484 7485 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 7486 buf_ptr = (uint8_t *) cmd; 7487 7488 WMITLV_SET_HDR(&cmd->tlv_header, 7489 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 7490 WMITLV_GET_STRUCT_TLVLEN( 7491 wmi_diag_event_log_config_fixed_param)); 7492 7493 cmd->num_of_diag_events_logs = total_len; 7494 7495 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 7496 7497 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7498 (total_len * sizeof(uint32_t))); 7499 7500 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 7501 7502 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 7503 log_level = 1; 7504 else 7505 log_level = 0; 7506 7507 WMI_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level); 7508 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 7509 uint32_t val = wmi_handle->events_logs_list[i]; 7510 if ((WMI_DIAG_FREQUENCY_GET(val)) && 7511 (WMI_DIAG_EXT_FEATURE_GET(val))) { 7512 7513 WMI_DIAG_ID_SET(cmd_args[count], 7514 WMI_DIAG_ID_GET(val)); 7515 WMI_DIAG_TYPE_SET(cmd_args[count], 7516 WMI_DIAG_TYPE_GET(val)); 7517 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 7518 log_level); 7519 WMI_LOGD("%s: Idx:%d, val:%x", __func__, i, val); 7520 count++; 7521 } 7522 } 7523 7524 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 7525 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7526 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 7527 WMI_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed", 7528 __func__); 7529 wmi_buf_free(buf); 7530 return QDF_STATUS_E_INVAL; 7531 } 7532 7533 return QDF_STATUS_SUCCESS; 7534 } 7535 7536 /** 7537 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 7538 * @wmi_handle: WMI handle 7539 * 7540 * This function is used to send the flush command to the FW, 7541 * that will flush the fw logs that are residue in the FW 7542 * 7543 * Return: None 7544 */ 7545 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 7546 { 7547 wmi_debug_mesg_flush_fixed_param *cmd; 7548 wmi_buf_t buf; 7549 int len = sizeof(*cmd); 7550 QDF_STATUS ret; 7551 7552 buf = wmi_buf_alloc(wmi_handle, len); 7553 if (!buf) 7554 return QDF_STATUS_E_NOMEM; 7555 7556 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 7557 WMITLV_SET_HDR(&cmd->tlv_header, 7558 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 7559 WMITLV_GET_STRUCT_TLVLEN( 7560 wmi_debug_mesg_flush_fixed_param)); 7561 cmd->reserved0 = 0; 7562 7563 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 7564 ret = wmi_unified_cmd_send(wmi_handle, 7565 buf, 7566 len, 7567 WMI_DEBUG_MESG_FLUSH_CMDID); 7568 if (QDF_IS_STATUS_ERROR(ret)) { 7569 WMI_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 7570 wmi_buf_free(buf); 7571 return QDF_STATUS_E_INVAL; 7572 } 7573 WMI_LOGD("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 7574 7575 return ret; 7576 } 7577 7578 #ifdef BIG_ENDIAN_HOST 7579 /** 7580 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 7581 * @param data_len - data length 7582 * @param data - pointer to data 7583 * 7584 * Return: QDF_STATUS - success or error status 7585 */ 7586 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 7587 struct fips_params *param) 7588 { 7589 unsigned char *key_unaligned, *data_unaligned; 7590 int c; 7591 u_int8_t *key_aligned = NULL; 7592 u_int8_t *data_aligned = NULL; 7593 7594 /* Assigning unaligned space to copy the key */ 7595 key_unaligned = qdf_mem_malloc( 7596 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 7597 data_unaligned = qdf_mem_malloc( 7598 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 7599 7600 /* Checking if kmalloc is successful to allocate space */ 7601 if (!key_unaligned) 7602 return QDF_STATUS_SUCCESS; 7603 /* Checking if space is aligned */ 7604 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 7605 /* align to 4 */ 7606 key_aligned = 7607 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 7608 FIPS_ALIGN); 7609 } else { 7610 key_aligned = (u_int8_t *)key_unaligned; 7611 } 7612 7613 /* memset and copy content from key to key aligned */ 7614 OS_MEMSET(key_aligned, 0, param->key_len); 7615 OS_MEMCPY(key_aligned, param->key, param->key_len); 7616 7617 /* print a hexdump for host debug */ 7618 print_hex_dump(KERN_DEBUG, 7619 "\t Aligned and Copied Key:@@@@ ", 7620 DUMP_PREFIX_NONE, 7621 16, 1, key_aligned, param->key_len, true); 7622 7623 /* Checking if kmalloc is successful to allocate space */ 7624 if (!data_unaligned) 7625 return QDF_STATUS_SUCCESS; 7626 /* Checking of space is aligned */ 7627 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 7628 /* align to 4 */ 7629 data_aligned = 7630 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 7631 FIPS_ALIGN); 7632 } else { 7633 data_aligned = (u_int8_t *)data_unaligned; 7634 } 7635 7636 /* memset and copy content from data to data aligned */ 7637 OS_MEMSET(data_aligned, 0, param->data_len); 7638 OS_MEMCPY(data_aligned, param->data, param->data_len); 7639 7640 /* print a hexdump for host debug */ 7641 print_hex_dump(KERN_DEBUG, 7642 "\t Properly Aligned and Copied Data:@@@@ ", 7643 DUMP_PREFIX_NONE, 7644 16, 1, data_aligned, param->data_len, true); 7645 7646 /* converting to little Endian both key_aligned and 7647 * data_aligned*/ 7648 for (c = 0; c < param->key_len/4; c++) { 7649 *((u_int32_t *)key_aligned+c) = 7650 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 7651 } 7652 for (c = 0; c < param->data_len/4; c++) { 7653 *((u_int32_t *)data_aligned+c) = 7654 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 7655 } 7656 7657 /* update endian data to key and data vectors */ 7658 OS_MEMCPY(param->key, key_aligned, param->key_len); 7659 OS_MEMCPY(param->data, data_aligned, param->data_len); 7660 7661 /* clean up allocated spaces */ 7662 qdf_mem_free(key_unaligned); 7663 key_unaligned = NULL; 7664 key_aligned = NULL; 7665 7666 qdf_mem_free(data_unaligned); 7667 data_unaligned = NULL; 7668 data_aligned = NULL; 7669 7670 return QDF_STATUS_SUCCESS; 7671 } 7672 #else 7673 /** 7674 * fips_align_data_be() - DUMMY for LE platform 7675 * 7676 * Return: QDF_STATUS - success 7677 */ 7678 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 7679 struct fips_params *param) 7680 { 7681 return QDF_STATUS_SUCCESS; 7682 } 7683 #endif 7684 7685 #ifdef WLAN_FEATURE_DISA 7686 /** 7687 * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw 7688 * @wmi_handle: wmi handle 7689 * @params: encrypt/decrypt params 7690 * 7691 * Return: QDF_STATUS_SUCCESS for success or error code 7692 */ 7693 static QDF_STATUS 7694 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 7695 struct disa_encrypt_decrypt_req_params 7696 *encrypt_decrypt_params) 7697 { 7698 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 7699 wmi_buf_t wmi_buf; 7700 uint8_t *buf_ptr; 7701 QDF_STATUS ret; 7702 uint32_t len; 7703 7704 WMI_LOGD(FL("Send encrypt decrypt cmd")); 7705 7706 len = sizeof(*cmd) + 7707 encrypt_decrypt_params->data_len + 7708 WMI_TLV_HDR_SIZE; 7709 wmi_buf = wmi_buf_alloc(wmi_handle, len); 7710 if (!wmi_buf) 7711 return QDF_STATUS_E_NOMEM; 7712 7713 buf_ptr = wmi_buf_data(wmi_buf); 7714 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 7715 7716 WMITLV_SET_HDR(&cmd->tlv_header, 7717 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 7718 WMITLV_GET_STRUCT_TLVLEN( 7719 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 7720 7721 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 7722 cmd->key_flag = encrypt_decrypt_params->key_flag; 7723 cmd->key_idx = encrypt_decrypt_params->key_idx; 7724 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 7725 cmd->key_len = encrypt_decrypt_params->key_len; 7726 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 7727 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 7728 7729 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 7730 encrypt_decrypt_params->key_len); 7731 7732 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 7733 MAX_MAC_HEADER_LEN); 7734 7735 cmd->data_len = encrypt_decrypt_params->data_len; 7736 7737 if (cmd->data_len) { 7738 buf_ptr += sizeof(*cmd); 7739 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 7740 roundup(encrypt_decrypt_params->data_len, 7741 sizeof(uint32_t))); 7742 buf_ptr += WMI_TLV_HDR_SIZE; 7743 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 7744 encrypt_decrypt_params->data_len); 7745 } 7746 7747 /* This conversion is to facilitate data to FW in little endian */ 7748 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 7749 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 7750 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 7751 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 7752 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 7753 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 7754 7755 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 7756 ret = wmi_unified_cmd_send(wmi_handle, 7757 wmi_buf, len, 7758 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 7759 if (QDF_IS_STATUS_ERROR(ret)) { 7760 WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 7761 wmi_buf_free(wmi_buf); 7762 } 7763 7764 return ret; 7765 } 7766 #endif /* WLAN_FEATURE_DISA */ 7767 7768 /** 7769 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 7770 * @wmi_handle: wmi handle 7771 * @param: pointer to hold pdev fips param 7772 * 7773 * Return: 0 for success or error code 7774 */ 7775 static QDF_STATUS 7776 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 7777 struct fips_params *param) 7778 { 7779 wmi_pdev_fips_cmd_fixed_param *cmd; 7780 wmi_buf_t buf; 7781 uint8_t *buf_ptr; 7782 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 7783 QDF_STATUS retval = QDF_STATUS_SUCCESS; 7784 7785 /* Length TLV placeholder for array of bytes */ 7786 len += WMI_TLV_HDR_SIZE; 7787 if (param->data_len) 7788 len += (param->data_len*sizeof(uint8_t)); 7789 7790 /* 7791 * Data length must be multiples of 16 bytes - checked against 0xF - 7792 * and must be less than WMI_SVC_MSG_SIZE - static size of 7793 * wmi_pdev_fips_cmd structure 7794 */ 7795 7796 /* do sanity on the input */ 7797 if (!(((param->data_len & 0xF) == 0) && 7798 ((param->data_len > 0) && 7799 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 7800 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 7801 return QDF_STATUS_E_INVAL; 7802 } 7803 7804 buf = wmi_buf_alloc(wmi_handle, len); 7805 if (!buf) 7806 return QDF_STATUS_E_FAILURE; 7807 7808 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7809 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 7810 WMITLV_SET_HDR(&cmd->tlv_header, 7811 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 7812 WMITLV_GET_STRUCT_TLVLEN 7813 (wmi_pdev_fips_cmd_fixed_param)); 7814 7815 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7816 wmi_handle, 7817 param->pdev_id); 7818 if (param->key && param->data) { 7819 cmd->key_len = param->key_len; 7820 cmd->data_len = param->data_len; 7821 cmd->fips_cmd = !!(param->op); 7822 7823 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 7824 return QDF_STATUS_E_FAILURE; 7825 7826 qdf_mem_copy(cmd->key, param->key, param->key_len); 7827 7828 if (param->mode == FIPS_ENGINE_AES_CTR || 7829 param->mode == FIPS_ENGINE_AES_MIC) { 7830 cmd->mode = param->mode; 7831 } else { 7832 cmd->mode = FIPS_ENGINE_AES_CTR; 7833 } 7834 qdf_print("Key len = %d, Data len = %d", 7835 cmd->key_len, cmd->data_len); 7836 7837 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 7838 cmd->key, cmd->key_len, true); 7839 buf_ptr += sizeof(*cmd); 7840 7841 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 7842 7843 buf_ptr += WMI_TLV_HDR_SIZE; 7844 if (param->data_len) 7845 qdf_mem_copy(buf_ptr, 7846 (uint8_t *) param->data, param->data_len); 7847 7848 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 7849 16, 1, buf_ptr, cmd->data_len, true); 7850 7851 buf_ptr += param->data_len; 7852 7853 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 7854 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 7855 WMI_PDEV_FIPS_CMDID); 7856 qdf_print("%s return value %d", __func__, retval); 7857 } else { 7858 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 7859 wmi_buf_free(buf); 7860 retval = -QDF_STATUS_E_BADMSG; 7861 } 7862 7863 return retval; 7864 } 7865 7866 /** 7867 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 7868 * to fw 7869 * @wmi_handle: wmi handle 7870 * @param: pointer to wlan profile param 7871 * 7872 * Return: 0 for success or error code 7873 */ 7874 static QDF_STATUS 7875 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 7876 struct wlan_profile_params *param) 7877 { 7878 wmi_buf_t buf; 7879 uint16_t len; 7880 QDF_STATUS ret; 7881 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 7882 7883 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 7884 buf = wmi_buf_alloc(wmi_handle, len); 7885 if (!buf) { 7886 WMI_LOGE("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 7887 return QDF_STATUS_E_NOMEM; 7888 } 7889 7890 profile_enable_cmd = 7891 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 7892 wmi_buf_data(buf); 7893 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 7894 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 7895 WMITLV_GET_STRUCT_TLVLEN 7896 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 7897 7898 profile_enable_cmd->profile_id = param->profile_id; 7899 profile_enable_cmd->enable = param->enable; 7900 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 7901 NO_SESSION, 0); 7902 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7903 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 7904 if (ret) { 7905 WMI_LOGE("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 7906 wmi_buf_free(buf); 7907 } 7908 return ret; 7909 } 7910 7911 /** 7912 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 7913 * to fw 7914 * @wmi_handle: wmi handle 7915 * @param: pointer to wlan profile param 7916 * 7917 * Return: 0 for success or error code 7918 */ 7919 static QDF_STATUS 7920 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 7921 struct wlan_profile_params *param) 7922 { 7923 wmi_buf_t buf; 7924 uint16_t len; 7925 QDF_STATUS ret; 7926 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 7927 7928 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 7929 buf = wmi_buf_alloc(wmi_handle, len); 7930 if (!buf) { 7931 WMI_LOGE("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 7932 return QDF_STATUS_E_NOMEM; 7933 } 7934 7935 prof_trig_cmd = 7936 (wmi_wlan_profile_trigger_cmd_fixed_param *) 7937 wmi_buf_data(buf); 7938 7939 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 7940 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 7941 WMITLV_GET_STRUCT_TLVLEN 7942 (wmi_wlan_profile_trigger_cmd_fixed_param)); 7943 7944 prof_trig_cmd->enable = param->enable; 7945 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 7946 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7947 WMI_WLAN_PROFILE_TRIGGER_CMDID); 7948 if (ret) { 7949 WMI_LOGE("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 7950 wmi_buf_free(buf); 7951 } 7952 return ret; 7953 } 7954 7955 /** 7956 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 7957 * to fw 7958 * @wmi_handle: wmi handle 7959 * @param: pointer to wlan profile param 7960 * 7961 * Return: 0 for success or error code 7962 */ 7963 static QDF_STATUS 7964 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 7965 struct wlan_profile_params *param) 7966 { 7967 wmi_buf_t buf; 7968 int32_t len = 0; 7969 QDF_STATUS ret; 7970 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 7971 7972 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 7973 buf = wmi_buf_alloc(wmi_handle, len); 7974 if (!buf) { 7975 WMI_LOGE("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 7976 return QDF_STATUS_E_NOMEM; 7977 } 7978 7979 hist_intvl_cmd = 7980 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 7981 wmi_buf_data(buf); 7982 7983 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 7984 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 7985 WMITLV_GET_STRUCT_TLVLEN 7986 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 7987 7988 hist_intvl_cmd->profile_id = param->profile_id; 7989 hist_intvl_cmd->value = param->enable; 7990 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 7991 NO_SESSION, 0); 7992 7993 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7994 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 7995 if (ret) { 7996 WMI_LOGE("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 7997 wmi_buf_free(buf); 7998 } 7999 return ret; 8000 } 8001 8002 /** 8003 * send_fw_test_cmd_tlv() - send fw test command to fw. 8004 * @wmi_handle: wmi handle 8005 * @wmi_fwtest: fw test command 8006 * 8007 * This function sends fw test command to fw. 8008 * 8009 * Return: CDF STATUS 8010 */ 8011 static 8012 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 8013 struct set_fwtest_params *wmi_fwtest) 8014 { 8015 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8016 wmi_buf_t wmi_buf; 8017 uint16_t len; 8018 8019 len = sizeof(*cmd); 8020 8021 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8022 if (!wmi_buf) 8023 return QDF_STATUS_E_NOMEM; 8024 8025 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 8026 WMITLV_SET_HDR(&cmd->tlv_header, 8027 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8028 WMITLV_GET_STRUCT_TLVLEN( 8029 wmi_fwtest_set_param_cmd_fixed_param)); 8030 cmd->param_id = wmi_fwtest->arg; 8031 cmd->param_value = wmi_fwtest->value; 8032 8033 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8034 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8035 WMI_FWTEST_CMDID)) { 8036 WMI_LOGP("%s: failed to send fw test command", __func__); 8037 wmi_buf_free(wmi_buf); 8038 return QDF_STATUS_E_FAILURE; 8039 } 8040 8041 return QDF_STATUS_SUCCESS; 8042 } 8043 8044 /** 8045 * send_unit_test_cmd_tlv() - send unit test command to fw. 8046 * @wmi_handle: wmi handle 8047 * @wmi_utest: unit test command 8048 * 8049 * This function send unit test command to fw. 8050 * 8051 * Return: CDF STATUS 8052 */ 8053 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 8054 struct wmi_unit_test_cmd *wmi_utest) 8055 { 8056 wmi_unit_test_cmd_fixed_param *cmd; 8057 wmi_buf_t wmi_buf; 8058 uint8_t *buf_ptr; 8059 int i; 8060 uint16_t len, args_tlv_len; 8061 uint32_t *unit_test_cmd_args; 8062 8063 args_tlv_len = 8064 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 8065 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 8066 8067 wmi_buf = wmi_buf_alloc(wmi_handle, len); 8068 if (!wmi_buf) 8069 return QDF_STATUS_E_NOMEM; 8070 8071 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 8072 buf_ptr = (uint8_t *) cmd; 8073 WMITLV_SET_HDR(&cmd->tlv_header, 8074 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 8075 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 8076 cmd->vdev_id = wmi_utest->vdev_id; 8077 cmd->module_id = wmi_utest->module_id; 8078 cmd->num_args = wmi_utest->num_args; 8079 cmd->diag_token = wmi_utest->diag_token; 8080 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 8081 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8082 (wmi_utest->num_args * sizeof(uint32_t))); 8083 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8084 WMI_LOGI("%s: VDEV ID: %d", __func__, cmd->vdev_id); 8085 WMI_LOGI("%s: MODULE ID: %d", __func__, cmd->module_id); 8086 WMI_LOGI("%s: TOKEN: %d", __func__, cmd->diag_token); 8087 WMI_LOGI("%s: %d num of args = ", __func__, wmi_utest->num_args); 8088 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 8089 unit_test_cmd_args[i] = wmi_utest->args[i]; 8090 WMI_LOGI("%d,", wmi_utest->args[i]); 8091 } 8092 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 8093 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 8094 WMI_UNIT_TEST_CMDID)) { 8095 WMI_LOGP("%s: failed to send unit test command", __func__); 8096 wmi_buf_free(wmi_buf); 8097 return QDF_STATUS_E_FAILURE; 8098 } 8099 8100 return QDF_STATUS_SUCCESS; 8101 } 8102 8103 /** 8104 * send_power_dbg_cmd_tlv() - send power debug commands 8105 * @wmi_handle: wmi handle 8106 * @param: wmi power debug parameter 8107 * 8108 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 8109 * 8110 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8111 */ 8112 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 8113 struct wmi_power_dbg_params *param) 8114 { 8115 wmi_buf_t buf = NULL; 8116 QDF_STATUS status; 8117 int len, args_tlv_len; 8118 uint8_t *buf_ptr; 8119 uint8_t i; 8120 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 8121 uint32_t *cmd_args; 8122 8123 /* Prepare and send power debug cmd parameters */ 8124 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 8125 len = sizeof(*cmd) + args_tlv_len; 8126 buf = wmi_buf_alloc(wmi_handle, len); 8127 if (!buf) 8128 return QDF_STATUS_E_NOMEM; 8129 8130 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8131 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 8132 WMITLV_SET_HDR(&cmd->tlv_header, 8133 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 8134 WMITLV_GET_STRUCT_TLVLEN 8135 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 8136 8137 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8138 wmi_handle, 8139 param->pdev_id); 8140 cmd->module_id = param->module_id; 8141 cmd->num_args = param->num_args; 8142 buf_ptr += sizeof(*cmd); 8143 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 8144 (param->num_args * sizeof(uint32_t))); 8145 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 8146 WMI_LOGI("%s: %d num of args = ", __func__, param->num_args); 8147 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 8148 cmd_args[i] = param->args[i]; 8149 WMI_LOGI("%d,", param->args[i]); 8150 } 8151 8152 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 8153 status = wmi_unified_cmd_send(wmi_handle, buf, 8154 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 8155 if (QDF_IS_STATUS_ERROR(status)) { 8156 WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 8157 status); 8158 goto error; 8159 } 8160 8161 return QDF_STATUS_SUCCESS; 8162 error: 8163 wmi_buf_free(buf); 8164 8165 return status; 8166 } 8167 8168 /** 8169 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 8170 * @wmi_handle: wmi handle 8171 * @pdev_id: pdev id 8172 * 8173 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 8174 * 8175 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8176 */ 8177 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 8178 uint32_t pdev_id) 8179 { 8180 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 8181 wmi_buf_t buf; 8182 uint16_t len; 8183 QDF_STATUS ret; 8184 8185 len = sizeof(*cmd); 8186 buf = wmi_buf_alloc(wmi_handle, len); 8187 8188 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 8189 8190 if (!buf) 8191 return QDF_STATUS_E_NOMEM; 8192 8193 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 8194 wmi_buf_data(buf); 8195 8196 WMITLV_SET_HDR(&cmd->tlv_header, 8197 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 8198 WMITLV_GET_STRUCT_TLVLEN( 8199 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 8200 8201 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8202 wmi_handle, 8203 pdev_id); 8204 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 8205 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8206 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 8207 if (QDF_IS_STATUS_ERROR(ret)) { 8208 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 8209 __func__, ret, pdev_id); 8210 wmi_buf_free(buf); 8211 return QDF_STATUS_E_FAILURE; 8212 } 8213 8214 return QDF_STATUS_SUCCESS; 8215 } 8216 8217 /** 8218 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 8219 * @wmi_handle: wmi handle 8220 * @pdev_id: pdev id 8221 * 8222 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 8223 * 8224 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 8225 */ 8226 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 8227 uint32_t pdev_id) 8228 { 8229 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 8230 wmi_buf_t buf; 8231 uint16_t len; 8232 QDF_STATUS ret; 8233 8234 len = sizeof(*cmd); 8235 buf = wmi_buf_alloc(wmi_handle, len); 8236 8237 WMI_LOGI("%s: pdev_id=%d", __func__, pdev_id); 8238 8239 if (!buf) 8240 return QDF_STATUS_E_NOMEM; 8241 8242 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 8243 wmi_buf_data(buf); 8244 8245 WMITLV_SET_HDR(&cmd->tlv_header, 8246 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 8247 WMITLV_GET_STRUCT_TLVLEN( 8248 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 8249 8250 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8251 wmi_handle, 8252 pdev_id); 8253 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 8254 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8255 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 8256 if (QDF_IS_STATUS_ERROR(ret)) { 8257 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d, pdev_id=%d", 8258 __func__, ret, pdev_id); 8259 wmi_buf_free(buf); 8260 return QDF_STATUS_E_FAILURE; 8261 } 8262 8263 return QDF_STATUS_SUCCESS; 8264 } 8265 8266 #ifdef QCA_SUPPORT_AGILE_DFS 8267 static 8268 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 8269 struct vdev_adfs_ch_cfg_params *param) 8270 { 8271 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 8272 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 8273 wmi_buf_t buf; 8274 QDF_STATUS ret; 8275 uint16_t len; 8276 8277 len = sizeof(*cmd); 8278 buf = wmi_buf_alloc(wmi_handle, len); 8279 8280 if (!buf) { 8281 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8282 return QDF_STATUS_E_NOMEM; 8283 } 8284 8285 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 8286 wmi_buf_data(buf); 8287 8288 WMITLV_SET_HDR(&cmd->tlv_header, 8289 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 8290 WMITLV_GET_STRUCT_TLVLEN 8291 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 8292 8293 cmd->vdev_id = param->vdev_id; 8294 cmd->ocac_mode = param->ocac_mode; 8295 cmd->center_freq1 = param->center_freq1; 8296 cmd->center_freq2 = param->center_freq2; 8297 cmd->chan_freq = param->chan_freq; 8298 cmd->chan_width = param->chan_width; 8299 cmd->min_duration_ms = param->min_duration_ms; 8300 cmd->max_duration_ms = param->max_duration_ms; 8301 WMI_LOGD("%s:cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 8302 __func__, cmd->vdev_id, cmd->ocac_mode, 8303 cmd->center_freq); 8304 8305 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 8306 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8307 WMI_VDEV_ADFS_CH_CFG_CMDID); 8308 8309 if (QDF_IS_STATUS_ERROR(ret)) { 8310 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", 8311 __func__, ret); 8312 wmi_buf_free(buf); 8313 return QDF_STATUS_E_FAILURE; 8314 } 8315 8316 return QDF_STATUS_SUCCESS; 8317 } 8318 8319 static 8320 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 8321 struct vdev_adfs_abort_params *param) 8322 { 8323 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 8324 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 8325 wmi_buf_t buf; 8326 QDF_STATUS ret; 8327 uint16_t len; 8328 8329 len = sizeof(*cmd); 8330 buf = wmi_buf_alloc(wmi_handle, len); 8331 8332 if (!buf) { 8333 WMI_LOGE("%s : wmi_buf_alloc failed", __func__); 8334 return QDF_STATUS_E_NOMEM; 8335 } 8336 8337 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 8338 wmi_buf_data(buf); 8339 8340 WMITLV_SET_HDR 8341 (&cmd->tlv_header, 8342 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 8343 WMITLV_GET_STRUCT_TLVLEN 8344 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 8345 8346 cmd->vdev_id = param->vdev_id; 8347 8348 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 8349 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8350 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 8351 8352 if (QDF_IS_STATUS_ERROR(ret)) { 8353 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", 8354 __func__, ret); 8355 wmi_buf_free(buf); 8356 return QDF_STATUS_E_FAILURE; 8357 } 8358 8359 return QDF_STATUS_SUCCESS; 8360 } 8361 #endif 8362 8363 /** 8364 * is_service_enabled_tlv() - Check if service enabled 8365 * @param wmi_handle: wmi handle 8366 * @param service_id: service identifier 8367 * 8368 * Return: 1 enabled, 0 disabled 8369 */ 8370 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 8371 uint32_t service_id) 8372 { 8373 struct wmi_soc *soc = wmi_handle->soc; 8374 8375 if (!soc->wmi_service_bitmap) { 8376 WMI_LOGE("WMI service bit map is not saved yet"); 8377 return false; 8378 } 8379 8380 /* if wmi_service_enabled was received with extended bitmap, 8381 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 8382 */ 8383 if (soc->wmi_ext_service_bitmap) 8384 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 8385 soc->wmi_ext_service_bitmap, 8386 service_id); 8387 8388 if (service_id >= WMI_MAX_SERVICE) { 8389 WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", 8390 service_id); 8391 return false; 8392 } 8393 8394 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 8395 service_id); 8396 } 8397 8398 /** 8399 * init_cmd_send_tlv() - send initialization cmd to fw 8400 * @wmi_handle: wmi handle 8401 * @param param: pointer to wmi init param 8402 * 8403 * Return: QDF_STATUS_SUCCESS for success or error code 8404 */ 8405 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 8406 struct wmi_init_cmd_param *param) 8407 { 8408 wmi_buf_t buf; 8409 wmi_init_cmd_fixed_param *cmd; 8410 uint8_t *buf_ptr; 8411 wmi_resource_config *resource_cfg; 8412 wlan_host_memory_chunk *host_mem_chunks; 8413 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 8414 uint16_t idx; 8415 int len; 8416 QDF_STATUS ret; 8417 8418 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 8419 WMI_TLV_HDR_SIZE; 8420 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 8421 8422 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 8423 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 8424 WMI_TLV_HDR_SIZE + 8425 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 8426 8427 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 8428 if (!buf) 8429 return QDF_STATUS_E_FAILURE; 8430 8431 buf_ptr = (uint8_t *) wmi_buf_data(buf); 8432 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 8433 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 8434 8435 host_mem_chunks = (wlan_host_memory_chunk *) 8436 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 8437 + WMI_TLV_HDR_SIZE); 8438 8439 WMITLV_SET_HDR(&cmd->tlv_header, 8440 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 8441 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 8442 8443 wmi_copy_resource_config(resource_cfg, param->res_cfg); 8444 WMITLV_SET_HDR(&resource_cfg->tlv_header, 8445 WMITLV_TAG_STRUC_wmi_resource_config, 8446 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 8447 8448 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 8449 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 8450 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 8451 WMITLV_GET_STRUCT_TLVLEN 8452 (wlan_host_memory_chunk)); 8453 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 8454 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 8455 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 8456 if (is_service_enabled_tlv(wmi_handle, 8457 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 8458 host_mem_chunks[idx].ptr_high = 8459 qdf_get_upper_32_bits( 8460 param->mem_chunks[idx].paddr); 8461 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 8462 "chunk %d len %d requested ,ptr 0x%x ", 8463 idx, host_mem_chunks[idx].size, 8464 host_mem_chunks[idx].ptr); 8465 } 8466 cmd->num_host_mem_chunks = param->num_mem_chunks; 8467 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 8468 8469 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 8470 WMITLV_TAG_ARRAY_STRUC, 8471 (sizeof(wlan_host_memory_chunk) * 8472 param->num_mem_chunks)); 8473 8474 /* Fill hw mode id config */ 8475 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 8476 8477 /* Fill fw_abi_vers */ 8478 copy_fw_abi_version_tlv(wmi_handle, cmd); 8479 8480 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 8481 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 8482 if (QDF_IS_STATUS_ERROR(ret)) { 8483 WMI_LOGE("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 8484 ret); 8485 wmi_buf_free(buf); 8486 } 8487 8488 return ret; 8489 8490 } 8491 8492 /** 8493 * send_addba_send_cmd_tlv() - send addba send command to fw 8494 * @wmi_handle: wmi handle 8495 * @param: pointer to delba send params 8496 * @macaddr: peer mac address 8497 * 8498 * Send WMI_ADDBA_SEND_CMDID command to firmware 8499 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 8500 */ 8501 static QDF_STATUS 8502 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 8503 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8504 struct addba_send_params *param) 8505 { 8506 wmi_addba_send_cmd_fixed_param *cmd; 8507 wmi_buf_t buf; 8508 uint16_t len; 8509 QDF_STATUS ret; 8510 8511 len = sizeof(*cmd); 8512 8513 buf = wmi_buf_alloc(wmi_handle, len); 8514 if (!buf) 8515 return QDF_STATUS_E_NOMEM; 8516 8517 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 8518 8519 WMITLV_SET_HDR(&cmd->tlv_header, 8520 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 8521 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 8522 8523 cmd->vdev_id = param->vdev_id; 8524 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8525 cmd->tid = param->tidno; 8526 cmd->buffersize = param->buffersize; 8527 8528 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 8529 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 8530 if (QDF_IS_STATUS_ERROR(ret)) { 8531 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 8532 wmi_buf_free(buf); 8533 return QDF_STATUS_E_FAILURE; 8534 } 8535 8536 return QDF_STATUS_SUCCESS; 8537 } 8538 8539 /** 8540 * send_delba_send_cmd_tlv() - send delba send command to fw 8541 * @wmi_handle: wmi handle 8542 * @param: pointer to delba send params 8543 * @macaddr: peer mac address 8544 * 8545 * Send WMI_DELBA_SEND_CMDID command to firmware 8546 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 8547 */ 8548 static QDF_STATUS 8549 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 8550 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8551 struct delba_send_params *param) 8552 { 8553 wmi_delba_send_cmd_fixed_param *cmd; 8554 wmi_buf_t buf; 8555 uint16_t len; 8556 QDF_STATUS ret; 8557 8558 len = sizeof(*cmd); 8559 8560 buf = wmi_buf_alloc(wmi_handle, len); 8561 if (!buf) 8562 return QDF_STATUS_E_NOMEM; 8563 8564 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 8565 8566 WMITLV_SET_HDR(&cmd->tlv_header, 8567 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 8568 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 8569 8570 cmd->vdev_id = param->vdev_id; 8571 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8572 cmd->tid = param->tidno; 8573 cmd->initiator = param->initiator; 8574 cmd->reasoncode = param->reasoncode; 8575 8576 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 8577 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 8578 if (QDF_IS_STATUS_ERROR(ret)) { 8579 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 8580 wmi_buf_free(buf); 8581 return QDF_STATUS_E_FAILURE; 8582 } 8583 8584 return QDF_STATUS_SUCCESS; 8585 } 8586 8587 /** 8588 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 8589 * to fw 8590 * @wmi_handle: wmi handle 8591 * @param: pointer to addba clearresp params 8592 * @macaddr: peer mac address 8593 * Return: 0 for success or error code 8594 */ 8595 static QDF_STATUS 8596 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 8597 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 8598 struct addba_clearresponse_params *param) 8599 { 8600 wmi_addba_clear_resp_cmd_fixed_param *cmd; 8601 wmi_buf_t buf; 8602 uint16_t len; 8603 QDF_STATUS ret; 8604 8605 len = sizeof(*cmd); 8606 8607 buf = wmi_buf_alloc(wmi_handle, len); 8608 if (!buf) 8609 return QDF_STATUS_E_FAILURE; 8610 8611 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 8612 8613 WMITLV_SET_HDR(&cmd->tlv_header, 8614 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 8615 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 8616 8617 cmd->vdev_id = param->vdev_id; 8618 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 8619 8620 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 8621 ret = wmi_unified_cmd_send(wmi_handle, 8622 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 8623 if (QDF_IS_STATUS_ERROR(ret)) { 8624 WMI_LOGE("%s: Failed to send cmd to fw, ret=%d", __func__, ret); 8625 wmi_buf_free(buf); 8626 return QDF_STATUS_E_FAILURE; 8627 } 8628 8629 return QDF_STATUS_SUCCESS; 8630 } 8631 8632 #ifdef OBSS_PD 8633 /** 8634 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 8635 * def thresh to fw 8636 * @wmi_handle: wmi handle 8637 * @thresh: pointer to obss_spatial_reuse_def_thresh 8638 * 8639 * Return: QDF_STATUS_SUCCESS for success or error code 8640 */ 8641 static 8642 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 8643 wmi_unified_t wmi_handle, 8644 struct wmi_host_obss_spatial_reuse_set_def_thresh 8645 *thresh) 8646 { 8647 wmi_buf_t buf; 8648 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 8649 QDF_STATUS ret; 8650 uint32_t cmd_len; 8651 uint32_t tlv_len; 8652 8653 cmd_len = sizeof(*cmd); 8654 8655 buf = wmi_buf_alloc(wmi_handle, cmd_len); 8656 if (!buf) 8657 return QDF_STATUS_E_NOMEM; 8658 8659 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 8660 wmi_buf_data(buf); 8661 8662 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 8663 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 8664 8665 WMITLV_SET_HDR(&cmd->tlv_header, 8666 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 8667 tlv_len); 8668 8669 cmd->obss_min = thresh->obss_min; 8670 cmd->obss_max = thresh->obss_max; 8671 cmd->vdev_type = thresh->vdev_type; 8672 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 8673 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 8674 if (QDF_IS_STATUS_ERROR(ret)) 8675 wmi_buf_free(buf); 8676 8677 return ret; 8678 } 8679 8680 /** 8681 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 8682 * @wmi_handle: wmi handle 8683 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 8684 * 8685 * Return: QDF_STATUS_SUCCESS for success or error code 8686 */ 8687 static 8688 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 8689 struct wmi_host_obss_spatial_reuse_set_param 8690 *obss_spatial_reuse_param) 8691 { 8692 wmi_buf_t buf; 8693 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 8694 QDF_STATUS ret; 8695 uint32_t len; 8696 8697 len = sizeof(*cmd); 8698 8699 buf = wmi_buf_alloc(wmi_handle, len); 8700 if (!buf) 8701 return QDF_STATUS_E_FAILURE; 8702 8703 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 8704 WMITLV_SET_HDR(&cmd->tlv_header, 8705 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 8706 WMITLV_GET_STRUCT_TLVLEN 8707 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 8708 8709 cmd->enable = obss_spatial_reuse_param->enable; 8710 cmd->obss_min = obss_spatial_reuse_param->obss_min; 8711 cmd->obss_max = obss_spatial_reuse_param->obss_max; 8712 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 8713 8714 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8715 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 8716 8717 if (QDF_IS_STATUS_ERROR(ret)) { 8718 WMI_LOGE( 8719 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 8720 ret); 8721 wmi_buf_free(buf); 8722 } 8723 8724 return ret; 8725 } 8726 8727 /** 8728 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 8729 * to be used by SRG based Spatial Reuse feature to the FW 8730 * @wmi_handle: wmi handle 8731 * @bitmap_0: lower 32 bits in BSS color bitmap 8732 * @bitmap_1: upper 32 bits in BSS color bitmap 8733 * @pdev_id: pdev ID 8734 * 8735 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8736 */ 8737 static QDF_STATUS 8738 send_self_srg_bss_color_bitmap_set_cmd_tlv( 8739 wmi_unified_t wmi_handle, uint32_t bitmap_0, 8740 uint32_t bitmap_1, uint8_t pdev_id) 8741 { 8742 wmi_buf_t buf; 8743 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 8744 QDF_STATUS ret; 8745 uint32_t len; 8746 8747 len = sizeof(*cmd); 8748 8749 buf = wmi_buf_alloc(wmi_handle, len); 8750 if (!buf) 8751 return QDF_STATUS_E_FAILURE; 8752 8753 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 8754 wmi_buf_data(buf); 8755 8756 WMITLV_SET_HDR( 8757 &cmd->tlv_header, 8758 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 8759 WMITLV_GET_STRUCT_TLVLEN 8760 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 8761 8762 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8763 wmi_handle, pdev_id); 8764 cmd->srg_bss_color_bitmap[0] = bitmap_0; 8765 cmd->srg_bss_color_bitmap[1] = bitmap_1; 8766 8767 ret = wmi_unified_cmd_send( 8768 wmi_handle, buf, len, 8769 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 8770 8771 if (QDF_IS_STATUS_ERROR(ret)) { 8772 WMI_LOGE( 8773 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 8774 ret); 8775 wmi_buf_free(buf); 8776 } 8777 8778 return ret; 8779 } 8780 8781 /** 8782 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 8783 * bitmap to be used by SRG based Spatial Reuse feature to the FW 8784 * @wmi_handle: wmi handle 8785 * @bitmap_0: lower 32 bits in partial BSSID bitmap 8786 * @bitmap_1: upper 32 bits in partial BSSID bitmap 8787 * @pdev_id: pdev ID 8788 * 8789 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8790 */ 8791 static QDF_STATUS 8792 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 8793 wmi_unified_t wmi_handle, uint32_t bitmap_0, 8794 uint32_t bitmap_1, uint8_t pdev_id) 8795 { 8796 wmi_buf_t buf; 8797 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 8798 QDF_STATUS ret; 8799 uint32_t len; 8800 8801 len = sizeof(*cmd); 8802 8803 buf = wmi_buf_alloc(wmi_handle, len); 8804 if (!buf) 8805 return QDF_STATUS_E_FAILURE; 8806 8807 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 8808 wmi_buf_data(buf); 8809 8810 WMITLV_SET_HDR( 8811 &cmd->tlv_header, 8812 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 8813 WMITLV_GET_STRUCT_TLVLEN 8814 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 8815 8816 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8817 wmi_handle, pdev_id); 8818 8819 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 8820 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 8821 8822 ret = wmi_unified_cmd_send( 8823 wmi_handle, buf, len, 8824 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 8825 8826 if (QDF_IS_STATUS_ERROR(ret)) { 8827 WMI_LOGE( 8828 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 8829 ret); 8830 wmi_buf_free(buf); 8831 } 8832 8833 return ret; 8834 } 8835 8836 /** 8837 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 8838 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 8839 * @wmi_handle: wmi handle 8840 * @bitmap_0: lower 32 bits in BSS color enable bitmap 8841 * @bitmap_1: upper 32 bits in BSS color enable bitmap 8842 * @pdev_id: pdev ID 8843 * 8844 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8845 */ 8846 static QDF_STATUS 8847 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 8848 wmi_unified_t wmi_handle, uint32_t bitmap_0, 8849 uint32_t bitmap_1, uint8_t pdev_id) 8850 { 8851 wmi_buf_t buf; 8852 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 8853 QDF_STATUS ret; 8854 uint32_t len; 8855 8856 len = sizeof(*cmd); 8857 8858 buf = wmi_buf_alloc(wmi_handle, len); 8859 if (!buf) 8860 return QDF_STATUS_E_FAILURE; 8861 8862 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 8863 wmi_buf_data(buf); 8864 8865 WMITLV_SET_HDR( 8866 &cmd->tlv_header, 8867 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 8868 WMITLV_GET_STRUCT_TLVLEN 8869 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 8870 8871 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8872 wmi_handle, pdev_id); 8873 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 8874 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 8875 8876 ret = wmi_unified_cmd_send( 8877 wmi_handle, buf, len, 8878 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 8879 8880 if (QDF_IS_STATUS_ERROR(ret)) { 8881 WMI_LOGE( 8882 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 8883 ret); 8884 wmi_buf_free(buf); 8885 } 8886 8887 return ret; 8888 } 8889 8890 /** 8891 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 8892 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 8893 * @wmi_handle: wmi handle 8894 * @bitmap_0: lower 32 bits in BSSID enable bitmap 8895 * @bitmap_1: upper 32 bits in BSSID enable bitmap 8896 * @pdev_id: pdev ID 8897 * 8898 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8899 */ 8900 static QDF_STATUS 8901 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 8902 wmi_unified_t wmi_handle, uint32_t bitmap_0, 8903 uint32_t bitmap_1, uint8_t pdev_id) 8904 { 8905 wmi_buf_t buf; 8906 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 8907 QDF_STATUS ret; 8908 uint32_t len; 8909 8910 len = sizeof(*cmd); 8911 8912 buf = wmi_buf_alloc(wmi_handle, len); 8913 if (!buf) 8914 return QDF_STATUS_E_FAILURE; 8915 8916 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 8917 wmi_buf_data(buf); 8918 8919 WMITLV_SET_HDR( 8920 &cmd->tlv_header, 8921 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 8922 WMITLV_GET_STRUCT_TLVLEN 8923 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 8924 8925 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8926 wmi_handle, pdev_id); 8927 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 8928 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 8929 8930 ret = wmi_unified_cmd_send( 8931 wmi_handle, buf, len, 8932 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 8933 8934 if (QDF_IS_STATUS_ERROR(ret)) { 8935 WMI_LOGE( 8936 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 8937 ret); 8938 wmi_buf_free(buf); 8939 } 8940 8941 return ret; 8942 } 8943 8944 /** 8945 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 8946 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 8947 * @wmi_handle: wmi handle 8948 * @bitmap_0: lower 32 bits in BSS color enable bitmap 8949 * @bitmap_1: upper 32 bits in BSS color enable bitmap 8950 * @pdev_id: pdev ID 8951 * 8952 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 8953 */ 8954 static QDF_STATUS 8955 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 8956 wmi_unified_t wmi_handle, uint32_t bitmap_0, 8957 uint32_t bitmap_1, uint8_t pdev_id) 8958 { 8959 wmi_buf_t buf; 8960 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 8961 QDF_STATUS ret; 8962 uint32_t len; 8963 8964 len = sizeof(*cmd); 8965 8966 buf = wmi_buf_alloc(wmi_handle, len); 8967 if (!buf) 8968 return QDF_STATUS_E_FAILURE; 8969 8970 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 8971 wmi_buf_data(buf); 8972 8973 WMITLV_SET_HDR( 8974 &cmd->tlv_header, 8975 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 8976 WMITLV_GET_STRUCT_TLVLEN 8977 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 8978 8979 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8980 wmi_handle, pdev_id); 8981 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 8982 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 8983 8984 ret = wmi_unified_cmd_send( 8985 wmi_handle, buf, len, 8986 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 8987 8988 if (QDF_IS_STATUS_ERROR(ret)) { 8989 WMI_LOGE( 8990 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 8991 ret); 8992 wmi_buf_free(buf); 8993 } 8994 8995 return ret; 8996 } 8997 8998 /** 8999 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 9000 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 9001 * @wmi_handle: wmi handle 9002 * @bitmap_0: lower 32 bits in BSSID enable bitmap 9003 * @bitmap_1: upper 32 bits in BSSID enable bitmap 9004 * @pdev_id: pdev ID 9005 * 9006 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 9007 */ 9008 static QDF_STATUS 9009 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 9010 wmi_unified_t wmi_handle, uint32_t bitmap_0, 9011 uint32_t bitmap_1, uint8_t pdev_id) 9012 { 9013 wmi_buf_t buf; 9014 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 9015 QDF_STATUS ret; 9016 uint32_t len; 9017 9018 len = sizeof(*cmd); 9019 9020 buf = wmi_buf_alloc(wmi_handle, len); 9021 if (!buf) 9022 return QDF_STATUS_E_FAILURE; 9023 9024 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 9025 wmi_buf_data(buf); 9026 9027 WMITLV_SET_HDR( 9028 &cmd->tlv_header, 9029 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 9030 WMITLV_GET_STRUCT_TLVLEN 9031 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 9032 9033 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9034 wmi_handle, pdev_id); 9035 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 9036 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 9037 9038 ret = wmi_unified_cmd_send( 9039 wmi_handle, buf, len, 9040 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 9041 9042 if (QDF_IS_STATUS_ERROR(ret)) { 9043 WMI_LOGE( 9044 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 9045 ret); 9046 wmi_buf_free(buf); 9047 } 9048 9049 return ret; 9050 } 9051 #endif 9052 9053 static 9054 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 9055 struct wmi_host_injector_frame_params *inject_config_params) 9056 { 9057 wmi_buf_t buf; 9058 wmi_frame_inject_cmd_fixed_param *cmd; 9059 QDF_STATUS ret; 9060 uint32_t len; 9061 9062 len = sizeof(*cmd); 9063 9064 buf = wmi_buf_alloc(wmi_handle, len); 9065 if (!buf) 9066 return QDF_STATUS_E_NOMEM; 9067 9068 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 9069 WMITLV_SET_HDR(&cmd->tlv_header, 9070 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 9071 WMITLV_GET_STRUCT_TLVLEN 9072 (wmi_frame_inject_cmd_fixed_param)); 9073 9074 cmd->vdev_id = inject_config_params->vdev_id; 9075 cmd->enable = inject_config_params->enable; 9076 cmd->frame_type = inject_config_params->frame_type; 9077 cmd->frame_inject_period = inject_config_params->frame_inject_period; 9078 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 9079 &cmd->frame_addr1); 9080 9081 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9082 WMI_PDEV_FRAME_INJECT_CMDID); 9083 9084 if (QDF_IS_STATUS_ERROR(ret)) { 9085 WMI_LOGE( 9086 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 9087 ret); 9088 wmi_buf_free(buf); 9089 } 9090 9091 return ret; 9092 } 9093 #ifdef QCA_SUPPORT_CP_STATS 9094 /** 9095 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 9096 * @wmi_handle: wma handle 9097 * @evt_buf: event buffer 9098 * @out_buff: buffer to populated after stats extraction 9099 * 9100 * Return: status of operation 9101 */ 9102 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 9103 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 9104 { 9105 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 9106 wmi_congestion_stats *congestion_stats; 9107 9108 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 9109 congestion_stats = param_buf->congestion_stats; 9110 if (!congestion_stats) 9111 return QDF_STATUS_E_INVAL; 9112 9113 out_buff->vdev_id = congestion_stats->vdev_id; 9114 out_buff->congestion = congestion_stats->congestion; 9115 9116 WMI_LOGD("%s: cca stats event processed", __func__); 9117 return QDF_STATUS_SUCCESS; 9118 } 9119 #endif /* QCA_SUPPORT_CP_STATS */ 9120 9121 /** 9122 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 9123 * event 9124 * @wmi_handle: wmi handle 9125 * @param evt_buf: pointer to event buffer 9126 * @param param: Pointer to hold peer ctl data 9127 * 9128 * Return: QDF_STATUS_SUCCESS for success or error code 9129 */ 9130 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 9131 wmi_unified_t wmi_handle, 9132 void *evt_buf, 9133 struct wmi_host_pdev_ctl_failsafe_event *param) 9134 { 9135 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 9136 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 9137 9138 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 9139 if (!param_buf) { 9140 WMI_LOGE("Invalid ctl_failsafe event buffer"); 9141 return QDF_STATUS_E_INVAL; 9142 } 9143 9144 fix_param = param_buf->fixed_param; 9145 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 9146 9147 return QDF_STATUS_SUCCESS; 9148 } 9149 9150 /** 9151 * save_service_bitmap_tlv() - save service bitmap 9152 * @wmi_handle: wmi handle 9153 * @param evt_buf: pointer to event buffer 9154 * @param bitmap_buf: bitmap buffer, for converged legacy support 9155 * 9156 * Return: QDF_STATUS 9157 */ 9158 static 9159 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9160 void *bitmap_buf) 9161 { 9162 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9163 struct wmi_soc *soc = wmi_handle->soc; 9164 9165 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9166 9167 /* If it is already allocated, use that buffer. This can happen 9168 * during target stop/start scenarios where host allocation is skipped. 9169 */ 9170 if (!soc->wmi_service_bitmap) { 9171 soc->wmi_service_bitmap = 9172 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 9173 if (!soc->wmi_service_bitmap) 9174 return QDF_STATUS_E_NOMEM; 9175 } 9176 9177 qdf_mem_copy(soc->wmi_service_bitmap, 9178 param_buf->wmi_service_bitmap, 9179 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 9180 9181 if (bitmap_buf) 9182 qdf_mem_copy(bitmap_buf, 9183 param_buf->wmi_service_bitmap, 9184 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 9185 9186 return QDF_STATUS_SUCCESS; 9187 } 9188 9189 /** 9190 * save_ext_service_bitmap_tlv() - save extendend service bitmap 9191 * @wmi_handle: wmi handle 9192 * @param evt_buf: pointer to event buffer 9193 * @param bitmap_buf: bitmap buffer, for converged legacy support 9194 * 9195 * Return: QDF_STATUS 9196 */ 9197 static 9198 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9199 void *bitmap_buf) 9200 { 9201 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 9202 wmi_service_available_event_fixed_param *ev; 9203 struct wmi_soc *soc = wmi_handle->soc; 9204 9205 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 9206 9207 ev = param_buf->fixed_param; 9208 9209 /* If it is already allocated, use that buffer. This can happen 9210 * during target stop/start scenarios where host allocation is skipped. 9211 */ 9212 if (!soc->wmi_ext_service_bitmap) { 9213 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 9214 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 9215 if (!soc->wmi_ext_service_bitmap) 9216 return QDF_STATUS_E_NOMEM; 9217 } 9218 9219 qdf_mem_copy(soc->wmi_ext_service_bitmap, 9220 ev->wmi_service_segment_bitmap, 9221 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 9222 9223 WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 9224 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 9225 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 9226 9227 if (bitmap_buf) 9228 qdf_mem_copy(bitmap_buf, 9229 soc->wmi_ext_service_bitmap, 9230 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 9231 9232 return QDF_STATUS_SUCCESS; 9233 } 9234 9235 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 9236 struct wlan_psoc_target_capability_info *cap) 9237 { 9238 /* except LDPC all flags are common betwen legacy and here 9239 * also IBFEER is not defined for TLV 9240 */ 9241 cap->ht_cap_info |= ev_target_cap & ( 9242 WMI_HT_CAP_ENABLED 9243 | WMI_HT_CAP_HT20_SGI 9244 | WMI_HT_CAP_DYNAMIC_SMPS 9245 | WMI_HT_CAP_TX_STBC 9246 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 9247 | WMI_HT_CAP_RX_STBC 9248 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 9249 | WMI_HT_CAP_LDPC 9250 | WMI_HT_CAP_L_SIG_TXOP_PROT 9251 | WMI_HT_CAP_MPDU_DENSITY 9252 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 9253 | WMI_HT_CAP_HT40_SGI); 9254 if (ev_target_cap & WMI_HT_CAP_LDPC) 9255 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 9256 WMI_HOST_HT_CAP_TX_LDPC; 9257 } 9258 /** 9259 * extract_service_ready_tlv() - extract service ready event 9260 * @wmi_handle: wmi handle 9261 * @param evt_buf: pointer to received event buffer 9262 * @param cap: pointer to hold target capability information extracted from even 9263 * 9264 * Return: QDF_STATUS_SUCCESS for success or error code 9265 */ 9266 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 9267 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 9268 { 9269 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9270 wmi_service_ready_event_fixed_param *ev; 9271 9272 9273 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9274 9275 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9276 if (!ev) { 9277 qdf_print("%s: wmi_buf_alloc failed", __func__); 9278 return QDF_STATUS_E_FAILURE; 9279 } 9280 9281 cap->phy_capability = ev->phy_capability; 9282 cap->max_frag_entry = ev->max_frag_entry; 9283 cap->num_rf_chains = ev->num_rf_chains; 9284 copy_ht_cap_info(ev->ht_cap_info, cap); 9285 cap->vht_cap_info = ev->vht_cap_info; 9286 cap->vht_supp_mcs = ev->vht_supp_mcs; 9287 cap->hw_min_tx_power = ev->hw_min_tx_power; 9288 cap->hw_max_tx_power = ev->hw_max_tx_power; 9289 cap->sys_cap_info = ev->sys_cap_info; 9290 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 9291 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 9292 cap->max_num_scan_channels = ev->max_num_scan_channels; 9293 cap->max_supported_macs = ev->max_supported_macs; 9294 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 9295 cap->txrx_chainmask = ev->txrx_chainmask; 9296 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 9297 cap->num_msdu_desc = ev->num_msdu_desc; 9298 cap->fw_version = ev->fw_build_vers; 9299 /* fw_version_1 is not available in TLV. */ 9300 cap->fw_version_1 = 0; 9301 9302 return QDF_STATUS_SUCCESS; 9303 } 9304 9305 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 9306 * to host internal WMI_HOST_REGDMN_MODE values. 9307 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 9308 * host currently. Add this in the future if required. 9309 * 11AX (Phase II) : 11ax related values are not currently 9310 * advertised separately by FW. As part of phase II regulatory bring-up, 9311 * finalize the advertisement mechanism. 9312 * @target_wireless_mode: target wireless mode received in message 9313 * 9314 * Return: returns the host internal wireless mode. 9315 */ 9316 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 9317 { 9318 9319 uint32_t wireless_modes = 0; 9320 9321 WMI_LOGD("Target wireless mode: 0x%x", target_wireless_mode); 9322 9323 if (target_wireless_mode & REGDMN_MODE_11A) 9324 wireless_modes |= WMI_HOST_REGDMN_MODE_11A; 9325 9326 if (target_wireless_mode & REGDMN_MODE_TURBO) 9327 wireless_modes |= WMI_HOST_REGDMN_MODE_TURBO; 9328 9329 if (target_wireless_mode & REGDMN_MODE_11B) 9330 wireless_modes |= WMI_HOST_REGDMN_MODE_11B; 9331 9332 if (target_wireless_mode & REGDMN_MODE_PUREG) 9333 wireless_modes |= WMI_HOST_REGDMN_MODE_PUREG; 9334 9335 if (target_wireless_mode & REGDMN_MODE_11G) 9336 wireless_modes |= WMI_HOST_REGDMN_MODE_11G; 9337 9338 if (target_wireless_mode & REGDMN_MODE_108G) 9339 wireless_modes |= WMI_HOST_REGDMN_MODE_108G; 9340 9341 if (target_wireless_mode & REGDMN_MODE_108A) 9342 wireless_modes |= WMI_HOST_REGDMN_MODE_108A; 9343 9344 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 9345 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20_2G; 9346 9347 if (target_wireless_mode & REGDMN_MODE_XR) 9348 wireless_modes |= WMI_HOST_REGDMN_MODE_XR; 9349 9350 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 9351 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_HALF_RATE; 9352 9353 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 9354 wireless_modes |= WMI_HOST_REGDMN_MODE_11A_QUARTER_RATE; 9355 9356 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 9357 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT20; 9358 9359 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 9360 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT20; 9361 9362 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 9363 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40PLUS; 9364 9365 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 9366 wireless_modes |= WMI_HOST_REGDMN_MODE_11NG_HT40MINUS; 9367 9368 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 9369 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40PLUS; 9370 9371 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 9372 wireless_modes |= WMI_HOST_REGDMN_MODE_11NA_HT40MINUS; 9373 9374 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 9375 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT20; 9376 9377 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 9378 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40PLUS; 9379 9380 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 9381 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT40MINUS; 9382 9383 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 9384 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80; 9385 9386 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 9387 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT160; 9388 9389 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 9390 wireless_modes |= WMI_HOST_REGDMN_MODE_11AC_VHT80_80; 9391 9392 return wireless_modes; 9393 } 9394 9395 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 9396 * target to host internal REGULATORY_PHYMODE values. 9397 * 9398 * @target_target_phybitmap: target phybitmap received in the message. 9399 * 9400 * Return: returns the host internal REGULATORY_PHYMODE. 9401 */ 9402 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 9403 { 9404 uint32_t phybitmap = 0; 9405 9406 WMI_LOGD("Target phybitmap: 0x%x", target_phybitmap); 9407 9408 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 9409 phybitmap |= REGULATORY_PHYMODE_NO11A; 9410 9411 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 9412 phybitmap |= REGULATORY_PHYMODE_NO11B; 9413 9414 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 9415 phybitmap |= REGULATORY_PHYMODE_NO11G; 9416 9417 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 9418 phybitmap |= REGULATORY_CHAN_NO11N; 9419 9420 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 9421 phybitmap |= REGULATORY_PHYMODE_NO11AC; 9422 9423 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 9424 phybitmap |= REGULATORY_PHYMODE_NO11AX; 9425 9426 return phybitmap; 9427 } 9428 9429 static inline uint32_t convert_wireless_modes_ext_tlv( 9430 uint32_t target_wireless_modes_ext) 9431 { 9432 uint32_t wireless_modes_ext = 0; 9433 9434 WMI_LOGD("Target wireless mode: 0x%x", target_wireless_modes_ext); 9435 9436 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 9437 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE20; 9438 9439 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 9440 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40PLUS; 9441 9442 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 9443 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXG_HE40MINUS; 9444 9445 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 9446 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE20; 9447 9448 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 9449 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40PLUS; 9450 9451 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 9452 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE40MINUS; 9453 9454 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 9455 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80; 9456 9457 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 9458 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE160; 9459 9460 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 9461 wireless_modes_ext |= WMI_HOST_REGDMN_MODE_11AXA_HE80_80; 9462 9463 return wireless_modes_ext; 9464 } 9465 9466 /** 9467 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 9468 * @wmi_handle: wmi handle 9469 * @param evt_buf: Pointer to event buffer 9470 * @param cap: pointer to hold HAL reg capabilities 9471 * 9472 * Return: QDF_STATUS_SUCCESS for success or error code 9473 */ 9474 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 9475 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 9476 { 9477 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9478 9479 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9480 if (!param_buf || !param_buf->hal_reg_capabilities) { 9481 WMI_LOGE("%s: Invalid arguments", __func__); 9482 return QDF_STATUS_E_FAILURE; 9483 } 9484 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 9485 sizeof(uint32_t)), 9486 sizeof(struct wlan_psoc_hal_reg_capability)); 9487 9488 cap->wireless_modes = convert_wireless_modes_tlv( 9489 param_buf->hal_reg_capabilities->wireless_modes); 9490 9491 return QDF_STATUS_SUCCESS; 9492 } 9493 9494 /** 9495 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 9496 * @wmi_handle: wmi handle 9497 * @param evt_buf: Pointer to event buffer 9498 * @param cap: pointer to hold HAL reg capabilities 9499 * 9500 * Return: QDF_STATUS_SUCCESS for success or error code 9501 */ 9502 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 9503 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 9504 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 9505 { 9506 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 9507 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 9508 9509 if (!evt_buf) { 9510 WMI_LOGE("null evt_buf"); 9511 return QDF_STATUS_E_INVAL; 9512 } 9513 9514 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 9515 9516 if (!param_buf->num_hal_reg_caps) 9517 return QDF_STATUS_SUCCESS; 9518 9519 if (phy_idx >= param_buf->num_hal_reg_caps) 9520 return QDF_STATUS_E_INVAL; 9521 9522 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 9523 9524 param->phy_id = reg_caps->phy_id; 9525 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 9526 reg_caps->wireless_modes_ext); 9527 9528 return QDF_STATUS_SUCCESS; 9529 } 9530 9531 /** 9532 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 9533 * @wmi_handle: wmi handle 9534 * @evt_buf: pointer to event buffer 9535 * 9536 * Return: Number of entries requested 9537 */ 9538 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 9539 void *evt_buf) 9540 { 9541 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9542 wmi_service_ready_event_fixed_param *ev; 9543 9544 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9545 9546 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9547 if (!ev) { 9548 qdf_print("%s: wmi_buf_alloc failed", __func__); 9549 return 0; 9550 } 9551 9552 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 9553 WMI_LOGE("Invalid num_mem_reqs %d:%d", 9554 ev->num_mem_reqs, param_buf->num_mem_reqs); 9555 return 0; 9556 } 9557 9558 return ev->num_mem_reqs; 9559 } 9560 9561 /** 9562 * extract_host_mem_req_tlv() - Extract host memory required from 9563 * service ready event 9564 * @wmi_handle: wmi handle 9565 * @evt_buf: pointer to event buffer 9566 * @mem_reqs: pointer to host memory request structure 9567 * @num_active_peers: number of active peers for peer cache 9568 * @num_peers: number of peers 9569 * @fw_prio: FW priority 9570 * @idx: index for memory request 9571 * 9572 * Return: Host memory request parameters requested by target 9573 */ 9574 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 9575 void *evt_buf, 9576 host_mem_req *mem_reqs, 9577 uint32_t num_active_peers, 9578 uint32_t num_peers, 9579 enum wmi_fw_mem_prio fw_prio, 9580 uint16_t idx) 9581 { 9582 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9583 9584 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 9585 9586 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 9587 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 9588 mem_reqs->num_unit_info = 9589 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 9590 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 9591 mem_reqs->tgt_num_units = 0; 9592 9593 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 9594 (mem_reqs->num_unit_info & 9595 REQ_TO_HOST_FOR_CONT_MEMORY)) || 9596 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 9597 (!(mem_reqs->num_unit_info & 9598 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 9599 /* First allocate the memory that requires contiguous memory */ 9600 mem_reqs->tgt_num_units = mem_reqs->num_units; 9601 if (mem_reqs->num_unit_info) { 9602 if (mem_reqs->num_unit_info & 9603 NUM_UNITS_IS_NUM_PEERS) { 9604 /* 9605 * number of units allocated is equal to number 9606 * of peers, 1 extra for self peer on target. 9607 * this needs to be fixed, host and target can 9608 * get out of sync 9609 */ 9610 mem_reqs->tgt_num_units = num_peers + 1; 9611 } 9612 if (mem_reqs->num_unit_info & 9613 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 9614 /* 9615 * Requesting allocation of memory using 9616 * num_active_peers in qcache. if qcache is 9617 * disabled in host, then it should allocate 9618 * memory for num_peers instead of 9619 * num_active_peers. 9620 */ 9621 if (num_active_peers) 9622 mem_reqs->tgt_num_units = 9623 num_active_peers + 1; 9624 else 9625 mem_reqs->tgt_num_units = 9626 num_peers + 1; 9627 } 9628 } 9629 9630 WMI_LOGI("idx %d req %d num_units %d num_unit_info %d" 9631 "unit size %d actual units %d", 9632 idx, mem_reqs->req_id, 9633 mem_reqs->num_units, 9634 mem_reqs->num_unit_info, 9635 mem_reqs->unit_size, 9636 mem_reqs->tgt_num_units); 9637 } 9638 9639 return QDF_STATUS_SUCCESS; 9640 } 9641 9642 /** 9643 * save_fw_version_in_service_ready_tlv() - Save fw version in service 9644 * ready function 9645 * @wmi_handle: wmi handle 9646 * @param evt_buf: pointer to event buffer 9647 * 9648 * Return: QDF_STATUS_SUCCESS for success or error code 9649 */ 9650 static QDF_STATUS 9651 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 9652 { 9653 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 9654 wmi_service_ready_event_fixed_param *ev; 9655 9656 9657 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 9658 9659 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 9660 if (!ev) { 9661 qdf_print("%s: wmi_buf_alloc failed", __func__); 9662 return QDF_STATUS_E_FAILURE; 9663 } 9664 9665 /*Save fw version from service ready message */ 9666 /*This will be used while sending INIT message */ 9667 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 9668 sizeof(wmi_handle->fw_abi_version)); 9669 9670 return QDF_STATUS_SUCCESS; 9671 } 9672 9673 /** 9674 * ready_extract_init_status_tlv() - Extract init status from ready event 9675 * @wmi_handle: wmi handle 9676 * @param evt_buf: Pointer to event buffer 9677 * 9678 * Return: ready status 9679 */ 9680 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 9681 void *evt_buf) 9682 { 9683 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9684 wmi_ready_event_fixed_param *ev = NULL; 9685 9686 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9687 ev = param_buf->fixed_param; 9688 9689 qdf_print("%s:%d", __func__, ev->status); 9690 9691 return ev->status; 9692 } 9693 9694 /** 9695 * ready_extract_mac_addr_tlv() - extract mac address from ready event 9696 * @wmi_handle: wmi handle 9697 * @param evt_buf: pointer to event buffer 9698 * @param macaddr: Pointer to hold MAC address 9699 * 9700 * Return: QDF_STATUS_SUCCESS for success or error code 9701 */ 9702 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_hamdle, 9703 void *evt_buf, uint8_t *macaddr) 9704 { 9705 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9706 wmi_ready_event_fixed_param *ev = NULL; 9707 9708 9709 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9710 ev = param_buf->fixed_param; 9711 9712 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 9713 9714 return QDF_STATUS_SUCCESS; 9715 } 9716 9717 /** 9718 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 9719 * @wmi_handle: wmi handle 9720 * @param evt_buf: pointer to event buffer 9721 * @param macaddr: Pointer to hold number of MAC addresses 9722 * 9723 * Return: Pointer to addr list 9724 */ 9725 static wmi_host_mac_addr *ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_hamdle, 9726 void *evt_buf, uint8_t *num_mac) 9727 { 9728 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9729 wmi_ready_event_fixed_param *ev = NULL; 9730 9731 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9732 ev = param_buf->fixed_param; 9733 9734 *num_mac = ev->num_extra_mac_addr; 9735 9736 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 9737 } 9738 9739 /** 9740 * extract_ready_params_tlv() - Extract data from ready event apart from 9741 * status, macaddr and version. 9742 * @wmi_handle: Pointer to WMI handle. 9743 * @evt_buf: Pointer to Ready event buffer. 9744 * @ev_param: Pointer to host defined struct to copy the data from event. 9745 * 9746 * Return: QDF_STATUS_SUCCESS on success. 9747 */ 9748 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 9749 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 9750 { 9751 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 9752 wmi_ready_event_fixed_param *ev = NULL; 9753 9754 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 9755 ev = param_buf->fixed_param; 9756 9757 ev_param->status = ev->status; 9758 ev_param->num_dscp_table = ev->num_dscp_table; 9759 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 9760 ev_param->num_total_peer = ev->num_total_peers; 9761 ev_param->num_extra_peer = ev->num_extra_peers; 9762 /* Agile_capability in ready event is supported in TLV target, 9763 * as per aDFS FR 9764 */ 9765 ev_param->max_ast_index = ev->max_ast_index; 9766 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 9767 ev_param->agile_capability = 1; 9768 9769 return QDF_STATUS_SUCCESS; 9770 } 9771 9772 /** 9773 * extract_dbglog_data_len_tlv() - extract debuglog data length 9774 * @wmi_handle: wmi handle 9775 * @param evt_buf: pointer to event buffer 9776 * 9777 * Return: length 9778 */ 9779 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 9780 void *evt_buf, uint32_t *len) 9781 { 9782 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 9783 9784 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 9785 9786 *len = param_buf->num_bufp; 9787 9788 return param_buf->bufp; 9789 } 9790 9791 9792 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 9793 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 9794 #else 9795 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 9796 ((_status) & WMI_RXERR_DECRYPT) 9797 #endif 9798 9799 /** 9800 * extract_mgmt_rx_params_tlv() - extract management rx params from event 9801 * @wmi_handle: wmi handle 9802 * @param evt_buf: pointer to event buffer 9803 * @param hdr: Pointer to hold header 9804 * @param bufp: Pointer to hold pointer to rx param buffer 9805 * 9806 * Return: QDF_STATUS_SUCCESS for success or error code 9807 */ 9808 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 9809 void *evt_buf, struct mgmt_rx_event_params *hdr, 9810 uint8_t **bufp) 9811 { 9812 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 9813 wmi_mgmt_rx_hdr *ev_hdr = NULL; 9814 int i; 9815 9816 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 9817 if (!param_tlvs) { 9818 WMI_LOGE("Get NULL point message from FW"); 9819 return QDF_STATUS_E_INVAL; 9820 } 9821 9822 ev_hdr = param_tlvs->hdr; 9823 if (!hdr) { 9824 WMI_LOGE("Rx event is NULL"); 9825 return QDF_STATUS_E_INVAL; 9826 } 9827 9828 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 9829 WMI_LOGE("%s: RX mgmt frame decrypt error, discard it", 9830 __func__); 9831 return QDF_STATUS_E_INVAL; 9832 } 9833 9834 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 9835 wmi_handle, 9836 ev_hdr->pdev_id); 9837 hdr->chan_freq = ev_hdr->chan_freq; 9838 hdr->channel = ev_hdr->channel; 9839 hdr->snr = ev_hdr->snr; 9840 hdr->rate = ev_hdr->rate; 9841 hdr->phy_mode = ev_hdr->phy_mode; 9842 hdr->buf_len = ev_hdr->buf_len; 9843 hdr->status = ev_hdr->status; 9844 hdr->flags = ev_hdr->flags; 9845 hdr->rssi = ev_hdr->rssi; 9846 hdr->tsf_delta = ev_hdr->tsf_delta; 9847 for (i = 0; i < ATH_MAX_ANTENNA; i++) 9848 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 9849 9850 *bufp = param_tlvs->bufp; 9851 9852 return QDF_STATUS_SUCCESS; 9853 } 9854 9855 /** 9856 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 9857 * @wmi_handle: wmi handle 9858 * @param evt_buf: pointer to event buffer 9859 * @param param: Pointer to hold roam param 9860 * 9861 * Return: QDF_STATUS_SUCCESS for success or error code 9862 */ 9863 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 9864 void *evt_buf, wmi_host_roam_event *param) 9865 { 9866 WMI_ROAM_EVENTID_param_tlvs *param_buf; 9867 wmi_roam_event_fixed_param *evt; 9868 9869 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 9870 if (!param_buf) { 9871 WMI_LOGE("Invalid roam event buffer"); 9872 return QDF_STATUS_E_INVAL; 9873 } 9874 9875 evt = param_buf->fixed_param; 9876 qdf_mem_zero(param, sizeof(*param)); 9877 9878 param->vdev_id = evt->vdev_id; 9879 param->reason = evt->reason; 9880 param->rssi = evt->rssi; 9881 9882 return QDF_STATUS_SUCCESS; 9883 } 9884 9885 /** 9886 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 9887 * @wmi_handle: wmi handle 9888 * @param evt_buf: pointer to event buffer 9889 * @param param: Pointer to hold vdev scan param 9890 * 9891 * Return: QDF_STATUS_SUCCESS for success or error code 9892 */ 9893 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 9894 void *evt_buf, struct scan_event *param) 9895 { 9896 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 9897 wmi_scan_event_fixed_param *evt = NULL; 9898 9899 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 9900 evt = param_buf->fixed_param; 9901 9902 qdf_mem_zero(param, sizeof(*param)); 9903 9904 switch (evt->event) { 9905 case WMI_SCAN_EVENT_STARTED: 9906 param->type = SCAN_EVENT_TYPE_STARTED; 9907 break; 9908 case WMI_SCAN_EVENT_COMPLETED: 9909 param->type = SCAN_EVENT_TYPE_COMPLETED; 9910 break; 9911 case WMI_SCAN_EVENT_BSS_CHANNEL: 9912 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 9913 break; 9914 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 9915 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 9916 break; 9917 case WMI_SCAN_EVENT_DEQUEUED: 9918 param->type = SCAN_EVENT_TYPE_DEQUEUED; 9919 break; 9920 case WMI_SCAN_EVENT_PREEMPTED: 9921 param->type = SCAN_EVENT_TYPE_PREEMPTED; 9922 break; 9923 case WMI_SCAN_EVENT_START_FAILED: 9924 param->type = SCAN_EVENT_TYPE_START_FAILED; 9925 break; 9926 case WMI_SCAN_EVENT_RESTARTED: 9927 param->type = SCAN_EVENT_TYPE_RESTARTED; 9928 break; 9929 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 9930 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 9931 break; 9932 case WMI_SCAN_EVENT_MAX: 9933 default: 9934 param->type = SCAN_EVENT_TYPE_MAX; 9935 break; 9936 }; 9937 9938 switch (evt->reason) { 9939 case WMI_SCAN_REASON_NONE: 9940 param->reason = SCAN_REASON_NONE; 9941 break; 9942 case WMI_SCAN_REASON_COMPLETED: 9943 param->reason = SCAN_REASON_COMPLETED; 9944 break; 9945 case WMI_SCAN_REASON_CANCELLED: 9946 param->reason = SCAN_REASON_CANCELLED; 9947 break; 9948 case WMI_SCAN_REASON_PREEMPTED: 9949 param->reason = SCAN_REASON_PREEMPTED; 9950 break; 9951 case WMI_SCAN_REASON_TIMEDOUT: 9952 param->reason = SCAN_REASON_TIMEDOUT; 9953 break; 9954 case WMI_SCAN_REASON_INTERNAL_FAILURE: 9955 param->reason = SCAN_REASON_INTERNAL_FAILURE; 9956 break; 9957 case WMI_SCAN_REASON_SUSPENDED: 9958 param->reason = SCAN_REASON_SUSPENDED; 9959 break; 9960 case WMI_SCAN_REASON_DFS_VIOLATION: 9961 param->reason = SCAN_REASON_DFS_VIOLATION; 9962 break; 9963 case WMI_SCAN_REASON_MAX: 9964 param->reason = SCAN_REASON_MAX; 9965 break; 9966 default: 9967 param->reason = SCAN_REASON_MAX; 9968 break; 9969 }; 9970 9971 param->chan_freq = evt->channel_freq; 9972 param->requester = evt->requestor; 9973 param->scan_id = evt->scan_id; 9974 param->vdev_id = evt->vdev_id; 9975 param->timestamp = evt->tsf_timestamp; 9976 9977 return QDF_STATUS_SUCCESS; 9978 } 9979 9980 #ifdef FEATURE_WLAN_SCAN_PNO 9981 /** 9982 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 9983 * @wmi_handle: pointer to WMI handle 9984 * @evt_buf: pointer to WMI event buffer 9985 * @param: pointer to scan event param for NLO match 9986 * 9987 * Return: QDF_STATUS_SUCCESS for success or error code 9988 */ 9989 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 9990 void *evt_buf, 9991 struct scan_event *param) 9992 { 9993 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 9994 wmi_nlo_event *evt = param_buf->fixed_param; 9995 9996 qdf_mem_zero(param, sizeof(*param)); 9997 9998 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 9999 param->vdev_id = evt->vdev_id; 10000 10001 return QDF_STATUS_SUCCESS; 10002 } 10003 10004 /** 10005 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 10006 * @wmi_handle: pointer to WMI handle 10007 * @evt_buf: pointer to WMI event buffer 10008 * @param: pointer to scan event param for NLO complete 10009 * 10010 * Return: QDF_STATUS_SUCCESS for success or error code 10011 */ 10012 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 10013 void *evt_buf, 10014 struct scan_event *param) 10015 { 10016 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 10017 wmi_nlo_event *evt = param_buf->fixed_param; 10018 10019 qdf_mem_zero(param, sizeof(*param)); 10020 10021 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 10022 param->vdev_id = evt->vdev_id; 10023 10024 return QDF_STATUS_SUCCESS; 10025 } 10026 #endif 10027 10028 /** 10029 * extract_all_stats_counts_tlv() - extract all stats count from event 10030 * @wmi_handle: wmi handle 10031 * @param evt_buf: pointer to event buffer 10032 * @param stats_param: Pointer to hold stats count 10033 * 10034 * Return: QDF_STATUS_SUCCESS for success or error code 10035 */ 10036 static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, 10037 void *evt_buf, wmi_host_stats_event *stats_param) 10038 { 10039 wmi_stats_event_fixed_param *ev; 10040 wmi_per_chain_rssi_stats *rssi_event; 10041 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10042 uint64_t min_data_len; 10043 10044 qdf_mem_zero(stats_param, sizeof(*stats_param)); 10045 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10046 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10047 rssi_event = param_buf->chain_stats; 10048 if (!ev) { 10049 WMI_LOGE("%s: event fixed param NULL", __func__); 10050 return QDF_STATUS_E_FAILURE; 10051 } 10052 10053 if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) { 10054 WMI_LOGE("num_data : %u is invalid", param_buf->num_data); 10055 return QDF_STATUS_E_FAULT; 10056 } 10057 10058 switch (ev->stats_id) { 10059 case WMI_REQUEST_PEER_STAT: 10060 stats_param->stats_id |= WMI_HOST_REQUEST_PEER_STAT; 10061 break; 10062 10063 case WMI_REQUEST_AP_STAT: 10064 stats_param->stats_id |= WMI_HOST_REQUEST_AP_STAT; 10065 break; 10066 10067 case WMI_REQUEST_PDEV_STAT: 10068 stats_param->stats_id |= WMI_HOST_REQUEST_PDEV_STAT; 10069 break; 10070 10071 case WMI_REQUEST_VDEV_STAT: 10072 stats_param->stats_id |= WMI_HOST_REQUEST_VDEV_STAT; 10073 break; 10074 10075 case WMI_REQUEST_BCNFLT_STAT: 10076 stats_param->stats_id |= WMI_HOST_REQUEST_BCNFLT_STAT; 10077 break; 10078 10079 case WMI_REQUEST_VDEV_RATE_STAT: 10080 stats_param->stats_id |= WMI_HOST_REQUEST_VDEV_RATE_STAT; 10081 break; 10082 10083 case WMI_REQUEST_BCN_STAT: 10084 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 10085 break; 10086 case WMI_REQUEST_PEER_EXTD_STAT: 10087 stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT; 10088 break; 10089 10090 case WMI_REQUEST_PEER_EXTD2_STAT: 10091 stats_param->stats_id |= WMI_HOST_REQUEST_PEER_ADV_STATS; 10092 break; 10093 10094 default: 10095 stats_param->stats_id = 0; 10096 break; 10097 10098 } 10099 10100 /* ev->num_*_stats may cause uint32_t overflow, so use uint64_t 10101 * to save total length calculated 10102 */ 10103 min_data_len = 10104 (((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 10105 (((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 10106 (((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) + 10107 (((uint64_t)ev->num_bcnflt_stats) * 10108 sizeof(wmi_bcnfilter_stats_t)) + 10109 (((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) + 10110 (((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) + 10111 (((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) + 10112 (((uint64_t)ev->num_peer_extd_stats) * 10113 sizeof(wmi_peer_extd_stats)) + 10114 (((uint64_t)ev->num_mib_extd_stats) * 10115 sizeof(wmi_mib_extd_stats)); 10116 if (param_buf->num_data != min_data_len) { 10117 WMI_LOGE("data len: %u isn't same as calculated: %llu", 10118 param_buf->num_data, min_data_len); 10119 return QDF_STATUS_E_FAULT; 10120 } 10121 10122 stats_param->last_event = ev->last_event; 10123 stats_param->num_pdev_stats = ev->num_pdev_stats; 10124 stats_param->num_pdev_ext_stats = 0; 10125 stats_param->num_vdev_stats = ev->num_vdev_stats; 10126 stats_param->num_peer_stats = ev->num_peer_stats; 10127 stats_param->num_peer_extd_stats = ev->num_peer_extd_stats; 10128 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 10129 stats_param->num_chan_stats = ev->num_chan_stats; 10130 stats_param->num_mib_stats = ev->num_mib_stats; 10131 stats_param->num_mib_extd_stats = ev->num_mib_extd_stats; 10132 stats_param->num_bcn_stats = ev->num_bcn_stats; 10133 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10134 wmi_handle, 10135 ev->pdev_id); 10136 10137 /* if chain_stats is not populated */ 10138 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 10139 return QDF_STATUS_SUCCESS; 10140 10141 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 10142 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 10143 return QDF_STATUS_SUCCESS; 10144 10145 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 10146 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 10147 return QDF_STATUS_SUCCESS; 10148 10149 if (rssi_event->num_per_chain_rssi_stats >= 10150 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) { 10151 WMI_LOGE("num_per_chain_rssi_stats:%u is out of bounds", 10152 rssi_event->num_per_chain_rssi_stats); 10153 return QDF_STATUS_E_INVAL; 10154 } 10155 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 10156 10157 /* if peer_adv_stats is not populated */ 10158 if (!param_buf->num_peer_extd2_stats) 10159 return QDF_STATUS_SUCCESS; 10160 10161 stats_param->num_peer_adv_stats = param_buf->num_peer_extd2_stats; 10162 10163 return QDF_STATUS_SUCCESS; 10164 } 10165 10166 /** 10167 * extract_pdev_tx_stats() - extract pdev tx stats from event 10168 */ 10169 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, 10170 struct wlan_dbg_tx_stats *tx_stats) 10171 { 10172 /* Tx Stats */ 10173 tx->comp_queued = tx_stats->comp_queued; 10174 tx->comp_delivered = tx_stats->comp_delivered; 10175 tx->msdu_enqued = tx_stats->msdu_enqued; 10176 tx->mpdu_enqued = tx_stats->mpdu_enqued; 10177 tx->wmm_drop = tx_stats->wmm_drop; 10178 tx->local_enqued = tx_stats->local_enqued; 10179 tx->local_freed = tx_stats->local_freed; 10180 tx->hw_queued = tx_stats->hw_queued; 10181 tx->hw_reaped = tx_stats->hw_reaped; 10182 tx->underrun = tx_stats->underrun; 10183 tx->tx_abort = tx_stats->tx_abort; 10184 tx->mpdus_requed = tx_stats->mpdus_requed; 10185 tx->data_rc = tx_stats->data_rc; 10186 tx->self_triggers = tx_stats->self_triggers; 10187 tx->sw_retry_failure = tx_stats->sw_retry_failure; 10188 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 10189 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 10190 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 10191 tx->pdev_resets = tx_stats->pdev_resets; 10192 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 10193 tx->phy_underrun = tx_stats->phy_underrun; 10194 tx->txop_ovf = tx_stats->txop_ovf; 10195 10196 return; 10197 } 10198 10199 10200 /** 10201 * extract_pdev_rx_stats() - extract pdev rx stats from event 10202 */ 10203 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, 10204 struct wlan_dbg_rx_stats *rx_stats) 10205 { 10206 /* Rx Stats */ 10207 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 10208 rx->status_rcvd = rx_stats->status_rcvd; 10209 rx->r0_frags = rx_stats->r0_frags; 10210 rx->r1_frags = rx_stats->r1_frags; 10211 rx->r2_frags = rx_stats->r2_frags; 10212 /* Only TLV */ 10213 rx->r3_frags = 0; 10214 rx->htt_msdus = rx_stats->htt_msdus; 10215 rx->htt_mpdus = rx_stats->htt_mpdus; 10216 rx->loc_msdus = rx_stats->loc_msdus; 10217 rx->loc_mpdus = rx_stats->loc_mpdus; 10218 rx->oversize_amsdu = rx_stats->oversize_amsdu; 10219 rx->phy_errs = rx_stats->phy_errs; 10220 rx->phy_err_drop = rx_stats->phy_err_drop; 10221 rx->mpdu_errs = rx_stats->mpdu_errs; 10222 10223 return; 10224 } 10225 10226 /** 10227 * extract_pdev_stats_tlv() - extract pdev stats from event 10228 * @wmi_handle: wmi handle 10229 * @param evt_buf: pointer to event buffer 10230 * @param index: Index into pdev stats 10231 * @param pdev_stats: Pointer to hold pdev stats 10232 * 10233 * Return: QDF_STATUS_SUCCESS for success or error code 10234 */ 10235 static QDF_STATUS extract_pdev_stats_tlv(wmi_unified_t wmi_handle, 10236 void *evt_buf, uint32_t index, wmi_host_pdev_stats *pdev_stats) 10237 { 10238 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10239 wmi_stats_event_fixed_param *ev_param; 10240 uint8_t *data; 10241 10242 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10243 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10244 10245 data = param_buf->data; 10246 10247 if (index < ev_param->num_pdev_stats) { 10248 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 10249 (index * sizeof(wmi_pdev_stats))); 10250 10251 pdev_stats->chan_nf = ev->chan_nf; 10252 pdev_stats->tx_frame_count = ev->tx_frame_count; 10253 pdev_stats->rx_frame_count = ev->rx_frame_count; 10254 pdev_stats->rx_clear_count = ev->rx_clear_count; 10255 pdev_stats->cycle_count = ev->cycle_count; 10256 pdev_stats->phy_err_count = ev->phy_err_count; 10257 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 10258 10259 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 10260 &(ev->pdev_stats.tx)); 10261 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 10262 &(ev->pdev_stats.rx)); 10263 } 10264 10265 return QDF_STATUS_SUCCESS; 10266 } 10267 10268 /** 10269 * extract_unit_test_tlv() - extract unit test data 10270 * @wmi_handle: wmi handle 10271 * @param evt_buf: pointer to event buffer 10272 * @param unit_test: pointer to hold unit test data 10273 * @param maxspace: Amount of space in evt_buf 10274 * 10275 * Return: QDF_STATUS_SUCCESS for success or error code 10276 */ 10277 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 10278 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 10279 { 10280 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 10281 wmi_unit_test_event_fixed_param *ev_param; 10282 uint32_t num_bufp; 10283 uint32_t copy_size; 10284 uint8_t *bufp; 10285 10286 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 10287 ev_param = param_buf->fixed_param; 10288 bufp = param_buf->bufp; 10289 num_bufp = param_buf->num_bufp; 10290 unit_test->vdev_id = ev_param->vdev_id; 10291 unit_test->module_id = ev_param->module_id; 10292 unit_test->diag_token = ev_param->diag_token; 10293 unit_test->flag = ev_param->flag; 10294 unit_test->payload_len = ev_param->payload_len; 10295 WMI_LOGI("%s:vdev_id:%d mod_id:%d diag_token:%d flag:%d", __func__, 10296 ev_param->vdev_id, 10297 ev_param->module_id, 10298 ev_param->diag_token, 10299 ev_param->flag); 10300 WMI_LOGD("%s: Unit-test data given below %d", __func__, num_bufp); 10301 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10302 bufp, num_bufp); 10303 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 10304 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 10305 unit_test->buffer_len = copy_size; 10306 10307 return QDF_STATUS_SUCCESS; 10308 } 10309 10310 /** 10311 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 10312 * @wmi_handle: wmi handle 10313 * @param evt_buf: pointer to event buffer 10314 * @param index: Index into extended pdev stats 10315 * @param pdev_ext_stats: Pointer to hold extended pdev stats 10316 * 10317 * Return: QDF_STATUS_SUCCESS for success or error code 10318 */ 10319 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 10320 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 10321 { 10322 return QDF_STATUS_SUCCESS; 10323 } 10324 10325 /** 10326 * extract_vdev_stats_tlv() - extract vdev stats from event 10327 * @wmi_handle: wmi handle 10328 * @param evt_buf: pointer to event buffer 10329 * @param index: Index into vdev stats 10330 * @param vdev_stats: Pointer to hold vdev stats 10331 * 10332 * Return: QDF_STATUS_SUCCESS for success or error code 10333 */ 10334 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 10335 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 10336 { 10337 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10338 wmi_stats_event_fixed_param *ev_param; 10339 uint8_t *data; 10340 10341 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10342 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10343 data = (uint8_t *) param_buf->data; 10344 10345 if (index < ev_param->num_vdev_stats) { 10346 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 10347 ((ev_param->num_pdev_stats) * 10348 sizeof(wmi_pdev_stats)) + 10349 (index * sizeof(wmi_vdev_stats))); 10350 10351 vdev_stats->vdev_id = ev->vdev_id; 10352 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 10353 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 10354 10355 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 10356 sizeof(ev->tx_frm_cnt)); 10357 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 10358 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 10359 ev->multiple_retry_cnt, 10360 sizeof(ev->multiple_retry_cnt)); 10361 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 10362 sizeof(ev->fail_cnt)); 10363 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 10364 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 10365 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 10366 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 10367 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 10368 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 10369 sizeof(ev->tx_rate_history)); 10370 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 10371 sizeof(ev->bcn_rssi_history)); 10372 10373 } 10374 10375 return QDF_STATUS_SUCCESS; 10376 } 10377 10378 /** 10379 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 10380 * buffer 10381 * @wmi_handle: wmi handle 10382 * @evt_buf: pointer to event buffer 10383 * @index: Index into vdev stats 10384 * @rssi_stats: Pointer to hold rssi stats 10385 * 10386 * Return: QDF_STATUS_SUCCESS for success or error code 10387 */ 10388 static QDF_STATUS extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, 10389 void *evt_buf, uint32_t index, 10390 struct wmi_host_per_chain_rssi_stats *rssi_stats) 10391 { 10392 uint8_t *data; 10393 wmi_rssi_stats *fw_rssi_stats; 10394 wmi_per_chain_rssi_stats *rssi_event; 10395 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10396 10397 if (!evt_buf) { 10398 WMI_LOGE("evt_buf is null"); 10399 return QDF_STATUS_E_NULL_VALUE; 10400 } 10401 10402 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10403 rssi_event = param_buf->chain_stats; 10404 10405 if (index >= rssi_event->num_per_chain_rssi_stats) { 10406 WMI_LOGE("invalid index"); 10407 return QDF_STATUS_E_INVAL; 10408 } 10409 10410 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 10411 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 10412 if (fw_rssi_stats->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 10413 return QDF_STATUS_E_INVAL; 10414 10415 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 10416 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 10417 fw_rssi_stats->rssi_avg_beacon, 10418 sizeof(fw_rssi_stats->rssi_avg_beacon)); 10419 qdf_mem_copy(rssi_stats->rssi_avg_data, 10420 fw_rssi_stats->rssi_avg_data, 10421 sizeof(fw_rssi_stats->rssi_avg_data)); 10422 qdf_mem_copy(&rssi_stats->peer_macaddr, 10423 &fw_rssi_stats->peer_macaddr, 10424 sizeof(fw_rssi_stats->peer_macaddr)); 10425 10426 return QDF_STATUS_SUCCESS; 10427 } 10428 10429 10430 10431 /** 10432 * extract_bcn_stats_tlv() - extract bcn stats from event 10433 * @wmi_handle: wmi handle 10434 * @param evt_buf: pointer to event buffer 10435 * @param index: Index into vdev stats 10436 * @param bcn_stats: Pointer to hold bcn stats 10437 * 10438 * Return: QDF_STATUS_SUCCESS for success or error code 10439 */ 10440 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 10441 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 10442 { 10443 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10444 wmi_stats_event_fixed_param *ev_param; 10445 uint8_t *data; 10446 10447 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10448 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10449 data = (uint8_t *) param_buf->data; 10450 10451 if (index < ev_param->num_bcn_stats) { 10452 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 10453 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 10454 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 10455 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 10456 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 10457 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 10458 (index * sizeof(wmi_bcn_stats))); 10459 10460 bcn_stats->vdev_id = ev->vdev_id; 10461 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 10462 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 10463 } 10464 10465 return QDF_STATUS_SUCCESS; 10466 } 10467 10468 /** 10469 * extract_peer_stats_tlv() - extract peer stats from event 10470 * @wmi_handle: wmi handle 10471 * @param evt_buf: pointer to event buffer 10472 * @param index: Index into peer stats 10473 * @param peer_stats: Pointer to hold peer stats 10474 * 10475 * Return: QDF_STATUS_SUCCESS for success or error code 10476 */ 10477 static QDF_STATUS extract_peer_stats_tlv(wmi_unified_t wmi_handle, 10478 void *evt_buf, uint32_t index, wmi_host_peer_stats *peer_stats) 10479 { 10480 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10481 wmi_stats_event_fixed_param *ev_param; 10482 uint8_t *data; 10483 10484 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10485 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10486 data = (uint8_t *) param_buf->data; 10487 10488 if (index < ev_param->num_peer_stats) { 10489 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 10490 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 10491 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 10492 (index * sizeof(wmi_peer_stats))); 10493 10494 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 10495 10496 OS_MEMCPY(&(peer_stats->peer_macaddr), 10497 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 10498 10499 peer_stats->peer_rssi = ev->peer_rssi; 10500 peer_stats->peer_tx_rate = ev->peer_tx_rate; 10501 peer_stats->peer_rx_rate = ev->peer_rx_rate; 10502 } 10503 10504 return QDF_STATUS_SUCCESS; 10505 } 10506 10507 /** 10508 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 10509 * @wmi_handle: wmi handle 10510 * @param evt_buf: pointer to event buffer 10511 * @param index: Index into bcn fault stats 10512 * @param bcnflt_stats: Pointer to hold bcn fault stats 10513 * 10514 * Return: QDF_STATUS_SUCCESS for success or error code 10515 */ 10516 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 10517 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *peer_stats) 10518 { 10519 return QDF_STATUS_SUCCESS; 10520 } 10521 10522 /** 10523 * extract_peer_adv_stats_tlv() - extract adv peer stats from event 10524 * @wmi_handle: wmi handle 10525 * @param evt_buf: pointer to event buffer 10526 * @param index: Index into extended peer stats 10527 * @param peer_adv_stats: Pointer to hold adv peer stats 10528 * 10529 * Return: QDF_STATUS_SUCCESS for success or error code 10530 */ 10531 static QDF_STATUS extract_peer_adv_stats_tlv(wmi_unified_t wmi_handle, 10532 void *evt_buf, 10533 struct wmi_host_peer_adv_stats 10534 *peer_adv_stats) 10535 { 10536 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10537 wmi_peer_extd2_stats *adv_stats; 10538 int i; 10539 10540 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 10541 10542 adv_stats = param_buf->peer_extd2_stats; 10543 if (!adv_stats) { 10544 WMI_LOGD("%s: no peer_adv stats in event buffer", __func__); 10545 return QDF_STATUS_E_INVAL; 10546 } 10547 10548 for (i = 0; i < param_buf->num_peer_extd2_stats; i++) { 10549 WMI_MAC_ADDR_TO_CHAR_ARRAY(&adv_stats[i].peer_macaddr, 10550 peer_adv_stats[i].peer_macaddr); 10551 peer_adv_stats[i].fcs_count = adv_stats[i].rx_fcs_err; 10552 peer_adv_stats[i].rx_bytes = 10553 (uint64_t)adv_stats[i].rx_bytes_u32 << 10554 WMI_LOWER_BITS_SHIFT_32 | 10555 adv_stats[i].rx_bytes_l32; 10556 peer_adv_stats[i].rx_count = adv_stats[i].rx_mpdus; 10557 } 10558 10559 return QDF_STATUS_SUCCESS; 10560 } 10561 10562 /** 10563 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 10564 * @wmi_handle: wmi handle 10565 * @param evt_buf: pointer to event buffer 10566 * @param index: Index into extended peer stats 10567 * @param peer_extd_stats: Pointer to hold extended peer stats 10568 * 10569 * Return: QDF_STATUS_SUCCESS for success or error code 10570 */ 10571 static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 10572 void *evt_buf, uint32_t index, 10573 wmi_host_peer_extd_stats *peer_extd_stats) 10574 { 10575 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10576 wmi_stats_event_fixed_param *ev_param; 10577 uint8_t *data; 10578 10579 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 10580 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 10581 data = (uint8_t *)param_buf->data; 10582 if (!data) 10583 return QDF_STATUS_E_FAILURE; 10584 10585 if (index < ev_param->num_peer_extd_stats) { 10586 wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data + 10587 (ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) + 10588 (ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) + 10589 (ev_param->num_peer_stats * sizeof(wmi_peer_stats)) + 10590 (ev_param->num_bcnflt_stats * 10591 sizeof(wmi_bcnfilter_stats_t)) + 10592 (ev_param->num_chan_stats * sizeof(wmi_chan_stats)) + 10593 (ev_param->num_mib_stats * sizeof(wmi_mib_stats)) + 10594 (ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) + 10595 (index * sizeof(wmi_peer_extd_stats))); 10596 10597 qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats)); 10598 qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr, 10599 sizeof(wmi_mac_addr)); 10600 10601 peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt; 10602 } 10603 10604 return QDF_STATUS_SUCCESS; 10605 10606 } 10607 10608 /** 10609 * extract_chan_stats_tlv() - extract chan stats from event 10610 * @wmi_handle: wmi handle 10611 * @param evt_buf: pointer to event buffer 10612 * @param index: Index into chan stats 10613 * @param vdev_extd_stats: Pointer to hold chan stats 10614 * 10615 * Return: QDF_STATUS_SUCCESS for success or error code 10616 */ 10617 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 10618 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 10619 { 10620 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10621 wmi_stats_event_fixed_param *ev_param; 10622 uint8_t *data; 10623 10624 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 10625 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 10626 data = (uint8_t *) param_buf->data; 10627 10628 if (index < ev_param->num_chan_stats) { 10629 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 10630 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 10631 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 10632 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 10633 (index * sizeof(wmi_chan_stats))); 10634 10635 10636 /* Non-TLV doesn't have num_chan_stats */ 10637 chan_stats->chan_mhz = ev->chan_mhz; 10638 chan_stats->sampling_period_us = ev->sampling_period_us; 10639 chan_stats->rx_clear_count = ev->rx_clear_count; 10640 chan_stats->tx_duration_us = ev->tx_duration_us; 10641 chan_stats->rx_duration_us = ev->rx_duration_us; 10642 } 10643 10644 return QDF_STATUS_SUCCESS; 10645 } 10646 10647 #ifdef WLAN_FEATURE_MIB_STATS 10648 /** 10649 * extract_mib_stats_tlv() - extract mib stats from event 10650 * @wmi_handle: wmi handle 10651 * @param evt_buf: pointer to event buffer 10652 * @param mib_stats: pointer to hold mib stats 10653 * 10654 * Return: QDF_STATUS_SUCCESS for success or error code 10655 */ 10656 static QDF_STATUS extract_mib_stats_tlv(wmi_unified_t wmi_handle, 10657 void *evt_buf, 10658 struct mib_stats_metrics 10659 *mib_stats) 10660 { 10661 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 10662 wmi_stats_event_fixed_param *ev_param; 10663 uint8_t *data; 10664 wmi_mib_stats *ev; 10665 wmi_mib_extd_stats *ev_extd; 10666 10667 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 10668 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 10669 data = (uint8_t *)param_buf->data; 10670 10671 ev = (wmi_mib_stats *)(data + 10672 ev_param->num_pdev_stats * sizeof(wmi_pdev_stats) + 10673 ev_param->num_vdev_stats * sizeof(wmi_vdev_stats) + 10674 ev_param->num_peer_stats * sizeof(wmi_peer_stats) + 10675 ev_param->num_bcnflt_stats * 10676 sizeof(wmi_bcnfilter_stats_t) + 10677 ev_param->num_chan_stats * sizeof(wmi_chan_stats)); 10678 10679 qdf_mem_zero(mib_stats, sizeof(*mib_stats)); 10680 10681 mib_stats->mib_counters.tx_frags = 10682 ev->tx_mpdu_grp_frag_cnt; 10683 mib_stats->mib_counters.group_tx_frames = 10684 ev->tx_msdu_grp_frm_cnt; 10685 mib_stats->mib_counters.failed_cnt = ev->tx_msdu_fail_cnt; 10686 mib_stats->mib_counters.rx_frags = ev->rx_mpdu_frag_cnt; 10687 mib_stats->mib_counters.group_rx_frames = 10688 ev->rx_msdu_grp_frm_cnt; 10689 mib_stats->mib_counters.fcs_error_cnt = 10690 ev->rx_mpdu_fcs_err; 10691 mib_stats->mib_counters.tx_frames = 10692 ev->tx_msdu_frm_cnt; 10693 mib_stats->mib_mac_statistics.retry_cnt = 10694 ev->tx_msdu_retry_cnt; 10695 mib_stats->mib_mac_statistics.frame_dup_cnt = 10696 ev->rx_frm_dup_cnt; 10697 mib_stats->mib_mac_statistics.rts_success_cnt = 10698 ev->tx_rts_success_cnt; 10699 mib_stats->mib_mac_statistics.rts_fail_cnt = 10700 ev->tx_rts_fail_cnt; 10701 10702 mib_stats->mib_qos_counters.qos_tx_frag_cnt = 10703 ev->tx_Qos_mpdu_grp_frag_cnt; 10704 mib_stats->mib_qos_counters.qos_retry_cnt = 10705 ev->tx_Qos_msdu_retry_UP; 10706 mib_stats->mib_qos_counters.qos_failed_cnt = 10707 ev->tx_Qos_msdu_fail_UP; 10708 mib_stats->mib_qos_counters.qos_frame_dup_cnt = 10709 ev->rx_Qos_frm_dup_cnt_UP; 10710 mib_stats->mib_qos_counters.qos_rts_success_cnt = 10711 ev->tx_Qos_rts_success_cnt_UP; 10712 mib_stats->mib_qos_counters.qos_rts_fail_cnt = 10713 ev->tx_Qos_rts_fail_cnt_UP; 10714 mib_stats->mib_qos_counters.qos_rx_frag_cnt = 10715 ev->rx_Qos_mpdu_frag_cnt_UP; 10716 mib_stats->mib_qos_counters.qos_tx_frame_cnt = 10717 ev->tx_Qos_msdu_frm_cnt_UP; 10718 mib_stats->mib_qos_counters.qos_discarded_frame_cnt = 10719 ev->rx_Qos_msdu_discard_cnt_UP; 10720 mib_stats->mib_qos_counters.qos_mpdu_rx_cnt = 10721 ev->rx_Qos_mpdu_cnt; 10722 mib_stats->mib_qos_counters.qos_retries_rx_cnt = 10723 ev->rx_Qos_mpdu_retryBit_cnt; 10724 10725 mib_stats->mib_rsna_stats.tkip_icv_err = 10726 ev->rsna_TKIP_icv_err_cnt; 10727 mib_stats->mib_rsna_stats.tkip_replays = 10728 ev->rsna_TKIP_replay_err_cnt; 10729 mib_stats->mib_rsna_stats.ccmp_decrypt_err = 10730 ev->rsna_CCMP_decrypt_err_cnt; 10731 mib_stats->mib_rsna_stats.ccmp_replays = 10732 ev->rsna_CCMP_replay_err_cnt; 10733 10734 mib_stats->mib_counters_group3.tx_ampdu_cnt = 10735 ev->tx_ampdu_cnt; 10736 mib_stats->mib_counters_group3.tx_mpdus_in_ampdu_cnt = 10737 ev->tx_mpdu_cnt_in_ampdu; 10738 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt = 10739 ev->tx_octets_in_ampdu.upload.high; 10740 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt = 10741 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt << 32; 10742 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt += 10743 ev->tx_octets_in_ampdu.upload.low; 10744 10745 mib_stats->mib_counters_group3.ampdu_rx_cnt = 10746 ev->rx_ampdu_cnt; 10747 mib_stats->mib_counters_group3.mpdu_in_rx_ampdu_cnt = 10748 ev->rx_mpdu_cnt_in_ampdu; 10749 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt = 10750 ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_high; 10751 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt = 10752 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt << 32; 10753 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt += 10754 ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_low; 10755 10756 if (ev_param->num_mib_extd_stats) { 10757 ev_extd = (wmi_mib_extd_stats *)((uint8_t *)ev + 10758 ev_param->num_mib_stats * sizeof(wmi_mib_stats) + 10759 ev_param->num_bcn_stats * sizeof(wmi_bcn_stats) + 10760 ev_param->num_peer_extd_stats * 10761 sizeof(wmi_peer_extd_stats)); 10762 mib_stats->mib_mac_statistics.multi_retry_cnt = 10763 ev_extd->tx_msdu_multi_retry_cnt; 10764 mib_stats->mib_mac_statistics.tx_ack_fail_cnt = 10765 ev_extd->tx_ack_fail_cnt; 10766 10767 mib_stats->mib_qos_counters.qos_multi_retry_cnt = 10768 ev_extd->tx_qos_msdu_multi_retry_up; 10769 mib_stats->mib_qos_counters.tx_qos_ack_fail_cnt_up = 10770 ev_extd->tx_qos_ack_fail_cnt_up; 10771 10772 mib_stats->mib_rsna_stats.cmac_icv_err = 10773 ev_extd->rsna_cmac_icv_err_cnt; 10774 mib_stats->mib_rsna_stats.cmac_replays = 10775 ev_extd->rsna_cmac_replay_err_cnt; 10776 10777 mib_stats->mib_counters_group3.rx_ampdu_deli_crc_err_cnt = 10778 ev_extd->rx_ampdu_deli_crc_err_cnt; 10779 } 10780 10781 return QDF_STATUS_SUCCESS; 10782 } 10783 #endif 10784 10785 /** 10786 * extract_profile_ctx_tlv() - extract profile context from event 10787 * @wmi_handle: wmi handle 10788 * @param evt_buf: pointer to event buffer 10789 * @idx: profile stats index to extract 10790 * @param profile_ctx: Pointer to hold profile context 10791 * 10792 * Return: QDF_STATUS_SUCCESS for success or error code 10793 */ 10794 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 10795 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 10796 { 10797 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 10798 10799 wmi_wlan_profile_ctx_t *ev; 10800 10801 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 10802 if (!param_buf) { 10803 WMI_LOGE("%s: Invalid profile data event buf", __func__); 10804 return QDF_STATUS_E_INVAL; 10805 } 10806 10807 ev = param_buf->profile_ctx; 10808 10809 profile_ctx->tot = ev->tot; 10810 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 10811 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 10812 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 10813 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 10814 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 10815 profile_ctx->bin_count = ev->bin_count; 10816 10817 return QDF_STATUS_SUCCESS; 10818 } 10819 10820 /** 10821 * extract_profile_data_tlv() - extract profile data from event 10822 * @wmi_handle: wmi handle 10823 * @param evt_buf: pointer to event buffer 10824 * @param profile_data: Pointer to hold profile data 10825 * 10826 * Return: QDF_STATUS_SUCCESS for success or error code 10827 */ 10828 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 10829 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 10830 { 10831 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 10832 wmi_wlan_profile_t *ev; 10833 uint8_t *buf_ptr; 10834 10835 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 10836 if (!param_buf) { 10837 WMI_LOGE("%s: Invalid profile data event buf", __func__); 10838 return QDF_STATUS_E_INVAL; 10839 } 10840 10841 buf_ptr = (uint8_t *)param_buf->profile_ctx; 10842 buf_ptr = buf_ptr + sizeof(wmi_wlan_profile_ctx_t) + WMI_TLV_HDR_SIZE; 10843 10844 buf_ptr = buf_ptr + (sizeof(wmi_wlan_profile_t) * idx); 10845 ev = (wmi_wlan_profile_t *)buf_ptr; 10846 10847 profile_data->id = ev->id; 10848 profile_data->cnt = ev->cnt; 10849 profile_data->tot = ev->tot; 10850 profile_data->min = ev->min; 10851 profile_data->max = ev->max; 10852 profile_data->hist_intvl = ev->hist_intvl; 10853 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 10854 10855 return QDF_STATUS_SUCCESS; 10856 } 10857 10858 /** 10859 * extract_pdev_utf_event_tlv() - extract UTF data info from event 10860 * @wmi_handle: WMI handle 10861 * @param evt_buf: Pointer to event buffer 10862 * @param param: Pointer to hold data 10863 * 10864 * Return : QDF_STATUS_SUCCESS for success or error code 10865 */ 10866 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 10867 uint8_t *evt_buf, 10868 struct wmi_host_pdev_utf_event *event) 10869 { 10870 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 10871 struct wmi_host_utf_seg_header_info *seg_hdr; 10872 10873 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 10874 event->data = param_buf->data; 10875 event->datalen = param_buf->num_data; 10876 10877 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 10878 WMI_LOGE("%s: Invalid datalen: %d ", __func__, event->datalen); 10879 return QDF_STATUS_E_INVAL; 10880 } 10881 seg_hdr = (struct wmi_host_utf_seg_header_info *)param_buf->data; 10882 /* Set pdev_id=1 until FW adds support to include pdev_id */ 10883 event->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 10884 wmi_handle, 10885 seg_hdr->pdev_id); 10886 10887 return QDF_STATUS_SUCCESS; 10888 } 10889 10890 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 10891 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 10892 uint8_t *event, 10893 uint32_t *num_rf_characterization_entries) 10894 { 10895 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 10896 10897 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 10898 if (!param_buf) 10899 return QDF_STATUS_E_INVAL; 10900 10901 *num_rf_characterization_entries = 10902 param_buf->num_wmi_chan_rf_characterization_info; 10903 10904 return QDF_STATUS_SUCCESS; 10905 } 10906 10907 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 10908 uint8_t *event, 10909 uint32_t num_rf_characterization_entries, 10910 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 10911 { 10912 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 10913 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 10914 uint8_t ix; 10915 10916 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 10917 if (!param_buf) 10918 return QDF_STATUS_E_INVAL; 10919 10920 wmi_rf_characterization_entry = 10921 param_buf->wmi_chan_rf_characterization_info; 10922 if (!wmi_rf_characterization_entry) 10923 return QDF_STATUS_E_INVAL; 10924 10925 /* 10926 * Using num_wmi_chan_rf_characterization instead of param_buf value 10927 * since memory for rf_characterization_entries was allocated using 10928 * the former. 10929 */ 10930 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 10931 rf_characterization_entries[ix].freq = 10932 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 10933 &wmi_rf_characterization_entry[ix]); 10934 10935 rf_characterization_entries[ix].bw = 10936 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 10937 &wmi_rf_characterization_entry[ix]); 10938 10939 rf_characterization_entries[ix].chan_metric = 10940 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 10941 &wmi_rf_characterization_entry[ix]); 10942 10943 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 10944 "bw: %u, chan_metric: %u", 10945 ix, rf_characterization_entries[ix].freq, 10946 rf_characterization_entries[ix].bw, 10947 rf_characterization_entries[ix].chan_metric); 10948 } 10949 10950 return QDF_STATUS_SUCCESS; 10951 } 10952 #endif 10953 10954 /** 10955 * extract_chainmask_tables_tlv() - extract chain mask tables from event 10956 * @wmi_handle: wmi handle 10957 * @param evt_buf: pointer to event buffer 10958 * @param param: Pointer to hold evt buf 10959 * 10960 * Return: QDF_STATUS_SUCCESS for success or error code 10961 */ 10962 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 10963 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 10964 { 10965 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 10966 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 10967 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 10968 uint8_t i = 0, j = 0; 10969 uint32_t num_mac_phy_chainmask_caps = 0; 10970 10971 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 10972 if (!param_buf) 10973 return QDF_STATUS_E_INVAL; 10974 10975 hw_caps = param_buf->soc_hw_mode_caps; 10976 if (!hw_caps) 10977 return QDF_STATUS_E_INVAL; 10978 10979 if ((!hw_caps->num_chainmask_tables) || 10980 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 10981 (hw_caps->num_chainmask_tables > 10982 param_buf->num_mac_phy_chainmask_combo)) 10983 return QDF_STATUS_E_INVAL; 10984 10985 chainmask_caps = param_buf->mac_phy_chainmask_caps; 10986 10987 if (!chainmask_caps) 10988 return QDF_STATUS_E_INVAL; 10989 10990 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 10991 if (chainmask_table[i].num_valid_chainmasks > 10992 (UINT_MAX - num_mac_phy_chainmask_caps)) { 10993 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 10994 num_mac_phy_chainmask_caps, i, 10995 chainmask_table[i].num_valid_chainmasks); 10996 return QDF_STATUS_E_INVAL; 10997 } 10998 num_mac_phy_chainmask_caps += 10999 chainmask_table[i].num_valid_chainmasks; 11000 } 11001 11002 if (num_mac_phy_chainmask_caps > 11003 param_buf->num_mac_phy_chainmask_caps) { 11004 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 11005 num_mac_phy_chainmask_caps, 11006 param_buf->num_mac_phy_chainmask_caps); 11007 return QDF_STATUS_E_INVAL; 11008 } 11009 11010 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 11011 11012 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 11013 i); 11014 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 11015 11016 chainmask_table[i].cap_list[j].chainmask = 11017 chainmask_caps->chainmask; 11018 11019 chainmask_table[i].cap_list[j].supports_chan_width_20 = 11020 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 11021 11022 chainmask_table[i].cap_list[j].supports_chan_width_40 = 11023 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 11024 11025 chainmask_table[i].cap_list[j].supports_chan_width_80 = 11026 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 11027 11028 chainmask_table[i].cap_list[j].supports_chan_width_160 = 11029 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 11030 11031 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 11032 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 11033 11034 chainmask_table[i].cap_list[j].chain_mask_2G = 11035 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 11036 11037 chainmask_table[i].cap_list[j].chain_mask_5G = 11038 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 11039 11040 chainmask_table[i].cap_list[j].chain_mask_tx = 11041 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 11042 11043 chainmask_table[i].cap_list[j].chain_mask_rx = 11044 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 11045 11046 chainmask_table[i].cap_list[j].supports_aDFS = 11047 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 11048 11049 chainmask_table[i].cap_list[j].supports_aSpectral = 11050 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 11051 11052 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 11053 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 11054 11055 chainmask_table[i].cap_list[j].supports_aDFS_160 = 11056 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 11057 11058 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 11059 chainmask_caps->supported_flags, 11060 chainmask_caps->chainmask); 11061 chainmask_caps++; 11062 } 11063 } 11064 11065 return QDF_STATUS_SUCCESS; 11066 } 11067 11068 /** 11069 * extract_service_ready_ext_tlv() - extract basic extended service ready params 11070 * from event 11071 * @wmi_handle: wmi handle 11072 * @param evt_buf: pointer to event buffer 11073 * @param param: Pointer to hold evt buf 11074 * 11075 * Return: QDF_STATUS_SUCCESS for success or error code 11076 */ 11077 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 11078 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 11079 { 11080 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11081 wmi_service_ready_ext_event_fixed_param *ev; 11082 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11083 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 11084 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 11085 uint8_t i = 0; 11086 11087 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11088 if (!param_buf) 11089 return QDF_STATUS_E_INVAL; 11090 11091 ev = param_buf->fixed_param; 11092 if (!ev) 11093 return QDF_STATUS_E_INVAL; 11094 11095 /* Move this to host based bitmap */ 11096 param->default_conc_scan_config_bits = 11097 ev->default_conc_scan_config_bits; 11098 param->default_fw_config_bits = ev->default_fw_config_bits; 11099 param->he_cap_info = ev->he_cap_info; 11100 param->mpdu_density = ev->mpdu_density; 11101 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 11102 param->fw_build_vers_ext = ev->fw_build_vers_ext; 11103 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 11104 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 11105 param->max_bssid_indicator = ev->max_bssid_indicator; 11106 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 11107 11108 hw_caps = param_buf->soc_hw_mode_caps; 11109 if (hw_caps) 11110 param->num_hw_modes = hw_caps->num_hw_modes; 11111 else 11112 param->num_hw_modes = 0; 11113 11114 reg_caps = param_buf->soc_hal_reg_caps; 11115 if (reg_caps) 11116 param->num_phy = reg_caps->num_phy; 11117 else 11118 param->num_phy = 0; 11119 11120 if (hw_caps) { 11121 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 11122 wmi_nofl_debug("Num chain mask tables: %d", 11123 hw_caps->num_chainmask_tables); 11124 } else 11125 param->num_chainmask_tables = 0; 11126 11127 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 11128 param->num_chainmask_tables > 11129 param_buf->num_mac_phy_chainmask_combo) { 11130 wmi_err_rl("num_chainmask_tables is OOB: %u", 11131 param->num_chainmask_tables); 11132 return QDF_STATUS_E_INVAL; 11133 } 11134 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 11135 11136 if (!chain_mask_combo) 11137 return QDF_STATUS_SUCCESS; 11138 11139 wmi_nofl_debug("Dumping chain mask combo data"); 11140 11141 for (i = 0; i < param->num_chainmask_tables; i++) { 11142 11143 wmi_nofl_debug("table_id : %d Num valid chainmasks: %d", 11144 chain_mask_combo->chainmask_table_id, 11145 chain_mask_combo->num_valid_chainmask); 11146 11147 param->chainmask_table[i].table_id = 11148 chain_mask_combo->chainmask_table_id; 11149 param->chainmask_table[i].num_valid_chainmasks = 11150 chain_mask_combo->num_valid_chainmask; 11151 chain_mask_combo++; 11152 } 11153 wmi_nofl_debug("chain mask combo end"); 11154 11155 return QDF_STATUS_SUCCESS; 11156 } 11157 11158 /** 11159 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 11160 * event 11161 * @wmi_handle: wmi handle 11162 * @event: pointer to event buffer 11163 * @param: Pointer to hold the params 11164 * 11165 * Return: QDF_STATUS_SUCCESS for success or error code 11166 */ 11167 static QDF_STATUS 11168 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 11169 struct wlan_psoc_host_service_ext2_param *param) 11170 { 11171 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11172 wmi_service_ready_ext2_event_fixed_param *ev; 11173 11174 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11175 if (!param_buf) 11176 return QDF_STATUS_E_INVAL; 11177 11178 ev = param_buf->fixed_param; 11179 if (!ev) 11180 return QDF_STATUS_E_INVAL; 11181 11182 param->reg_db_version_major = 11183 WMI_REG_DB_VERSION_MAJOR_GET( 11184 ev->reg_db_version); 11185 param->reg_db_version_minor = 11186 WMI_REG_DB_VERSION_MINOR_GET( 11187 ev->reg_db_version); 11188 param->bdf_reg_db_version_major = 11189 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 11190 ev->reg_db_version); 11191 param->bdf_reg_db_version_minor = 11192 WMI_BDF_REG_DB_VERSION_MINOR_GET( 11193 ev->reg_db_version); 11194 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 11195 11196 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 11197 11198 if (param_buf->nan_cap) 11199 param->max_ndp_sessions = 11200 param_buf->nan_cap->max_ndp_sessions; 11201 else 11202 param->max_ndp_sessions = 0; 11203 11204 return QDF_STATUS_SUCCESS; 11205 } 11206 11207 /** 11208 * extract_sar_cap_service_ready_ext_tlv() - 11209 * extract SAR cap from service ready event 11210 * @wmi_handle: wmi handle 11211 * @event: pointer to event buffer 11212 * @ext_param: extended target info 11213 * 11214 * Return: QDF_STATUS_SUCCESS for success or error code 11215 */ 11216 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 11217 wmi_unified_t wmi_handle, 11218 uint8_t *event, 11219 struct wlan_psoc_host_service_ext_param *ext_param) 11220 { 11221 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11222 WMI_SAR_CAPABILITIES *sar_caps; 11223 11224 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 11225 11226 if (!param_buf) 11227 return QDF_STATUS_E_INVAL; 11228 11229 sar_caps = param_buf->sar_caps; 11230 if (sar_caps) 11231 ext_param->sar_version = sar_caps->active_version; 11232 else 11233 ext_param->sar_version = 0; 11234 11235 return QDF_STATUS_SUCCESS; 11236 } 11237 11238 /** 11239 * extract_hw_mode_cap_service_ready_ext_tlv() - 11240 * extract HW mode cap from service ready event 11241 * @wmi_handle: wmi handle 11242 * @param evt_buf: pointer to event buffer 11243 * @param param: Pointer to hold evt buf 11244 * @param hw_mode_idx: hw mode idx should be less than num_mode 11245 * 11246 * Return: QDF_STATUS_SUCCESS for success or error code 11247 */ 11248 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 11249 wmi_unified_t wmi_handle, 11250 uint8_t *event, uint8_t hw_mode_idx, 11251 struct wlan_psoc_host_hw_mode_caps *param) 11252 { 11253 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11254 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11255 11256 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11257 if (!param_buf) 11258 return QDF_STATUS_E_INVAL; 11259 11260 hw_caps = param_buf->soc_hw_mode_caps; 11261 if (!hw_caps) 11262 return QDF_STATUS_E_INVAL; 11263 11264 if (!hw_caps->num_hw_modes || 11265 !param_buf->hw_mode_caps || 11266 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 11267 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 11268 return QDF_STATUS_E_INVAL; 11269 11270 if (hw_mode_idx >= hw_caps->num_hw_modes) 11271 return QDF_STATUS_E_INVAL; 11272 11273 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 11274 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 11275 11276 param->hw_mode_config_type = 11277 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 11278 11279 return QDF_STATUS_SUCCESS; 11280 } 11281 11282 /** 11283 * extract_mac_phy_cap_service_ready_ext_tlv() - 11284 * extract MAC phy cap from service ready event 11285 * @wmi_handle: wmi handle 11286 * @param evt_buf: pointer to event buffer 11287 * @param param: Pointer to hold evt buf 11288 * @param hw_mode_idx: hw mode idx should be less than num_mode 11289 * @param phy_id: phy id within hw_mode 11290 * 11291 * Return: QDF_STATUS_SUCCESS for success or error code 11292 */ 11293 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 11294 wmi_unified_t wmi_handle, 11295 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 11296 struct wlan_psoc_host_mac_phy_caps *param) 11297 { 11298 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11299 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 11300 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 11301 uint32_t phy_map; 11302 uint8_t hw_idx, phy_idx = 0; 11303 11304 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11305 if (!param_buf) 11306 return QDF_STATUS_E_INVAL; 11307 11308 hw_caps = param_buf->soc_hw_mode_caps; 11309 if (!hw_caps) 11310 return QDF_STATUS_E_INVAL; 11311 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 11312 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 11313 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 11314 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 11315 return QDF_STATUS_E_INVAL; 11316 } 11317 11318 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 11319 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 11320 break; 11321 11322 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 11323 while (phy_map) { 11324 phy_map >>= 1; 11325 phy_idx++; 11326 } 11327 } 11328 11329 if (hw_idx == hw_caps->num_hw_modes) 11330 return QDF_STATUS_E_INVAL; 11331 11332 phy_idx += phy_id; 11333 if (phy_idx >= param_buf->num_mac_phy_caps) 11334 return QDF_STATUS_E_INVAL; 11335 11336 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 11337 11338 param->hw_mode_id = mac_phy_caps->hw_mode_id; 11339 param->phy_idx = phy_idx; 11340 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11341 wmi_handle, 11342 mac_phy_caps->pdev_id); 11343 param->tgt_pdev_id = mac_phy_caps->pdev_id; 11344 param->phy_id = mac_phy_caps->phy_id; 11345 param->supports_11b = 11346 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 11347 param->supports_11g = 11348 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 11349 param->supports_11a = 11350 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 11351 param->supports_11n = 11352 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 11353 param->supports_11ac = 11354 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 11355 param->supports_11ax = 11356 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 11357 11358 param->supported_bands = mac_phy_caps->supported_bands; 11359 param->ampdu_density = mac_phy_caps->ampdu_density; 11360 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 11361 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 11362 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 11363 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 11364 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 11365 mac_phy_caps->he_cap_info_2G; 11366 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 11367 mac_phy_caps->he_cap_info_2G_ext; 11368 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 11369 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 11370 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 11371 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 11372 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 11373 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 11374 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 11375 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 11376 mac_phy_caps->he_cap_info_5G; 11377 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 11378 mac_phy_caps->he_cap_info_5G_ext; 11379 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 11380 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 11381 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 11382 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 11383 qdf_mem_copy(¶m->he_cap_phy_info_2G, 11384 &mac_phy_caps->he_cap_phy_info_2G, 11385 sizeof(param->he_cap_phy_info_2G)); 11386 qdf_mem_copy(¶m->he_cap_phy_info_5G, 11387 &mac_phy_caps->he_cap_phy_info_5G, 11388 sizeof(param->he_cap_phy_info_5G)); 11389 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 11390 sizeof(param->he_ppet2G)); 11391 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 11392 sizeof(param->he_ppet5G)); 11393 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 11394 param->lmac_id = mac_phy_caps->lmac_id; 11395 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 11396 (mac_phy_caps->wireless_modes); 11397 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 11398 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 11399 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 11400 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 11401 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 11402 mac_phy_caps->nss_ratio); 11403 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 11404 11405 return QDF_STATUS_SUCCESS; 11406 } 11407 11408 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 11409 wmi_unified_t wmi_handle, 11410 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 11411 uint8_t phy_idx, 11412 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 11413 { 11414 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11415 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 11416 11417 if (!event) { 11418 WMI_LOGE("null evt_buf"); 11419 return QDF_STATUS_E_INVAL; 11420 } 11421 11422 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11423 11424 if (!param_buf->num_mac_phy_caps) 11425 return QDF_STATUS_SUCCESS; 11426 11427 if (phy_idx >= param_buf->num_mac_phy_caps) 11428 return QDF_STATUS_E_INVAL; 11429 11430 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 11431 11432 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 11433 (phy_id != mac_phy_caps->phy_id)) 11434 return QDF_STATUS_E_INVAL; 11435 11436 param->hw_mode_id = mac_phy_caps->hw_mode_id; 11437 param->phy_id = mac_phy_caps->phy_id; 11438 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11439 wmi_handle, mac_phy_caps->pdev_id); 11440 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 11441 mac_phy_caps->wireless_modes_ext); 11442 11443 return QDF_STATUS_SUCCESS; 11444 } 11445 11446 /** 11447 * extract_reg_cap_service_ready_ext_tlv() - 11448 * extract REG cap from service ready event 11449 * @wmi_handle: wmi handle 11450 * @param evt_buf: pointer to event buffer 11451 * @param param: Pointer to hold evt buf 11452 * @param phy_idx: phy idx should be less than num_mode 11453 * 11454 * Return: QDF_STATUS_SUCCESS for success or error code 11455 */ 11456 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 11457 wmi_unified_t wmi_handle, 11458 uint8_t *event, uint8_t phy_idx, 11459 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 11460 { 11461 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11462 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 11463 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 11464 11465 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 11466 if (!param_buf) 11467 return QDF_STATUS_E_INVAL; 11468 11469 reg_caps = param_buf->soc_hal_reg_caps; 11470 if (!reg_caps) 11471 return QDF_STATUS_E_INVAL; 11472 11473 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 11474 return QDF_STATUS_E_INVAL; 11475 11476 if (phy_idx >= reg_caps->num_phy) 11477 return QDF_STATUS_E_INVAL; 11478 11479 if (!param_buf->hal_reg_caps) 11480 return QDF_STATUS_E_INVAL; 11481 11482 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 11483 11484 param->phy_id = ext_reg_cap->phy_id; 11485 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 11486 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 11487 param->regcap1 = ext_reg_cap->regcap1; 11488 param->regcap2 = ext_reg_cap->regcap2; 11489 param->wireless_modes = convert_wireless_modes_tlv( 11490 ext_reg_cap->wireless_modes); 11491 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 11492 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 11493 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 11494 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 11495 11496 return QDF_STATUS_SUCCESS; 11497 } 11498 11499 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 11500 uint8_t num_dma_ring_caps) 11501 { 11502 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 11503 if (!num_dma_ring_caps) { 11504 WMI_LOGI("%s: dma_ring_caps %d", __func__, num_dma_ring_caps); 11505 return QDF_STATUS_E_INVAL; 11506 } 11507 if (idx >= num_dma_ring_caps) { 11508 WMI_LOGE("%s: Index %d exceeds range", __func__, idx); 11509 return QDF_STATUS_E_INVAL; 11510 } 11511 return QDF_STATUS_SUCCESS; 11512 } 11513 11514 static void 11515 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 11516 struct wlan_psoc_host_dbr_ring_caps *param, 11517 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 11518 { 11519 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 11520 wmi_handle, 11521 dbr_ring_caps->pdev_id); 11522 param->mod_id = dbr_ring_caps->mod_id; 11523 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 11524 param->min_buf_size = dbr_ring_caps->min_buf_size; 11525 param->min_buf_align = dbr_ring_caps->min_buf_align; 11526 } 11527 11528 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 11529 wmi_unified_t wmi_handle, 11530 uint8_t *event, uint8_t idx, 11531 struct wlan_psoc_host_dbr_ring_caps *param) 11532 { 11533 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 11534 QDF_STATUS status; 11535 11536 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 11537 if (!param_buf) 11538 return QDF_STATUS_E_INVAL; 11539 11540 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 11541 if (status != QDF_STATUS_SUCCESS) 11542 return status; 11543 11544 populate_dbr_ring_cap_elems(wmi_handle, param, 11545 ¶m_buf->dma_ring_caps[idx]); 11546 return QDF_STATUS_SUCCESS; 11547 } 11548 11549 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 11550 wmi_unified_t wmi_handle, 11551 uint8_t *event, uint8_t idx, 11552 struct wlan_psoc_host_dbr_ring_caps *param) 11553 { 11554 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 11555 QDF_STATUS status; 11556 11557 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 11558 if (!param_buf) 11559 return QDF_STATUS_E_INVAL; 11560 11561 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 11562 if (status != QDF_STATUS_SUCCESS) 11563 return status; 11564 11565 populate_dbr_ring_cap_elems(wmi_handle, param, 11566 ¶m_buf->dma_ring_caps[idx]); 11567 return QDF_STATUS_SUCCESS; 11568 } 11569 /** 11570 * extract_thermal_stats_tlv() - extract thermal stats from event 11571 * @wmi_handle: wmi handle 11572 * @param evt_buf: Pointer to event buffer 11573 * @param temp: Pointer to hold extracted temperature 11574 * @param level: Pointer to hold extracted level 11575 * 11576 * Return: 0 for success or error code 11577 */ 11578 static QDF_STATUS 11579 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 11580 void *evt_buf, uint32_t *temp, 11581 uint32_t *level, uint32_t *pdev_id) 11582 { 11583 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 11584 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 11585 11586 param_buf = 11587 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 11588 if (!param_buf) 11589 return QDF_STATUS_E_INVAL; 11590 11591 tt_stats_event = param_buf->fixed_param; 11592 11593 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11594 wmi_handle, 11595 tt_stats_event->pdev_id); 11596 *temp = tt_stats_event->temp; 11597 *level = tt_stats_event->level; 11598 11599 return QDF_STATUS_SUCCESS; 11600 } 11601 11602 /** 11603 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 11604 * @wmi_handle: wmi handle 11605 * @param evt_buf: pointer to event buffer 11606 * @param idx: Index to level stats 11607 * @param levelcount: Pointer to hold levelcount 11608 * @param dccount: Pointer to hold dccount 11609 * 11610 * Return: 0 for success or error code 11611 */ 11612 static QDF_STATUS 11613 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 11614 void *evt_buf, uint8_t idx, uint32_t *levelcount, 11615 uint32_t *dccount) 11616 { 11617 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 11618 wmi_therm_throt_level_stats_info *tt_level_info; 11619 11620 param_buf = 11621 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 11622 if (!param_buf) 11623 return QDF_STATUS_E_INVAL; 11624 11625 tt_level_info = param_buf->therm_throt_level_stats_info; 11626 11627 if (idx < THERMAL_LEVELS) { 11628 *levelcount = tt_level_info[idx].level_count; 11629 *dccount = tt_level_info[idx].dc_count; 11630 return QDF_STATUS_SUCCESS; 11631 } 11632 11633 return QDF_STATUS_E_FAILURE; 11634 } 11635 #ifdef BIG_ENDIAN_HOST 11636 /** 11637 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 11638 * @param data_len - data length 11639 * @param data - pointer to data 11640 * 11641 * Return: QDF_STATUS - success or error status 11642 */ 11643 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 11644 { 11645 uint8_t *data_aligned = NULL; 11646 int c; 11647 unsigned char *data_unaligned; 11648 11649 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 11650 FIPS_ALIGN)); 11651 /* Assigning unaligned space to copy the data */ 11652 /* Checking if kmalloc does successful allocation */ 11653 if (!data_unaligned) 11654 return QDF_STATUS_E_FAILURE; 11655 11656 /* Checking if space is alligned */ 11657 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 11658 /* align the data space */ 11659 data_aligned = 11660 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 11661 } else { 11662 data_aligned = (u_int8_t *)data_unaligned; 11663 } 11664 11665 /* memset and copy content from data to data aligned */ 11666 OS_MEMSET(data_aligned, 0, data_len); 11667 OS_MEMCPY(data_aligned, data, data_len); 11668 /* Endianness to LE */ 11669 for (c = 0; c < data_len/4; c++) { 11670 *((u_int32_t *)data_aligned + c) = 11671 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 11672 } 11673 11674 /* Copy content to event->data */ 11675 OS_MEMCPY(data, data_aligned, data_len); 11676 11677 /* clean up allocated space */ 11678 qdf_mem_free(data_unaligned); 11679 data_aligned = NULL; 11680 data_unaligned = NULL; 11681 11682 /*************************************************************/ 11683 11684 return QDF_STATUS_SUCCESS; 11685 } 11686 #else 11687 /** 11688 * fips_conv_data_be() - DUMMY for LE platform 11689 * 11690 * Return: QDF_STATUS - success 11691 */ 11692 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 11693 { 11694 return QDF_STATUS_SUCCESS; 11695 } 11696 #endif 11697 11698 /** 11699 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 11700 * @wmi_handle - wmi handle 11701 * @params - PN request params for peer 11702 * 11703 * Return: QDF_STATUS - success or error status 11704 */ 11705 static QDF_STATUS 11706 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 11707 struct peer_request_pn_param *params) 11708 { 11709 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 11710 wmi_buf_t buf; 11711 uint8_t *buf_ptr; 11712 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 11713 11714 buf = wmi_buf_alloc(wmi_handle, len); 11715 if (!buf) { 11716 WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__); 11717 return QDF_STATUS_E_FAILURE; 11718 } 11719 11720 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11721 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 11722 11723 WMITLV_SET_HDR(&cmd->tlv_header, 11724 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 11725 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 11726 11727 cmd->vdev_id = params->vdev_id; 11728 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 11729 cmd->key_type = params->key_type; 11730 if (wmi_unified_cmd_send(wmi_handle, buf, len, 11731 WMI_PEER_TX_PN_REQUEST_CMDID)) { 11732 WMI_LOGE("%s:Failed to send WMI command\n", __func__); 11733 wmi_buf_free(buf); 11734 return QDF_STATUS_E_FAILURE; 11735 } 11736 return QDF_STATUS_SUCCESS; 11737 } 11738 11739 /** 11740 * extract_get_pn_data_tlv() - extract pn resp 11741 * @wmi_handle - wmi handle 11742 * @params - PN response params for peer 11743 * 11744 * Return: QDF_STATUS - success or error status 11745 */ 11746 static QDF_STATUS 11747 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 11748 struct wmi_host_get_pn_event *param) 11749 { 11750 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 11751 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 11752 11753 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 11754 event = 11755 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 11756 11757 param->vdev_id = event->vdev_id; 11758 param->key_type = event->key_type; 11759 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 11760 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 11761 11762 return QDF_STATUS_SUCCESS; 11763 } 11764 11765 /** 11766 * extract_fips_event_data_tlv() - extract fips event data 11767 * @wmi_handle: wmi handle 11768 * @param evt_buf: pointer to event buffer 11769 * @param param: pointer FIPS event params 11770 * 11771 * Return: 0 for success or error code 11772 */ 11773 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 11774 void *evt_buf, struct wmi_host_fips_event_param *param) 11775 { 11776 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 11777 wmi_pdev_fips_event_fixed_param *event; 11778 11779 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 11780 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 11781 11782 if (fips_conv_data_be(event->data_len, param_buf->data) != 11783 QDF_STATUS_SUCCESS) 11784 return QDF_STATUS_E_FAILURE; 11785 11786 param->data = (uint32_t *)param_buf->data; 11787 param->data_len = event->data_len; 11788 param->error_status = event->error_status; 11789 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 11790 wmi_handle, 11791 event->pdev_id); 11792 11793 return QDF_STATUS_SUCCESS; 11794 } 11795 11796 #ifdef WLAN_FEATURE_DISA 11797 /** 11798 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 11799 * params from event 11800 * @wmi_handle: wmi handle 11801 * @evt_buf: pointer to event buffer 11802 * @resp: Pointer to hold resp parameters 11803 * 11804 * Return: QDF_STATUS_SUCCESS for success or error code 11805 */ 11806 static QDF_STATUS 11807 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 11808 void *evt_buf, 11809 struct disa_encrypt_decrypt_resp_params 11810 *resp) 11811 { 11812 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 11813 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 11814 11815 param_buf = evt_buf; 11816 if (!param_buf) { 11817 WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); 11818 return QDF_STATUS_E_INVAL; 11819 } 11820 11821 data_event = param_buf->fixed_param; 11822 11823 resp->vdev_id = data_event->vdev_id; 11824 resp->status = data_event->status; 11825 11826 if ((data_event->data_length > param_buf->num_enc80211_frame) || 11827 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 11828 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 11829 WMI_LOGE("FW msg data_len %d more than TLV hdr %d", 11830 data_event->data_length, 11831 param_buf->num_enc80211_frame); 11832 return QDF_STATUS_E_INVAL; 11833 } 11834 11835 resp->data_len = data_event->data_length; 11836 11837 if (resp->data_len) 11838 resp->data = (uint8_t *)param_buf->enc80211_frame; 11839 11840 return QDF_STATUS_SUCCESS; 11841 } 11842 #endif /* WLAN_FEATURE_DISA */ 11843 11844 static bool is_management_record_tlv(uint32_t cmd_id) 11845 { 11846 switch (cmd_id) { 11847 case WMI_MGMT_TX_SEND_CMDID: 11848 case WMI_MGMT_TX_COMPLETION_EVENTID: 11849 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 11850 case WMI_MGMT_RX_EVENTID: 11851 return true; 11852 default: 11853 return false; 11854 } 11855 } 11856 11857 static bool is_diag_event_tlv(uint32_t event_id) 11858 { 11859 if (WMI_DIAG_EVENTID == event_id) 11860 return true; 11861 11862 return false; 11863 } 11864 11865 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 11866 { 11867 uint16_t tag = 0; 11868 11869 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 11870 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 11871 __func__); 11872 return tag; 11873 } 11874 11875 if (wmi_handle->tag_crash_inject) 11876 tag = HTC_TX_PACKET_TAG_AUTO_PM; 11877 11878 wmi_handle->tag_crash_inject = false; 11879 return tag; 11880 } 11881 11882 /** 11883 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 11884 * @wmi_handle: WMI handle 11885 * @buf: WMI buffer 11886 * @cmd_id: WMI command Id 11887 * 11888 * Return htc_tx_tag 11889 */ 11890 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 11891 wmi_buf_t buf, 11892 uint32_t cmd_id) 11893 { 11894 uint16_t htc_tx_tag = 0; 11895 11896 switch (cmd_id) { 11897 case WMI_WOW_ENABLE_CMDID: 11898 case WMI_PDEV_SUSPEND_CMDID: 11899 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 11900 case WMI_PDEV_RESUME_CMDID: 11901 case WMI_HB_SET_ENABLE_CMDID: 11902 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 11903 #ifdef FEATURE_WLAN_D0WOW 11904 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 11905 #endif 11906 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 11907 break; 11908 case WMI_FORCE_FW_HANG_CMDID: 11909 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 11910 break; 11911 default: 11912 break; 11913 } 11914 11915 return htc_tx_tag; 11916 } 11917 11918 static struct cur_reg_rule 11919 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 11920 wmi_regulatory_rule_struct *wmi_reg_rule) 11921 { 11922 struct cur_reg_rule *reg_rule_ptr; 11923 uint32_t count; 11924 11925 if (!num_reg_rules) 11926 return NULL; 11927 11928 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 11929 sizeof(*reg_rule_ptr)); 11930 11931 if (!reg_rule_ptr) 11932 return NULL; 11933 11934 for (count = 0; count < num_reg_rules; count++) { 11935 reg_rule_ptr[count].start_freq = 11936 WMI_REG_RULE_START_FREQ_GET( 11937 wmi_reg_rule[count].freq_info); 11938 reg_rule_ptr[count].end_freq = 11939 WMI_REG_RULE_END_FREQ_GET( 11940 wmi_reg_rule[count].freq_info); 11941 reg_rule_ptr[count].max_bw = 11942 WMI_REG_RULE_MAX_BW_GET( 11943 wmi_reg_rule[count].bw_pwr_info); 11944 reg_rule_ptr[count].reg_power = 11945 WMI_REG_RULE_REG_POWER_GET( 11946 wmi_reg_rule[count].bw_pwr_info); 11947 reg_rule_ptr[count].ant_gain = 11948 WMI_REG_RULE_ANTENNA_GAIN_GET( 11949 wmi_reg_rule[count].bw_pwr_info); 11950 reg_rule_ptr[count].flags = 11951 WMI_REG_RULE_FLAGS_GET( 11952 wmi_reg_rule[count].flag_info); 11953 } 11954 11955 return reg_rule_ptr; 11956 } 11957 11958 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 11959 wmi_unified_t wmi_handle, uint8_t *evt_buf, 11960 struct cur_regulatory_info *reg_info, uint32_t len) 11961 { 11962 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 11963 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 11964 wmi_regulatory_rule_struct *wmi_reg_rule; 11965 uint32_t num_2g_reg_rules, num_5g_reg_rules; 11966 11967 WMI_LOGD("processing regulatory channel list"); 11968 11969 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 11970 if (!param_buf) { 11971 WMI_LOGE("invalid channel list event buf"); 11972 return QDF_STATUS_E_FAILURE; 11973 } 11974 11975 chan_list_event_hdr = param_buf->fixed_param; 11976 11977 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 11978 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 11979 num_2g_reg_rules = reg_info->num_2g_reg_rules; 11980 num_5g_reg_rules = reg_info->num_5g_reg_rules; 11981 if ((num_2g_reg_rules > MAX_REG_RULES) || 11982 (num_5g_reg_rules > MAX_REG_RULES) || 11983 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 11984 (num_2g_reg_rules + num_5g_reg_rules != 11985 param_buf->num_reg_rule_array)) { 11986 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 11987 num_2g_reg_rules, num_5g_reg_rules); 11988 return QDF_STATUS_E_FAILURE; 11989 } 11990 if (param_buf->num_reg_rule_array > 11991 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 11992 sizeof(*wmi_reg_rule)) { 11993 wmi_err_rl("Invalid num_reg_rule_array: %u", 11994 param_buf->num_reg_rule_array); 11995 return QDF_STATUS_E_FAILURE; 11996 } 11997 11998 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 11999 REG_ALPHA2_LEN); 12000 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 12001 reg_info->phybitmap = convert_phybitmap_tlv( 12002 chan_list_event_hdr->phybitmap); 12003 reg_info->offload_enabled = true; 12004 reg_info->num_phy = chan_list_event_hdr->num_phy; 12005 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 12006 wmi_handle, chan_list_event_hdr->phy_id); 12007 reg_info->ctry_code = chan_list_event_hdr->country_id; 12008 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 12009 if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) 12010 reg_info->status_code = REG_SET_CC_STATUS_PASS; 12011 else if (chan_list_event_hdr->status_code == 12012 WMI_REG_CURRENT_ALPHA2_NOT_FOUND) 12013 reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; 12014 else if (chan_list_event_hdr->status_code == 12015 WMI_REG_INIT_ALPHA2_NOT_FOUND) 12016 reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; 12017 else if (chan_list_event_hdr->status_code == 12018 WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) 12019 reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; 12020 else if (chan_list_event_hdr->status_code == 12021 WMI_REG_SET_CC_STATUS_NO_MEMORY) 12022 reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; 12023 else if (chan_list_event_hdr->status_code == 12024 WMI_REG_SET_CC_STATUS_FAIL) 12025 reg_info->status_code = REG_SET_CC_STATUS_FAIL; 12026 12027 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 12028 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 12029 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 12030 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 12031 12032 WMI_LOGD(FL("num_phys = %u and phy_id = %u"), 12033 reg_info->num_phy, reg_info->phy_id); 12034 12035 WMI_LOGD("%s:cc %s dfs %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", 12036 __func__, reg_info->alpha2, reg_info->dfs_region, 12037 reg_info->min_bw_2g, reg_info->max_bw_2g, 12038 reg_info->min_bw_5g, reg_info->max_bw_5g); 12039 12040 WMI_LOGD("%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, 12041 num_2g_reg_rules, num_5g_reg_rules); 12042 wmi_reg_rule = 12043 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 12044 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 12045 + WMI_TLV_HDR_SIZE); 12046 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 12047 wmi_reg_rule); 12048 wmi_reg_rule += num_2g_reg_rules; 12049 12050 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 12051 wmi_reg_rule); 12052 12053 WMI_LOGD("processed regulatory channel list"); 12054 12055 return QDF_STATUS_SUCCESS; 12056 } 12057 12058 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 12059 wmi_unified_t wmi_handle, uint8_t *evt_buf, 12060 struct reg_11d_new_country *reg_11d_country, uint32_t len) 12061 { 12062 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 12063 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 12064 12065 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 12066 if (!param_buf) { 12067 WMI_LOGE("invalid 11d country event buf"); 12068 return QDF_STATUS_E_FAILURE; 12069 } 12070 12071 reg_11d_country_event = param_buf->fixed_param; 12072 12073 qdf_mem_copy(reg_11d_country->alpha2, 12074 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 12075 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 12076 12077 WMI_LOGD("processed 11d country event, new cc %s", 12078 reg_11d_country->alpha2); 12079 12080 return QDF_STATUS_SUCCESS; 12081 } 12082 12083 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 12084 wmi_unified_t wmi_handle, uint8_t *evt_buf, 12085 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 12086 { 12087 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 12088 wmi_avoid_freq_range_desc *afr_desc; 12089 uint32_t num_freq_ranges, freq_range_idx; 12090 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 12091 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 12092 12093 if (!param_buf) { 12094 WMI_LOGE("Invalid channel avoid event buffer"); 12095 return QDF_STATUS_E_INVAL; 12096 } 12097 12098 afr_fixed_param = param_buf->fixed_param; 12099 if (!afr_fixed_param) { 12100 WMI_LOGE("Invalid channel avoid event fixed param buffer"); 12101 return QDF_STATUS_E_INVAL; 12102 } 12103 12104 if (!ch_avoid_ind) { 12105 WMI_LOGE("Invalid channel avoid indication buffer"); 12106 return QDF_STATUS_E_INVAL; 12107 } 12108 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 12109 WMI_LOGE(FL("no.of freq ranges exceeded the limit")); 12110 return QDF_STATUS_E_INVAL; 12111 } 12112 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 12113 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 12114 afr_fixed_param->num_freq_ranges; 12115 12116 WMI_LOGD("Channel avoid event received with %d ranges", 12117 num_freq_ranges); 12118 12119 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 12120 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 12121 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 12122 freq_range_idx++) { 12123 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 12124 afr_desc->start_freq; 12125 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 12126 afr_desc->end_freq; 12127 WMI_LOGD("range %d tlv id %u, start freq %u, end freq %u", 12128 freq_range_idx, afr_desc->tlv_header, 12129 afr_desc->start_freq, afr_desc->end_freq); 12130 afr_desc++; 12131 } 12132 12133 return QDF_STATUS_SUCCESS; 12134 } 12135 12136 #ifdef DFS_COMPONENT_ENABLE 12137 /** 12138 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 12139 * @wmi_handle: wma handle 12140 * @evt_buf: event buffer 12141 * @vdev_id: vdev id 12142 * @len: length of buffer 12143 * 12144 * Return: 0 for success or error code 12145 */ 12146 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 12147 uint8_t *evt_buf, 12148 uint32_t *vdev_id, 12149 uint32_t len) 12150 { 12151 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 12152 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 12153 12154 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 12155 if (!param_tlvs) { 12156 WMI_LOGE("invalid cac complete event buf"); 12157 return QDF_STATUS_E_FAILURE; 12158 } 12159 12160 cac_event = param_tlvs->fixed_param; 12161 *vdev_id = cac_event->vdev_id; 12162 WMI_LOGD("processed cac complete event vdev %d", *vdev_id); 12163 12164 return QDF_STATUS_SUCCESS; 12165 } 12166 12167 /** 12168 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 12169 * @wmi_handle: wma handle 12170 * @evt_buf: event buffer 12171 * @vdev_id: vdev id 12172 * @len: length of buffer 12173 * 12174 * Return: 0 for success or error code 12175 */ 12176 static QDF_STATUS 12177 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 12178 uint8_t *evt_buf, 12179 struct vdev_adfs_complete_status *param) 12180 { 12181 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 12182 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 12183 12184 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 12185 if (!param_tlvs) { 12186 WMI_LOGE("invalid ocac complete event buf"); 12187 return QDF_STATUS_E_FAILURE; 12188 } 12189 12190 if (!param_tlvs->fixed_param) { 12191 WMI_LOGE("invalid param_tlvs->fixed_param"); 12192 return QDF_STATUS_E_FAILURE; 12193 } 12194 12195 ocac_complete_status = param_tlvs->fixed_param; 12196 param->vdev_id = ocac_complete_status->vdev_id; 12197 param->chan_freq = ocac_complete_status->chan_freq; 12198 param->center_freq1 = ocac_complete_status->center_freq1; 12199 param->center_freq2 = ocac_complete_status->center_freq2; 12200 param->ocac_status = ocac_complete_status->status; 12201 param->chan_width = ocac_complete_status->chan_width; 12202 WMI_LOGD("processed ocac complete event vdev %d" 12203 " agile chan %d %d width %d status %d", 12204 param->vdev_id, 12205 param->center_freq1, 12206 param->center_freq2, 12207 param->chan_width, 12208 param->ocac_status); 12209 12210 return QDF_STATUS_SUCCESS; 12211 } 12212 12213 /** 12214 * extract_dfs_radar_detection_event_tlv() - extract radar found event 12215 * @wmi_handle: wma handle 12216 * @evt_buf: event buffer 12217 * @radar_found: radar found event info 12218 * @len: length of buffer 12219 * 12220 * Return: 0 for success or error code 12221 */ 12222 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 12223 wmi_unified_t wmi_handle, 12224 uint8_t *evt_buf, 12225 struct radar_found_info *radar_found, 12226 uint32_t len) 12227 { 12228 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 12229 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 12230 12231 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 12232 if (!param_tlv) { 12233 WMI_LOGE("invalid radar detection event buf"); 12234 return QDF_STATUS_E_FAILURE; 12235 } 12236 12237 radar_event = param_tlv->fixed_param; 12238 12239 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 12240 wmi_handle, 12241 radar_event->pdev_id); 12242 12243 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 12244 return QDF_STATUS_E_FAILURE; 12245 12246 radar_found->detection_mode = radar_event->detection_mode; 12247 radar_found->chan_freq = radar_event->chan_freq; 12248 radar_found->chan_width = radar_event->chan_width; 12249 radar_found->detector_id = radar_event->detector_id; 12250 radar_found->segment_id = radar_event->segment_id; 12251 radar_found->timestamp = radar_event->timestamp; 12252 radar_found->is_chirp = radar_event->is_chirp; 12253 radar_found->freq_offset = radar_event->freq_offset; 12254 radar_found->sidx = radar_event->sidx; 12255 12256 WMI_LOGI("processed radar found event pdev %d," 12257 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 12258 "chan_width (RSSI) %d,detector_id (false_radar) %d," 12259 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 12260 "is_chirp %d,detection mode %d", 12261 radar_event->pdev_id, radar_found->pdev_id, 12262 radar_event->timestamp, radar_event->chan_freq, 12263 radar_event->chan_width, radar_event->detector_id, 12264 radar_event->freq_offset, radar_event->segment_id, 12265 radar_event->sidx, radar_event->is_chirp, 12266 radar_event->detection_mode); 12267 12268 return QDF_STATUS_SUCCESS; 12269 } 12270 12271 #ifdef QCA_MCL_DFS_SUPPORT 12272 /** 12273 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 12274 * @wmi_handle: wma handle 12275 * @evt_buf: event buffer 12276 * @wlan_radar_event: Pointer to struct radar_event_info 12277 * @len: length of buffer 12278 * 12279 * Return: QDF_STATUS 12280 */ 12281 static QDF_STATUS extract_wlan_radar_event_info_tlv( 12282 wmi_unified_t wmi_handle, 12283 uint8_t *evt_buf, 12284 struct radar_event_info *wlan_radar_event, 12285 uint32_t len) 12286 { 12287 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 12288 wmi_dfs_radar_event_fixed_param *radar_event; 12289 12290 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 12291 if (!param_tlv) { 12292 WMI_LOGE("invalid wlan radar event buf"); 12293 return QDF_STATUS_E_FAILURE; 12294 } 12295 12296 radar_event = param_tlv->fixed_param; 12297 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 12298 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 12299 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 12300 wlan_radar_event->rssi = radar_event->rssi; 12301 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 12302 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 12303 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 12304 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 12305 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 12306 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 12307 if (radar_event->pulse_flags & 12308 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 12309 wlan_radar_event->is_psidx_diff_valid = true; 12310 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 12311 } else { 12312 wlan_radar_event->is_psidx_diff_valid = false; 12313 } 12314 12315 wlan_radar_event->pdev_id = radar_event->pdev_id; 12316 12317 return QDF_STATUS_SUCCESS; 12318 } 12319 #else 12320 static QDF_STATUS extract_wlan_radar_event_info_tlv( 12321 wmi_unified_t wmi_handle, 12322 uint8_t *evt_buf, 12323 struct radar_event_info *wlan_radar_event, 12324 uint32_t len) 12325 { 12326 return QDF_STATUS_SUCCESS; 12327 } 12328 #endif 12329 #endif 12330 12331 /** 12332 * send_get_rcpi_cmd_tlv() - send request for rcpi value 12333 * @wmi_handle: wmi handle 12334 * @get_rcpi_param: rcpi params 12335 * 12336 * Return: QDF status 12337 */ 12338 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 12339 struct rcpi_req *get_rcpi_param) 12340 { 12341 wmi_buf_t buf; 12342 wmi_request_rcpi_cmd_fixed_param *cmd; 12343 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 12344 12345 buf = wmi_buf_alloc(wmi_handle, len); 12346 if (!buf) 12347 return QDF_STATUS_E_NOMEM; 12348 12349 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 12350 WMITLV_SET_HDR(&cmd->tlv_header, 12351 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 12352 WMITLV_GET_STRUCT_TLVLEN 12353 (wmi_request_rcpi_cmd_fixed_param)); 12354 12355 cmd->vdev_id = get_rcpi_param->vdev_id; 12356 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 12357 &cmd->peer_macaddr); 12358 12359 switch (get_rcpi_param->measurement_type) { 12360 12361 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 12362 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 12363 break; 12364 12365 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 12366 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 12367 break; 12368 12369 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 12370 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 12371 break; 12372 12373 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 12374 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 12375 break; 12376 12377 default: 12378 /* 12379 * invalid rcpi measurement type, fall back to 12380 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 12381 */ 12382 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 12383 break; 12384 } 12385 WMI_LOGD("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 12386 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 12387 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12388 WMI_REQUEST_RCPI_CMDID)) { 12389 12390 WMI_LOGE("%s: Failed to send WMI_REQUEST_RCPI_CMDID", 12391 __func__); 12392 wmi_buf_free(buf); 12393 return QDF_STATUS_E_FAILURE; 12394 } 12395 12396 return QDF_STATUS_SUCCESS; 12397 } 12398 12399 /** 12400 * extract_rcpi_response_event_tlv() - Extract RCPI event params 12401 * @wmi_handle: wmi handle 12402 * @evt_buf: pointer to event buffer 12403 * @res: pointer to hold rcpi response from firmware 12404 * 12405 * Return: QDF_STATUS_SUCCESS for successful event parse 12406 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 12407 */ 12408 static QDF_STATUS 12409 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 12410 void *evt_buf, struct rcpi_res *res) 12411 { 12412 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 12413 wmi_update_rcpi_event_fixed_param *event; 12414 12415 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 12416 if (!param_buf) { 12417 WMI_LOGE(FL("Invalid rcpi event")); 12418 return QDF_STATUS_E_INVAL; 12419 } 12420 12421 event = param_buf->fixed_param; 12422 res->vdev_id = event->vdev_id; 12423 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 12424 12425 switch (event->measurement_type) { 12426 12427 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 12428 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 12429 break; 12430 12431 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 12432 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 12433 break; 12434 12435 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 12436 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 12437 break; 12438 12439 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 12440 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 12441 break; 12442 12443 default: 12444 WMI_LOGE(FL("Invalid rcpi measurement type from firmware")); 12445 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 12446 return QDF_STATUS_E_FAILURE; 12447 } 12448 12449 if (event->status) 12450 return QDF_STATUS_E_FAILURE; 12451 else 12452 return QDF_STATUS_SUCCESS; 12453 } 12454 12455 /** 12456 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 12457 * host to target defines. For legacy there is not conversion 12458 * required. Just return pdev_id as it is. 12459 * @param pdev_id: host pdev_id to be converted. 12460 * Return: target pdev_id after conversion. 12461 */ 12462 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 12463 wmi_unified_t wmi_handle, 12464 uint32_t pdev_id) 12465 { 12466 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 12467 return WMI_PDEV_ID_SOC; 12468 12469 /*No conversion required*/ 12470 return pdev_id; 12471 } 12472 12473 /** 12474 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 12475 * target to host defines. For legacy there is not conversion 12476 * required. Just return pdev_id as it is. 12477 * @param pdev_id: target pdev_id to be converted. 12478 * Return: host pdev_id after conversion. 12479 */ 12480 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 12481 wmi_unified_t wmi_handle, 12482 uint32_t pdev_id) 12483 { 12484 /*No conversion required*/ 12485 return pdev_id; 12486 } 12487 12488 /** 12489 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 12490 * host to target defines. For legacy there is not conversion 12491 * required. Just return phy_id as it is. 12492 * @param pdev_id: host phy_id to be converted. 12493 * Return: target phy_id after conversion. 12494 */ 12495 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 12496 wmi_unified_t wmi_handle, 12497 uint32_t phy_id) 12498 { 12499 /*No conversion required*/ 12500 return phy_id; 12501 } 12502 12503 /** 12504 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 12505 * target to host defines. For legacy there is not conversion 12506 * required. Just return phy_id as it is. 12507 * @param pdev_id: target phy_id to be converted. 12508 * Return: host phy_id after conversion. 12509 */ 12510 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 12511 wmi_unified_t wmi_handle, 12512 uint32_t phy_id) 12513 { 12514 /*No conversion required*/ 12515 return phy_id; 12516 } 12517 12518 /** 12519 * send_set_country_cmd_tlv() - WMI scan channel list function 12520 * @param wmi_handle : handle to WMI. 12521 * @param param : pointer to hold scan channel list parameter 12522 * 12523 * Return: 0 on success and -ve on failure. 12524 */ 12525 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 12526 struct set_country *params) 12527 { 12528 wmi_buf_t buf; 12529 QDF_STATUS qdf_status; 12530 wmi_set_current_country_cmd_fixed_param *cmd; 12531 uint16_t len = sizeof(*cmd); 12532 uint8_t pdev_id = params->pdev_id; 12533 12534 buf = wmi_buf_alloc(wmi_handle, len); 12535 if (!buf) { 12536 qdf_status = QDF_STATUS_E_NOMEM; 12537 goto end; 12538 } 12539 12540 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 12541 WMITLV_SET_HDR(&cmd->tlv_header, 12542 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 12543 WMITLV_GET_STRUCT_TLVLEN 12544 (wmi_set_current_country_cmd_fixed_param)); 12545 12546 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 12547 wmi_handle, 12548 pdev_id); 12549 WMI_LOGD("setting current country to %s and target pdev_id = %u", 12550 params->country, cmd->pdev_id); 12551 12552 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 12553 12554 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 12555 qdf_status = wmi_unified_cmd_send(wmi_handle, 12556 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 12557 12558 if (QDF_IS_STATUS_ERROR(qdf_status)) { 12559 WMI_LOGE("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 12560 wmi_buf_free(buf); 12561 } 12562 12563 end: 12564 return qdf_status; 12565 } 12566 12567 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 12568 WMI_SET_BITS(alpha, 0, 8, val0); \ 12569 WMI_SET_BITS(alpha, 8, 8, val1); \ 12570 WMI_SET_BITS(alpha, 16, 8, val2); \ 12571 } while (0) 12572 12573 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 12574 uint8_t pdev_id, struct cc_regdmn_s *rd) 12575 { 12576 wmi_set_init_country_cmd_fixed_param *cmd; 12577 uint16_t len; 12578 wmi_buf_t buf; 12579 int ret; 12580 12581 len = sizeof(wmi_set_init_country_cmd_fixed_param); 12582 buf = wmi_buf_alloc(wmi_handle, len); 12583 if (!buf) 12584 return QDF_STATUS_E_NOMEM; 12585 12586 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 12587 WMITLV_SET_HDR(&cmd->tlv_header, 12588 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 12589 WMITLV_GET_STRUCT_TLVLEN 12590 (wmi_set_init_country_cmd_fixed_param)); 12591 12592 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12593 wmi_handle, 12594 pdev_id); 12595 12596 if (rd->flags == CC_IS_SET) { 12597 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 12598 cmd->country_code.country_id = rd->cc.country_code; 12599 } else if (rd->flags == ALPHA_IS_SET) { 12600 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 12601 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 12602 rd->cc.alpha[0], 12603 rd->cc.alpha[1], 12604 rd->cc.alpha[2]); 12605 } else if (rd->flags == REGDMN_IS_SET) { 12606 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 12607 cmd->country_code.domain_code = rd->cc.regdmn_id; 12608 } 12609 12610 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 12611 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12612 WMI_SET_INIT_COUNTRY_CMDID); 12613 if (ret) { 12614 WMI_LOGE("Failed to config wow wakeup event"); 12615 wmi_buf_free(buf); 12616 return QDF_STATUS_E_FAILURE; 12617 } 12618 12619 return QDF_STATUS_SUCCESS; 12620 } 12621 12622 /** 12623 * send_obss_detection_cfg_cmd_tlv() - send obss detection 12624 * configurations to firmware. 12625 * @wmi_handle: wmi handle 12626 * @obss_cfg_param: obss detection configurations 12627 * 12628 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 12629 * 12630 * Return: QDF_STATUS 12631 */ 12632 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 12633 struct wmi_obss_detection_cfg_param *obss_cfg_param) 12634 { 12635 wmi_buf_t buf; 12636 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 12637 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 12638 12639 buf = wmi_buf_alloc(wmi_handle, len); 12640 if (!buf) 12641 return QDF_STATUS_E_NOMEM; 12642 12643 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 12644 WMITLV_SET_HDR(&cmd->tlv_header, 12645 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 12646 WMITLV_GET_STRUCT_TLVLEN 12647 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 12648 12649 cmd->vdev_id = obss_cfg_param->vdev_id; 12650 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 12651 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 12652 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 12653 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 12654 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 12655 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 12656 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 12657 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 12658 12659 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 12660 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12661 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 12662 WMI_LOGE("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 12663 wmi_buf_free(buf); 12664 return QDF_STATUS_E_FAILURE; 12665 } 12666 12667 return QDF_STATUS_SUCCESS; 12668 } 12669 12670 /** 12671 * extract_obss_detection_info_tlv() - Extract obss detection info 12672 * received from firmware. 12673 * @evt_buf: pointer to event buffer 12674 * @obss_detection: Pointer to hold obss detection info 12675 * 12676 * Return: QDF_STATUS 12677 */ 12678 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 12679 struct wmi_obss_detect_info 12680 *obss_detection) 12681 { 12682 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 12683 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 12684 12685 if (!obss_detection) { 12686 WMI_LOGE("%s: Invalid obss_detection event buffer", __func__); 12687 return QDF_STATUS_E_INVAL; 12688 } 12689 12690 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 12691 if (!param_buf) { 12692 WMI_LOGE("%s: Invalid evt_buf", __func__); 12693 return QDF_STATUS_E_INVAL; 12694 } 12695 12696 fix_param = param_buf->fixed_param; 12697 obss_detection->vdev_id = fix_param->vdev_id; 12698 obss_detection->matched_detection_masks = 12699 fix_param->matched_detection_masks; 12700 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 12701 &obss_detection->matched_bssid_addr[0]); 12702 switch (fix_param->reason) { 12703 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 12704 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 12705 break; 12706 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 12707 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 12708 break; 12709 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 12710 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 12711 break; 12712 default: 12713 WMI_LOGE("%s: Invalid reason %d", __func__, fix_param->reason); 12714 return QDF_STATUS_E_INVAL; 12715 } 12716 12717 return QDF_STATUS_SUCCESS; 12718 } 12719 12720 /** 12721 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 12722 * @wmi_handle: wmi handle 12723 * @params: pointer to request structure 12724 * 12725 * Return: QDF_STATUS 12726 */ 12727 static QDF_STATUS 12728 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 12729 struct wmi_roam_scan_stats_req *params) 12730 { 12731 wmi_buf_t buf; 12732 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 12733 WMITLV_TAG_ID tag; 12734 uint32_t size; 12735 uint32_t len = sizeof(*cmd); 12736 12737 buf = wmi_buf_alloc(wmi_handle, len); 12738 if (!buf) 12739 return QDF_STATUS_E_FAILURE; 12740 12741 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 12742 12743 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 12744 size = WMITLV_GET_STRUCT_TLVLEN( 12745 wmi_request_roam_scan_stats_cmd_fixed_param); 12746 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 12747 12748 cmd->vdev_id = params->vdev_id; 12749 12750 WMI_LOGD(FL("Roam Scan Stats Req vdev_id: %u"), cmd->vdev_id); 12751 if (wmi_unified_cmd_send(wmi_handle, buf, len, 12752 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 12753 WMI_LOGE("%s: Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID", 12754 __func__); 12755 wmi_buf_free(buf); 12756 return QDF_STATUS_E_FAILURE; 12757 } 12758 12759 return QDF_STATUS_SUCCESS; 12760 } 12761 12762 /** 12763 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 12764 * channel list from firmware 12765 * @wmi_handle: wmi handler 12766 * @vdev_id: vdev id 12767 * 12768 * Return: QDF_STATUS 12769 */ 12770 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 12771 uint32_t vdev_id) 12772 { 12773 wmi_buf_t buf; 12774 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 12775 uint16_t len = sizeof(*cmd); 12776 int ret; 12777 12778 buf = wmi_buf_alloc(wmi_handle, len); 12779 if (!buf) { 12780 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 12781 return QDF_STATUS_E_NOMEM; 12782 } 12783 12784 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 12785 wmi_buf_data(buf); 12786 WMITLV_SET_HDR(&cmd->tlv_header, 12787 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 12788 WMITLV_GET_STRUCT_TLVLEN( 12789 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 12790 cmd->vdev_id = vdev_id; 12791 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 12792 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12793 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 12794 if (QDF_IS_STATUS_ERROR(ret)) { 12795 WMI_LOGE("Failed to send get roam scan channels request = %d", 12796 ret); 12797 wmi_buf_free(buf); 12798 } 12799 return ret; 12800 } 12801 12802 /** 12803 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 12804 * @wmi_handle: wmi handle 12805 * @evt_buf: pointer to event buffer 12806 * @vdev_id: output pointer to hold vdev id 12807 * @res_param: output pointer to hold the allocated response 12808 * 12809 * Return: QDF_STATUS 12810 */ 12811 static QDF_STATUS 12812 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12813 uint32_t *vdev_id, 12814 struct wmi_roam_scan_stats_res **res_param) 12815 { 12816 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 12817 wmi_roam_scan_stats_event_fixed_param *fixed_param; 12818 uint32_t *client_id = NULL; 12819 wmi_roaming_timestamp *timestamp = NULL; 12820 uint32_t *num_channels = NULL; 12821 uint32_t *chan_info = NULL; 12822 wmi_mac_addr *old_bssid = NULL; 12823 uint32_t *is_roaming_success = NULL; 12824 wmi_mac_addr *new_bssid = NULL; 12825 uint32_t *num_roam_candidates = NULL; 12826 wmi_roam_scan_trigger_reason *roam_reason = NULL; 12827 wmi_mac_addr *bssid = NULL; 12828 uint32_t *score = NULL; 12829 uint32_t *channel = NULL; 12830 uint32_t *rssi = NULL; 12831 int chan_idx = 0, cand_idx = 0; 12832 uint32_t total_len; 12833 struct wmi_roam_scan_stats_res *res; 12834 uint32_t i, j; 12835 uint32_t num_scans, scan_param_size; 12836 12837 *res_param = NULL; 12838 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 12839 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 12840 if (!param_buf) { 12841 WMI_LOGE(FL("Invalid roam scan stats event")); 12842 return QDF_STATUS_E_INVAL; 12843 } 12844 12845 fixed_param = param_buf->fixed_param; 12846 12847 num_scans = fixed_param->num_roam_scans; 12848 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 12849 *vdev_id = fixed_param->vdev_id; 12850 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 12851 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 12852 num_scans, WMI_ROAM_SCAN_STATS_MAX); 12853 return QDF_STATUS_E_INVAL; 12854 } 12855 12856 total_len = sizeof(*res) + num_scans * scan_param_size; 12857 12858 res = qdf_mem_malloc(total_len); 12859 if (!res) 12860 return QDF_STATUS_E_NOMEM; 12861 12862 if (!num_scans) { 12863 *res_param = res; 12864 return QDF_STATUS_SUCCESS; 12865 } 12866 12867 if (param_buf->client_id && 12868 param_buf->num_client_id == num_scans) 12869 client_id = param_buf->client_id; 12870 12871 if (param_buf->timestamp && 12872 param_buf->num_timestamp == num_scans) 12873 timestamp = param_buf->timestamp; 12874 12875 if (param_buf->old_bssid && 12876 param_buf->num_old_bssid == num_scans) 12877 old_bssid = param_buf->old_bssid; 12878 12879 if (param_buf->new_bssid && 12880 param_buf->num_new_bssid == num_scans) 12881 new_bssid = param_buf->new_bssid; 12882 12883 if (param_buf->is_roaming_success && 12884 param_buf->num_is_roaming_success == num_scans) 12885 is_roaming_success = param_buf->is_roaming_success; 12886 12887 if (param_buf->roam_reason && 12888 param_buf->num_roam_reason == num_scans) 12889 roam_reason = param_buf->roam_reason; 12890 12891 if (param_buf->num_channels && 12892 param_buf->num_num_channels == num_scans) { 12893 uint32_t count, chan_info_sum = 0; 12894 12895 num_channels = param_buf->num_channels; 12896 for (count = 0; count < param_buf->num_num_channels; count++) { 12897 if (param_buf->num_channels[count] > 12898 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 12899 wmi_err_rl("%u exceeded max scan channels %u", 12900 param_buf->num_channels[count], 12901 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 12902 goto error; 12903 } 12904 chan_info_sum += param_buf->num_channels[count]; 12905 } 12906 12907 if (param_buf->chan_info && 12908 param_buf->num_chan_info == chan_info_sum) 12909 chan_info = param_buf->chan_info; 12910 } 12911 12912 if (param_buf->num_roam_candidates && 12913 param_buf->num_num_roam_candidates == num_scans) { 12914 uint32_t cnt, roam_cand_sum = 0; 12915 12916 num_roam_candidates = param_buf->num_roam_candidates; 12917 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 12918 if (param_buf->num_roam_candidates[cnt] > 12919 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 12920 wmi_err_rl("%u exceeded max scan cand %u", 12921 param_buf->num_roam_candidates[cnt], 12922 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 12923 goto error; 12924 } 12925 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 12926 } 12927 12928 if (param_buf->bssid && 12929 param_buf->num_bssid == roam_cand_sum) 12930 bssid = param_buf->bssid; 12931 12932 if (param_buf->score && 12933 param_buf->num_score == roam_cand_sum) 12934 score = param_buf->score; 12935 12936 if (param_buf->channel && 12937 param_buf->num_channel == roam_cand_sum) 12938 channel = param_buf->channel; 12939 12940 if (param_buf->rssi && 12941 param_buf->num_rssi == roam_cand_sum) 12942 rssi = param_buf->rssi; 12943 } 12944 12945 res->num_roam_scans = num_scans; 12946 for (i = 0; i < num_scans; i++) { 12947 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 12948 12949 if (timestamp) 12950 roam->time_stamp = timestamp[i].lower32bit | 12951 (timestamp[i].upper32bit << 31); 12952 12953 if (client_id) 12954 roam->client_id = client_id[i]; 12955 12956 if (num_channels) { 12957 roam->num_scan_chans = num_channels[i]; 12958 if (chan_info) { 12959 for (j = 0; j < num_channels[i]; j++) 12960 roam->scan_freqs[j] = 12961 chan_info[chan_idx++]; 12962 } 12963 } 12964 12965 if (is_roaming_success) 12966 roam->is_roam_successful = is_roaming_success[i]; 12967 12968 if (roam_reason) { 12969 roam->trigger_id = roam_reason[i].trigger_id; 12970 roam->trigger_value = roam_reason[i].trigger_value; 12971 } 12972 12973 if (num_roam_candidates) { 12974 roam->num_roam_candidates = num_roam_candidates[i]; 12975 12976 for (j = 0; j < num_roam_candidates[i]; j++) { 12977 if (score) 12978 roam->cand[j].score = score[cand_idx]; 12979 if (rssi) 12980 roam->cand[j].rssi = rssi[cand_idx]; 12981 if (channel) 12982 roam->cand[j].freq = 12983 channel[cand_idx]; 12984 12985 if (bssid) 12986 WMI_MAC_ADDR_TO_CHAR_ARRAY( 12987 &bssid[cand_idx], 12988 roam->cand[j].bssid); 12989 12990 cand_idx++; 12991 } 12992 } 12993 12994 if (old_bssid) 12995 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 12996 roam->old_bssid); 12997 12998 if (new_bssid) 12999 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 13000 roam->new_bssid); 13001 } 13002 13003 *res_param = res; 13004 13005 return QDF_STATUS_SUCCESS; 13006 error: 13007 qdf_mem_free(res); 13008 return QDF_STATUS_E_FAILURE; 13009 } 13010 13011 /** 13012 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 13013 * @wmi_handle: wmi handle 13014 * @evt_buf: pointer to event buffer 13015 * @vdev_id: output pointer to hold vdev id 13016 * @tx_status: output pointer to hold the tx_status 13017 * 13018 * Return: QDF_STATUS 13019 */ 13020 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 13021 void *evt_buf, 13022 uint32_t *vdev_id, 13023 uint32_t *tx_status) { 13024 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 13025 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 13026 13027 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 13028 if (!param_buf) { 13029 WMI_LOGE("Invalid offload bcn tx status event buffer"); 13030 return QDF_STATUS_E_INVAL; 13031 } 13032 13033 bcn_tx_status_event = param_buf->fixed_param; 13034 *vdev_id = bcn_tx_status_event->vdev_id; 13035 *tx_status = bcn_tx_status_event->tx_status; 13036 13037 return QDF_STATUS_SUCCESS; 13038 } 13039 13040 #ifdef WLAN_SUPPORT_GREEN_AP 13041 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 13042 uint8_t *evt_buf, 13043 struct wlan_green_ap_egap_status_info *egap_status_info_params) 13044 { 13045 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 13046 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 13047 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 13048 13049 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 13050 if (!param_buf) { 13051 WMI_LOGE("Invalid EGAP Info status event buffer"); 13052 return QDF_STATUS_E_INVAL; 13053 } 13054 13055 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 13056 param_buf->fixed_param; 13057 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 13058 param_buf->chainmask_list; 13059 13060 if (!egap_info_event || !chainmask_event) { 13061 WMI_LOGE("Invalid EGAP Info event or chainmask event"); 13062 return QDF_STATUS_E_INVAL; 13063 } 13064 13065 egap_status_info_params->status = egap_info_event->status; 13066 egap_status_info_params->mac_id = chainmask_event->mac_id; 13067 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 13068 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 13069 13070 return QDF_STATUS_SUCCESS; 13071 } 13072 #endif 13073 13074 /* 13075 * extract_comb_phyerr_tlv() - extract comb phy error from event 13076 * @wmi_handle: wmi handle 13077 * @evt_buf: pointer to event buffer 13078 * @datalen: data length of event buffer 13079 * @buf_offset: Pointer to hold value of current event buffer offset 13080 * post extraction 13081 * @phyerr: Pointer to hold phyerr 13082 * 13083 * Return: QDF_STATUS 13084 */ 13085 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 13086 void *evt_buf, 13087 uint16_t datalen, 13088 uint16_t *buf_offset, 13089 wmi_host_phyerr_t *phyerr) 13090 { 13091 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 13092 wmi_comb_phyerr_rx_hdr *pe_hdr; 13093 13094 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 13095 if (!param_tlvs) { 13096 WMI_LOGD("%s: Received null data from FW", __func__); 13097 return QDF_STATUS_E_FAILURE; 13098 } 13099 13100 pe_hdr = param_tlvs->hdr; 13101 if (!pe_hdr) { 13102 WMI_LOGD("%s: Received Data PE Header is NULL", __func__); 13103 return QDF_STATUS_E_FAILURE; 13104 } 13105 13106 /* Ensure it's at least the size of the header */ 13107 if (datalen < sizeof(*pe_hdr)) { 13108 WMI_LOGD("%s: Expected minimum size %zu, received %d", 13109 __func__, sizeof(*pe_hdr), datalen); 13110 return QDF_STATUS_E_FAILURE; 13111 } 13112 13113 phyerr->pdev_id = wmi_handle->ops-> 13114 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 13115 phyerr->tsf64 = pe_hdr->tsf_l32; 13116 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 13117 phyerr->bufp = param_tlvs->bufp; 13118 13119 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 13120 WMI_LOGD("Invalid buf_len %d, num_bufp %d", 13121 pe_hdr->buf_len, param_tlvs->num_bufp); 13122 return QDF_STATUS_E_FAILURE; 13123 } 13124 13125 phyerr->buf_len = pe_hdr->buf_len; 13126 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 13127 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 13128 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 13129 13130 return QDF_STATUS_SUCCESS; 13131 } 13132 13133 /** 13134 * extract_single_phyerr_tlv() - extract single phy error from event 13135 * @wmi_handle: wmi handle 13136 * @evt_buf: pointer to event buffer 13137 * @datalen: data length of event buffer 13138 * @buf_offset: Pointer to hold value of current event buffer offset 13139 * post extraction 13140 * @phyerr: Pointer to hold phyerr 13141 * 13142 * Return: QDF_STATUS 13143 */ 13144 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 13145 void *evt_buf, 13146 uint16_t datalen, 13147 uint16_t *buf_offset, 13148 wmi_host_phyerr_t *phyerr) 13149 { 13150 wmi_single_phyerr_rx_event *ev; 13151 uint16_t n = *buf_offset; 13152 uint8_t *data = (uint8_t *)evt_buf; 13153 13154 if (n < datalen) { 13155 if ((datalen - n) < sizeof(ev->hdr)) { 13156 WMI_LOGD("%s: Not enough space. len=%d, n=%d, hdr=%zu", 13157 __func__, datalen, n, sizeof(ev->hdr)); 13158 return QDF_STATUS_E_FAILURE; 13159 } 13160 13161 /* 13162 * Obtain a pointer to the beginning of the current event. 13163 * data[0] is the beginning of the WMI payload. 13164 */ 13165 ev = (wmi_single_phyerr_rx_event *)&data[n]; 13166 13167 /* 13168 * Sanity check the buffer length of the event against 13169 * what we currently have. 13170 * 13171 * Since buf_len is 32 bits, we check if it overflows 13172 * a large 32 bit value. It's not 0x7fffffff because 13173 * we increase n by (buf_len + sizeof(hdr)), which would 13174 * in itself cause n to overflow. 13175 * 13176 * If "int" is 64 bits then this becomes a moot point. 13177 */ 13178 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 13179 WMI_LOGD("%s: buf_len is garbage 0x%x", 13180 __func__, ev->hdr.buf_len); 13181 return QDF_STATUS_E_FAILURE; 13182 } 13183 13184 if ((n + ev->hdr.buf_len) > datalen) { 13185 WMI_LOGD("%s: len exceeds n=%d, buf_len=%d, datalen=%d", 13186 __func__, n, ev->hdr.buf_len, datalen); 13187 return QDF_STATUS_E_FAILURE; 13188 } 13189 13190 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 13191 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 13192 phyerr->bufp = &ev->bufp[0]; 13193 phyerr->buf_len = ev->hdr.buf_len; 13194 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 13195 13196 /* 13197 * Advance the buffer pointer to the next PHY error. 13198 * buflen is the length of this payload, so we need to 13199 * advance past the current header _AND_ the payload. 13200 */ 13201 n += sizeof(*ev) + ev->hdr.buf_len; 13202 } 13203 *buf_offset = n; 13204 13205 return QDF_STATUS_SUCCESS; 13206 } 13207 13208 /** 13209 * extract_esp_estimation_ev_param_tlv() - extract air time from event 13210 * @wmi_handle: wmi handle 13211 * @evt_buf: pointer to event buffer 13212 * @param: Pointer to hold esp event 13213 * 13214 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 13215 */ 13216 static QDF_STATUS 13217 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 13218 void *evt_buf, 13219 struct esp_estimation_event *param) 13220 { 13221 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 13222 wmi_esp_estimate_event_fixed_param *esp_event; 13223 13224 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 13225 if (!param_buf) { 13226 WMI_LOGE("Invalid ESP Estimate Event buffer"); 13227 return QDF_STATUS_E_INVAL; 13228 } 13229 esp_event = param_buf->fixed_param; 13230 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 13231 13232 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 13233 wmi_handle, 13234 esp_event->pdev_id); 13235 13236 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 13237 return QDF_STATUS_E_FAILURE; 13238 13239 return QDF_STATUS_SUCCESS; 13240 } 13241 13242 /* 13243 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 13244 * updating bss color change within firmware when AP announces bss color change. 13245 * @wmi_handle: wmi handle 13246 * @vdev_id: vdev ID 13247 * @enable: enable bss color change within firmware 13248 * 13249 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 13250 * 13251 * Return: QDF_STATUS 13252 */ 13253 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 13254 uint32_t vdev_id, 13255 bool enable) 13256 { 13257 wmi_buf_t buf; 13258 wmi_bss_color_change_enable_fixed_param *cmd; 13259 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 13260 13261 buf = wmi_buf_alloc(wmi_handle, len); 13262 if (!buf) 13263 return QDF_STATUS_E_NOMEM; 13264 13265 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 13266 WMITLV_SET_HDR(&cmd->tlv_header, 13267 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 13268 WMITLV_GET_STRUCT_TLVLEN 13269 (wmi_bss_color_change_enable_fixed_param)); 13270 cmd->vdev_id = vdev_id; 13271 cmd->enable = enable; 13272 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 13273 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13274 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 13275 WMI_LOGE("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 13276 wmi_buf_free(buf); 13277 return QDF_STATUS_E_FAILURE; 13278 } 13279 13280 return QDF_STATUS_SUCCESS; 13281 } 13282 13283 /** 13284 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 13285 * configurations to firmware. 13286 * @wmi_handle: wmi handle 13287 * @cfg_param: obss detection configurations 13288 * 13289 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 13290 * 13291 * Return: QDF_STATUS 13292 */ 13293 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 13294 wmi_unified_t wmi_handle, 13295 struct wmi_obss_color_collision_cfg_param *cfg_param) 13296 { 13297 wmi_buf_t buf; 13298 wmi_obss_color_collision_det_config_fixed_param *cmd; 13299 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 13300 13301 buf = wmi_buf_alloc(wmi_handle, len); 13302 if (!buf) 13303 return QDF_STATUS_E_NOMEM; 13304 13305 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 13306 buf); 13307 WMITLV_SET_HDR(&cmd->tlv_header, 13308 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 13309 WMITLV_GET_STRUCT_TLVLEN 13310 (wmi_obss_color_collision_det_config_fixed_param)); 13311 cmd->vdev_id = cfg_param->vdev_id; 13312 cmd->flags = cfg_param->flags; 13313 cmd->current_bss_color = cfg_param->current_bss_color; 13314 cmd->detection_period_ms = cfg_param->detection_period_ms; 13315 cmd->scan_period_ms = cfg_param->scan_period_ms; 13316 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 13317 13318 switch (cfg_param->evt_type) { 13319 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 13320 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 13321 break; 13322 case OBSS_COLOR_COLLISION_DETECTION: 13323 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 13324 break; 13325 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 13326 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 13327 break; 13328 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 13329 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 13330 break; 13331 default: 13332 WMI_LOGE("%s: invalid event type: %d", 13333 __func__, cfg_param->evt_type); 13334 wmi_buf_free(buf); 13335 return QDF_STATUS_E_FAILURE; 13336 } 13337 13338 WMI_LOGD("%s: evt_type: %d vdev id: %d current_bss_color: %d\n" 13339 "detection_period_ms: %d scan_period_ms: %d\n" 13340 "free_slot_expiry_timer_ms: %d", 13341 __func__, cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 13342 cmd->detection_period_ms, cmd->scan_period_ms, 13343 cmd->free_slot_expiry_time_ms); 13344 13345 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 13346 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13347 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 13348 WMI_LOGE("%s: Sending OBSS color det cmd failed, vdev_id: %d", 13349 __func__, cfg_param->vdev_id); 13350 wmi_buf_free(buf); 13351 return QDF_STATUS_E_FAILURE; 13352 } 13353 13354 return QDF_STATUS_SUCCESS; 13355 } 13356 13357 /** 13358 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 13359 * received from firmware. 13360 * @evt_buf: pointer to event buffer 13361 * @info: Pointer to hold bss collision info 13362 * 13363 * Return: QDF_STATUS 13364 */ 13365 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 13366 struct wmi_obss_color_collision_info *info) 13367 { 13368 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 13369 wmi_obss_color_collision_evt_fixed_param *fix_param; 13370 13371 if (!info) { 13372 WMI_LOGE("%s: Invalid obss color buffer", __func__); 13373 return QDF_STATUS_E_INVAL; 13374 } 13375 13376 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 13377 evt_buf; 13378 if (!param_buf) { 13379 WMI_LOGE("%s: Invalid evt_buf", __func__); 13380 return QDF_STATUS_E_INVAL; 13381 } 13382 13383 fix_param = param_buf->fixed_param; 13384 info->vdev_id = fix_param->vdev_id; 13385 info->obss_color_bitmap_bit0to31 = 13386 fix_param->bss_color_bitmap_bit0to31; 13387 info->obss_color_bitmap_bit32to63 = 13388 fix_param->bss_color_bitmap_bit32to63; 13389 13390 switch (fix_param->evt_type) { 13391 case WMI_BSS_COLOR_COLLISION_DISABLE: 13392 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 13393 break; 13394 case WMI_BSS_COLOR_COLLISION_DETECTION: 13395 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 13396 break; 13397 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 13398 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 13399 break; 13400 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 13401 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 13402 break; 13403 default: 13404 WMI_LOGE("%s: invalid event type: %d, vdev_id: %d", 13405 __func__, fix_param->evt_type, fix_param->vdev_id); 13406 return QDF_STATUS_E_FAILURE; 13407 } 13408 13409 return QDF_STATUS_SUCCESS; 13410 } 13411 13412 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 13413 { 13414 struct wmi_ops *ops = wmi_handle->ops; 13415 13416 ops->send_obss_color_collision_cfg_cmd = 13417 send_obss_color_collision_cfg_cmd_tlv; 13418 ops->extract_obss_color_collision_info = 13419 extract_obss_color_collision_info_tlv; 13420 } 13421 13422 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 13423 static QDF_STATUS 13424 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 13425 struct config_fils_params *param) 13426 { 13427 wmi_buf_t buf; 13428 wmi_enable_fils_cmd_fixed_param *cmd; 13429 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 13430 13431 buf = wmi_buf_alloc(wmi_handle, len); 13432 if (!buf) 13433 return QDF_STATUS_E_NOMEM; 13434 13435 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 13436 buf); 13437 WMITLV_SET_HDR(&cmd->tlv_header, 13438 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 13439 WMITLV_GET_STRUCT_TLVLEN 13440 (wmi_enable_fils_cmd_fixed_param)); 13441 cmd->vdev_id = param->vdev_id; 13442 cmd->fd_period = param->fd_period; 13443 if (param->send_prb_rsp_frame) 13444 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 13445 WMI_LOGD("%s: vdev id: %d fd_period: %d cmd->Flags %d", 13446 __func__, cmd->vdev_id, cmd->fd_period, cmd->flags); 13447 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 13448 if (wmi_unified_cmd_send(wmi_handle, buf, len, 13449 WMI_ENABLE_FILS_CMDID)) { 13450 WMI_LOGE("%s: Sending FILS cmd failed, vdev_id: %d", 13451 __func__, param->vdev_id); 13452 wmi_buf_free(buf); 13453 return QDF_STATUS_E_FAILURE; 13454 } 13455 13456 return QDF_STATUS_SUCCESS; 13457 } 13458 #endif 13459 13460 #ifdef WLAN_MWS_INFO_DEBUGFS 13461 /** 13462 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 13463 * 13464 * @wmi_handle: wmi handle 13465 * @vdev_id: vdev id 13466 * @cmd_id: Coex command id 13467 * 13468 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 13469 * 13470 * Return: QDF_STATUS 13471 */ 13472 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 13473 uint32_t vdev_id, 13474 uint32_t cmd_id) 13475 { 13476 wmi_buf_t buf; 13477 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 13478 uint16_t len = sizeof(*cmd); 13479 int ret; 13480 13481 buf = wmi_buf_alloc(wmi_handle, len); 13482 if (!buf) { 13483 WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); 13484 return QDF_STATUS_E_NOMEM; 13485 } 13486 13487 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 13488 WMITLV_SET_HDR(&cmd->tlv_header, 13489 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 13490 WMITLV_GET_STRUCT_TLVLEN 13491 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 13492 cmd->vdev_id = vdev_id; 13493 cmd->cmd_id = cmd_id; 13494 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 13495 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13496 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 13497 if (QDF_IS_STATUS_ERROR(ret)) { 13498 WMI_LOGE("Failed to send set param command ret = %d", ret); 13499 wmi_buf_free(buf); 13500 } 13501 return ret; 13502 } 13503 #endif 13504 13505 #ifdef WIFI_POS_CONVERGED 13506 /** 13507 * extract_oem_response_param_tlv() - Extract oem response params 13508 * @wmi_handle: wmi handle 13509 * @resp_buf: response buffer 13510 * @oem_resp_param: pointer to hold oem response params 13511 * 13512 * Return: QDF_STATUS_SUCCESS on success or proper error code. 13513 */ 13514 static QDF_STATUS 13515 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 13516 struct wmi_oem_response_param *oem_resp_param) 13517 { 13518 uint64_t temp_addr; 13519 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 13520 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 13521 13522 if (!param_buf) { 13523 WMI_LOGE("Invalid OEM response"); 13524 return QDF_STATUS_E_INVAL; 13525 } 13526 13527 if (param_buf->num_data) { 13528 oem_resp_param->num_data1 = param_buf->num_data; 13529 oem_resp_param->data_1 = param_buf->data; 13530 } 13531 13532 if (param_buf->num_data2) { 13533 oem_resp_param->num_data2 = param_buf->num_data2; 13534 oem_resp_param->data_2 = param_buf->data2; 13535 } 13536 13537 if (param_buf->indirect_data) { 13538 oem_resp_param->indirect_data.pdev_id = 13539 param_buf->indirect_data->pdev_id; 13540 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 13541 oem_resp_param->indirect_data.addr = 13542 param_buf->indirect_data->addr_lo + 13543 ((uint64_t)temp_addr << 32); 13544 oem_resp_param->indirect_data.len = 13545 param_buf->indirect_data->len; 13546 } 13547 13548 return QDF_STATUS_SUCCESS; 13549 } 13550 #endif /* WIFI_POS_CONVERGED */ 13551 13552 /** 13553 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 13554 * @wmi_handle: wmi handle 13555 * @event_buf: pointer to event buffer 13556 * @cmd_status: status of HW mode change command 13557 * 13558 * Return QDF_STATUS_SUCCESS on success or proper error code. 13559 */ 13560 static QDF_STATUS 13561 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13562 uint32_t *cmd_status) 13563 { 13564 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 13565 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 13566 13567 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 13568 if (!param_buf) { 13569 WMI_LOGE("Invalid mode change event buffer"); 13570 return QDF_STATUS_E_INVAL; 13571 } 13572 13573 fixed_param = param_buf->fixed_param; 13574 if (!fixed_param) { 13575 WMI_LOGE("Invalid fixed param"); 13576 return QDF_STATUS_E_INVAL; 13577 } 13578 13579 *cmd_status = fixed_param->status; 13580 return QDF_STATUS_SUCCESS; 13581 } 13582 13583 #ifdef FEATURE_ANI_LEVEL_REQUEST 13584 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 13585 uint32_t *freqs, 13586 uint8_t num_freqs) 13587 { 13588 wmi_buf_t buf; 13589 wmi_get_channel_ani_cmd_fixed_param *cmd; 13590 QDF_STATUS ret; 13591 uint32_t len; 13592 A_UINT32 *chan_list; 13593 uint8_t i, *buf_ptr; 13594 13595 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 13596 WMI_TLV_HDR_SIZE + 13597 num_freqs * sizeof(A_UINT32); 13598 13599 buf = wmi_buf_alloc(wmi_handle, len); 13600 if (!buf) 13601 return QDF_STATUS_E_FAILURE; 13602 13603 buf_ptr = (uint8_t *)wmi_buf_data(buf); 13604 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 13605 WMITLV_SET_HDR(&cmd->tlv_header, 13606 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 13607 WMITLV_GET_STRUCT_TLVLEN( 13608 wmi_get_channel_ani_cmd_fixed_param)); 13609 13610 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 13611 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 13612 (num_freqs * sizeof(A_UINT32))); 13613 13614 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 13615 for (i = 0; i < num_freqs; i++) { 13616 chan_list[i] = freqs[i]; 13617 WMI_LOGD("Requesting ANI for channel[%d]", chan_list[i]); 13618 } 13619 13620 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 13621 WMI_GET_CHANNEL_ANI_CMDID); 13622 13623 if (QDF_IS_STATUS_ERROR(ret)) { 13624 WMI_LOGE("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 13625 wmi_buf_free(buf); 13626 } 13627 13628 return ret; 13629 } 13630 13631 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 13632 struct wmi_host_ani_level_event **info, 13633 uint32_t *num_freqs) 13634 { 13635 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 13636 wmi_get_channel_ani_event_fixed_param *fixed_param; 13637 wmi_channel_ani_info_tlv_param *tlv_params; 13638 uint8_t *buf_ptr, i; 13639 13640 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 13641 if (!param_buf) { 13642 wmi_err("Invalid ani level event buffer"); 13643 return QDF_STATUS_E_INVAL; 13644 } 13645 13646 fixed_param = 13647 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 13648 if (!fixed_param) { 13649 wmi_err("Invalid fixed param"); 13650 return QDF_STATUS_E_INVAL; 13651 } 13652 13653 buf_ptr = (uint8_t *)fixed_param; 13654 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 13655 buf_ptr += WMI_TLV_HDR_SIZE; 13656 13657 *num_freqs = param_buf->num_ani_info; 13658 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 13659 wmi_err("Invalid number of freqs received"); 13660 return QDF_STATUS_E_INVAL; 13661 } 13662 13663 *info = qdf_mem_malloc(*num_freqs * 13664 sizeof(struct wmi_host_ani_level_event)); 13665 if (!(*info)) 13666 return QDF_STATUS_E_NOMEM; 13667 13668 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 13669 for (i = 0; i < param_buf->num_ani_info; i++) { 13670 (*info)[i].ani_level = tlv_params->ani_level; 13671 (*info)[i].chan_freq = tlv_params->chan_freq; 13672 tlv_params++; 13673 } 13674 13675 return QDF_STATUS_SUCCESS; 13676 } 13677 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 13678 13679 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 13680 /** 13681 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 13682 * from the WMI_ROAM_STATS_EVENTID 13683 * @wmi_handle: wmi handle 13684 * @evt_buf: Pointer to the event buffer 13685 * @trig: Pointer to destination structure to fill data 13686 * @idx: TLV id 13687 */ 13688 static QDF_STATUS 13689 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13690 struct wmi_roam_trigger_info *trig, uint8_t idx) 13691 { 13692 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13693 wmi_roam_trigger_reason *src_data = NULL; 13694 13695 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13696 if (!param_buf || !param_buf->roam_trigger_reason) 13697 return QDF_STATUS_E_FAILURE; 13698 13699 src_data = ¶m_buf->roam_trigger_reason[idx]; 13700 13701 trig->present = true; 13702 trig->trigger_reason = src_data->trigger_reason; 13703 trig->trigger_sub_reason = src_data->trigger_sub_reason; 13704 trig->current_rssi = src_data->current_rssi; 13705 trig->timestamp = src_data->timestamp; 13706 13707 switch (trig->trigger_reason) { 13708 case WMI_ROAM_TRIGGER_REASON_PER: 13709 case WMI_ROAM_TRIGGER_REASON_BMISS: 13710 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 13711 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 13712 case WMI_ROAM_TRIGGER_REASON_MAWC: 13713 case WMI_ROAM_TRIGGER_REASON_DENSE: 13714 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 13715 case WMI_ROAM_TRIGGER_REASON_IDLE: 13716 case WMI_ROAM_TRIGGER_REASON_FORCED: 13717 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 13718 return QDF_STATUS_SUCCESS; 13719 13720 case WMI_ROAM_TRIGGER_REASON_BTM: 13721 trig->btm_trig_data.btm_request_mode = 13722 src_data->btm_request_mode; 13723 trig->btm_trig_data.disassoc_timer = 13724 src_data->disassoc_imminent_timer; 13725 trig->btm_trig_data.validity_interval = 13726 src_data->validity_internal; 13727 trig->btm_trig_data.candidate_list_count = 13728 src_data->candidate_list_count; 13729 trig->btm_trig_data.btm_resp_status = 13730 src_data->btm_response_status_code; 13731 return QDF_STATUS_SUCCESS; 13732 13733 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 13734 trig->cu_trig_data.cu_load = src_data->cu_load; 13735 return QDF_STATUS_SUCCESS; 13736 13737 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 13738 trig->deauth_trig_data.type = src_data->deauth_type; 13739 trig->deauth_trig_data.reason = src_data->deauth_reason; 13740 return QDF_STATUS_SUCCESS; 13741 13742 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 13743 trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold; 13744 return QDF_STATUS_SUCCESS; 13745 13746 default: 13747 return QDF_STATUS_SUCCESS; 13748 } 13749 13750 return QDF_STATUS_SUCCESS; 13751 } 13752 13753 /** 13754 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 13755 * from the WMI_ROAM_STATS_EVENTID 13756 * @wmi_handle: wmi handle 13757 * @evt_buf: Pointer to the event buffer 13758 * @dst: Pointer to destination structure to fill data 13759 * @ap_idx: TLV index for this roam scan 13760 * @num_cand: number of candidates list in the roam scan 13761 */ 13762 static QDF_STATUS 13763 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13764 struct wmi_roam_candidate_info *dst, 13765 uint8_t ap_idx, uint16_t num_cand) 13766 { 13767 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13768 wmi_roam_ap_info *src = NULL; 13769 uint8_t i; 13770 13771 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13772 if (!param_buf) { 13773 wmi_err("Param buf is NULL"); 13774 return QDF_STATUS_E_FAILURE; 13775 } 13776 13777 if (ap_idx >= param_buf->num_roam_ap_info) { 13778 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 13779 ap_idx, param_buf->num_roam_ap_info); 13780 return QDF_STATUS_E_FAILURE; 13781 } 13782 13783 src = ¶m_buf->roam_ap_info[ap_idx]; 13784 13785 for (i = 0; i < num_cand; i++) { 13786 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 13787 dst->type = src->candidate_type; 13788 dst->freq = src->channel; 13789 dst->etp = src->etp; 13790 dst->rssi = src->rssi; 13791 dst->rssi_score = src->rssi_score; 13792 dst->cu_load = src->cu_load; 13793 dst->cu_score = src->cu_score; 13794 dst->total_score = src->total_score; 13795 dst->timestamp = src->timestamp; 13796 13797 src++; 13798 dst++; 13799 } 13800 13801 return QDF_STATUS_SUCCESS; 13802 } 13803 13804 /** 13805 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 13806 * from the WMI_ROAM_STATS_EVENTID 13807 * @wmi_handle: wmi handle 13808 * @evt_buf: Pointer to the event buffer 13809 * @dst: Pointer to destination structure to fill data 13810 * @idx: TLV id 13811 * @chan_idx: Index of the channel tlv for the current roam trigger 13812 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 13813 */ 13814 static QDF_STATUS 13815 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13816 struct wmi_roam_scan_data *dst, uint8_t idx, 13817 uint8_t chan_idx, uint8_t ap_idx) 13818 { 13819 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13820 wmi_roam_scan_info *src_data = NULL; 13821 wmi_roam_scan_channel_info *src_chan = NULL; 13822 QDF_STATUS status; 13823 uint8_t i; 13824 13825 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13826 if (!param_buf || !param_buf->roam_scan_info || 13827 idx >= param_buf->num_roam_scan_info) 13828 return QDF_STATUS_E_FAILURE; 13829 13830 src_data = ¶m_buf->roam_scan_info[idx]; 13831 13832 dst->present = true; 13833 dst->type = src_data->roam_scan_type; 13834 dst->num_chan = src_data->roam_scan_channel_count; 13835 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 13836 13837 /* Read the channel data only for dst->type is 0 (partial scan) */ 13838 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 13839 chan_idx < param_buf->num_roam_scan_chan_info) { 13840 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 13841 dst->num_chan = MAX_ROAM_SCAN_CHAN; 13842 13843 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 13844 for (i = 0; i < dst->num_chan; i++) { 13845 dst->chan_freq[i] = src_chan->channel; 13846 src_chan++; 13847 } 13848 } 13849 13850 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 13851 return QDF_STATUS_SUCCESS; 13852 13853 dst->num_ap = src_data->roam_ap_count; 13854 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 13855 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 13856 13857 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 13858 ap_idx, dst->num_ap); 13859 if (QDF_IS_STATUS_ERROR(status)) { 13860 WMI_LOGE("Extract candidate stats for tlv[%d] failed", idx); 13861 return status; 13862 } 13863 13864 return QDF_STATUS_SUCCESS; 13865 } 13866 13867 /** 13868 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 13869 * from the WMI_ROAM_STATS_EVENTID 13870 * @wmi_handle: wmi handle 13871 * @evt_buf: Pointer to the event buffer 13872 * @dst: Pointer to destination structure to fill data 13873 * @idx: TLV id 13874 */ 13875 static QDF_STATUS 13876 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13877 struct wmi_roam_result *dst, uint8_t idx) 13878 { 13879 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13880 wmi_roam_result *src_data = NULL; 13881 13882 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13883 if (!param_buf || !param_buf->roam_result || 13884 idx >= param_buf->num_roam_result) 13885 return QDF_STATUS_E_FAILURE; 13886 13887 src_data = ¶m_buf->roam_result[idx]; 13888 13889 dst->present = true; 13890 dst->status = src_data->roam_status ? false : true; 13891 dst->timestamp = src_data->timestamp; 13892 dst->fail_reason = src_data->roam_fail_reason; 13893 13894 return QDF_STATUS_SUCCESS; 13895 } 13896 13897 /** 13898 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 13899 * from the WMI_ROAM_STATS_EVENTID 13900 * @wmi_handle: wmi handle 13901 * @evt_buf: Pointer to the event buffer 13902 * @dst: Pointer to destination structure to fill data 13903 * @idx: TLV id 13904 * @rpt_idx: Neighbor report Channel index 13905 */ 13906 static QDF_STATUS 13907 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13908 struct wmi_neighbor_report_data *dst, 13909 uint8_t idx, uint8_t rpt_idx) 13910 { 13911 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 13912 wmi_roam_neighbor_report_info *src_data = NULL; 13913 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 13914 uint8_t i; 13915 13916 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 13917 if (!param_buf || !param_buf->roam_neighbor_report_info || 13918 !param_buf->num_roam_neighbor_report_info || 13919 idx >= param_buf->num_roam_neighbor_report_info) { 13920 WMI_LOGD("%s: Invalid 1kv param buf", __func__); 13921 return QDF_STATUS_E_FAILURE; 13922 } 13923 13924 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 13925 13926 dst->present = true; 13927 dst->req_type = src_data->request_type; 13928 dst->num_freq = src_data->neighbor_report_channel_count; 13929 dst->req_time = src_data->neighbor_report_request_timestamp; 13930 dst->resp_time = src_data->neighbor_report_response_timestamp; 13931 13932 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 13933 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 13934 return QDF_STATUS_SUCCESS; 13935 13936 if (!param_buf->roam_neighbor_report_chan_info) { 13937 WMI_LOGD("%s: 11kv channel present, but TLV is NULL num_freq:%d", 13938 __func__, dst->num_freq); 13939 dst->num_freq = 0; 13940 /* return success as its optional tlv and we can print neighbor 13941 * report received info 13942 */ 13943 return QDF_STATUS_SUCCESS; 13944 } 13945 13946 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 13947 13948 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 13949 dst->num_freq = MAX_ROAM_SCAN_CHAN; 13950 13951 for (i = 0; i < dst->num_freq; i++) { 13952 dst->freq[i] = src_freq->channel; 13953 src_freq++; 13954 } 13955 13956 return QDF_STATUS_SUCCESS; 13957 } 13958 #else 13959 static inline QDF_STATUS 13960 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13961 struct wmi_roam_trigger_info *trig, uint8_t idx) 13962 { 13963 return QDF_STATUS_E_NOSUPPORT; 13964 } 13965 13966 static inline QDF_STATUS 13967 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13968 struct wmi_roam_result *dst, uint8_t idx) 13969 { 13970 return QDF_STATUS_E_NOSUPPORT; 13971 } 13972 13973 static QDF_STATUS 13974 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13975 struct wmi_neighbor_report_data *dst, 13976 uint8_t idx, uint8_t rpt_idx) 13977 { 13978 return QDF_STATUS_E_NOSUPPORT; 13979 } 13980 13981 static QDF_STATUS 13982 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 13983 struct wmi_roam_scan_data *dst, uint8_t idx, 13984 uint8_t chan_idx, uint8_t ap_idx) 13985 { 13986 return QDF_STATUS_E_NOSUPPORT; 13987 } 13988 #endif 13989 13990 #ifdef WLAN_FEATURE_PKT_CAPTURE 13991 static QDF_STATUS 13992 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 13993 struct mgmt_offload_event_params *params) 13994 { 13995 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 13996 wmi_mgmt_hdr *hdr; 13997 13998 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 13999 if (!param_tlvs) 14000 return QDF_STATUS_E_INVAL; 14001 14002 hdr = param_tlvs->fixed_param; 14003 if (!hdr) 14004 return QDF_STATUS_E_INVAL; 14005 14006 if (hdr->buf_len > param_tlvs->num_bufp) 14007 return QDF_STATUS_E_INVAL; 14008 14009 params->tsf_l32 = hdr->tsf_l32; 14010 params->chan_freq = hdr->chan_freq; 14011 params->rate_kbps = hdr->rate_kbps; 14012 params->rssi = hdr->rssi; 14013 params->buf_len = hdr->buf_len; 14014 params->tx_status = hdr->tx_status; 14015 params->buf = param_tlvs->bufp; 14016 params->tx_retry_cnt = hdr->tx_retry_cnt; 14017 return QDF_STATUS_SUCCESS; 14018 } 14019 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 14020 14021 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 14022 /** 14023 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 14024 * 14025 * @wmi: wmi handle 14026 * @vdev_id: vdev id 14027 * @burst_mode: Indicates whether relation derived using FTM is needed for 14028 * each FTM frame or only aggregated result is required. 14029 * 14030 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 14031 * 14032 * Return: QDF_STATUS 14033 */ 14034 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 14035 uint32_t vdev_id, 14036 bool burst_mode) 14037 { 14038 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 14039 wmi_buf_t buf; 14040 int32_t len = sizeof(*cmd); 14041 14042 buf = wmi_buf_alloc(wmi, len); 14043 if (!buf) { 14044 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 14045 return QDF_STATUS_E_NOMEM; 14046 } 14047 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 14048 WMITLV_SET_HDR(&cmd->tlv_header, 14049 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 14050 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 14051 cmd->vdev_id = vdev_id; 14052 cmd->agg_relation = burst_mode ? false : true; 14053 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 14054 WMI_LOGE("%s: failed to send audio sync trigger cmd", __func__); 14055 wmi_buf_free(buf); 14056 return QDF_STATUS_E_FAILURE; 14057 } 14058 14059 return QDF_STATUS_SUCCESS; 14060 } 14061 14062 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 14063 uint32_t vdev_id, 14064 uint64_t lpass_ts) 14065 { 14066 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 14067 wmi_buf_t buf; 14068 int32_t len = sizeof(*cmd); 14069 14070 buf = wmi_buf_alloc(wmi, len); 14071 if (!buf) { 14072 WMI_LOGP("%s: wmi_buf_alloc failed", __func__); 14073 return QDF_STATUS_E_NOMEM; 14074 } 14075 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 14076 WMITLV_SET_HDR(&cmd->tlv_header, 14077 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 14078 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 14079 cmd->vdev_id = vdev_id; 14080 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 14081 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 14082 14083 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 14084 WMI_LOGP("%s: Failed to send audio qtime command", __func__); 14085 wmi_buf_free(buf); 14086 return QDF_STATUS_E_FAILURE; 14087 } 14088 14089 return QDF_STATUS_SUCCESS; 14090 } 14091 14092 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 14093 wmi_unified_t wmi, void *buf, 14094 struct ftm_time_sync_start_stop_params *param) 14095 { 14096 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 14097 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 14098 14099 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 14100 if (!param_buf) { 14101 WMI_LOGE("Invalid audio sync start stop event buffer"); 14102 return QDF_STATUS_E_FAILURE; 14103 } 14104 14105 resp_event = param_buf->fixed_param; 14106 if (!resp_event) { 14107 WMI_LOGE("Invalid audio sync start stop fixed param buffer"); 14108 return QDF_STATUS_E_FAILURE; 14109 } 14110 14111 param->vdev_id = resp_event->vdev_id; 14112 param->timer_interval = resp_event->periodicity; 14113 param->num_reads = resp_event->reads_needed; 14114 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 14115 resp_event->qtimer_l32; 14116 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 14117 resp_event->mac_timer_l32; 14118 14119 WMI_LOGI("%s: FTM time sync time_interval %d, num_reads %d", __func__, 14120 param->timer_interval, param->num_reads); 14121 14122 return QDF_STATUS_SUCCESS; 14123 } 14124 14125 static QDF_STATUS 14126 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 14127 struct ftm_time_sync_offset *param) 14128 { 14129 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 14130 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 14131 wmi_audio_sync_q_master_slave_times *q_pair; 14132 int iter; 14133 14134 param_buf = 14135 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 14136 if (!param_buf) { 14137 WMI_LOGE("Invalid timesync ftm offset event buffer"); 14138 return QDF_STATUS_E_FAILURE; 14139 } 14140 14141 resp_event = param_buf->fixed_param; 14142 if (!resp_event) { 14143 WMI_LOGE("Invalid timesync ftm offset fixed param buffer"); 14144 return QDF_STATUS_E_FAILURE; 14145 } 14146 14147 param->vdev_id = resp_event->vdev_id; 14148 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 14149 q_pair = param_buf->audio_sync_q_master_slave_times; 14150 if (!q_pair) { 14151 WMI_LOGE("Invalid q_master_slave_times buffer"); 14152 return QDF_STATUS_E_FAILURE; 14153 } 14154 14155 for (iter = 0; iter < param->num_qtime; iter++) { 14156 param->pairs[iter].qtime_master = ( 14157 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 14158 q_pair[iter].qmaster_l32; 14159 param->pairs[iter].qtime_slave = ( 14160 (uint64_t)q_pair[iter].qslave_u32 << 32) | 14161 q_pair[iter].qslave_l32; 14162 } 14163 return QDF_STATUS_SUCCESS; 14164 } 14165 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 14166 14167 struct wmi_ops tlv_ops = { 14168 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 14169 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 14170 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 14171 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 14172 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 14173 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 14174 .send_peer_param_cmd = send_peer_param_cmd_tlv, 14175 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 14176 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 14177 .send_peer_create_cmd = send_peer_create_cmd_tlv, 14178 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 14179 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 14180 .send_peer_rx_reorder_queue_setup_cmd = 14181 send_peer_rx_reorder_queue_setup_cmd_tlv, 14182 .send_peer_rx_reorder_queue_remove_cmd = 14183 send_peer_rx_reorder_queue_remove_cmd_tlv, 14184 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 14185 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 14186 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 14187 .send_suspend_cmd = send_suspend_cmd_tlv, 14188 .send_resume_cmd = send_resume_cmd_tlv, 14189 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 14190 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 14191 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 14192 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 14193 #ifdef FEATURE_FW_LOG_PARSING 14194 .send_dbglog_cmd = send_dbglog_cmd_tlv, 14195 #endif 14196 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 14197 .send_stats_request_cmd = send_stats_request_cmd_tlv, 14198 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 14199 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 14200 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 14201 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 14202 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 14203 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 14204 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 14205 .send_scan_start_cmd = send_scan_start_cmd_tlv, 14206 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 14207 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 14208 .send_mgmt_cmd = send_mgmt_cmd_tlv, 14209 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 14210 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 14211 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 14212 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 14213 .send_set_sta_uapsd_auto_trig_cmd = 14214 send_set_sta_uapsd_auto_trig_cmd_tlv, 14215 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 14216 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 14217 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 14218 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 14219 .send_lro_config_cmd = send_lro_config_cmd_tlv, 14220 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 14221 .send_probe_rsp_tmpl_send_cmd = 14222 send_probe_rsp_tmpl_send_cmd_tlv, 14223 .send_p2p_go_set_beacon_ie_cmd = 14224 send_p2p_go_set_beacon_ie_cmd_tlv, 14225 .send_setup_install_key_cmd = 14226 send_setup_install_key_cmd_tlv, 14227 .send_scan_probe_setoui_cmd = 14228 send_scan_probe_setoui_cmd_tlv, 14229 #ifdef IPA_OFFLOAD 14230 .send_ipa_offload_control_cmd = 14231 send_ipa_offload_control_cmd_tlv, 14232 #endif 14233 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 14234 .send_pno_start_cmd = send_pno_start_cmd_tlv, 14235 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 14236 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 14237 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 14238 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 14239 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 14240 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 14241 .send_congestion_cmd = send_congestion_cmd_tlv, 14242 .send_snr_request_cmd = send_snr_request_cmd_tlv, 14243 .send_snr_cmd = send_snr_cmd_tlv, 14244 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 14245 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 14246 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 14247 #endif 14248 #ifdef WLAN_SUPPORT_GREEN_AP 14249 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 14250 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 14251 .extract_green_ap_egap_status_info = 14252 extract_green_ap_egap_status_info_tlv, 14253 #endif 14254 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 14255 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 14256 #ifdef FEATURE_OEM_DATA 14257 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 14258 #endif 14259 #ifdef WLAN_FEATURE_CIF_CFR 14260 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 14261 #endif 14262 .send_dfs_phyerr_filter_offload_en_cmd = 14263 send_dfs_phyerr_filter_offload_en_cmd_tlv, 14264 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 14265 .send_process_dhcpserver_offload_cmd = 14266 send_process_dhcpserver_offload_cmd_tlv, 14267 .send_pdev_set_regdomain_cmd = 14268 send_pdev_set_regdomain_cmd_tlv, 14269 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 14270 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 14271 .save_fw_version_cmd = save_fw_version_cmd_tlv, 14272 .check_and_update_fw_version = 14273 check_and_update_fw_version_cmd_tlv, 14274 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 14275 .send_enable_specific_fw_logs_cmd = 14276 send_enable_specific_fw_logs_cmd_tlv, 14277 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 14278 .send_unit_test_cmd = send_unit_test_cmd_tlv, 14279 #ifdef FEATURE_WLAN_APF 14280 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 14281 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 14282 .send_apf_write_work_memory_cmd = 14283 wmi_send_apf_write_work_memory_cmd_tlv, 14284 .send_apf_read_work_memory_cmd = 14285 wmi_send_apf_read_work_memory_cmd_tlv, 14286 .extract_apf_read_memory_resp_event = 14287 wmi_extract_apf_read_memory_resp_event_tlv, 14288 #endif /* FEATURE_WLAN_APF */ 14289 .init_cmd_send = init_cmd_send_tlv, 14290 .send_vdev_set_custom_aggr_size_cmd = 14291 send_vdev_set_custom_aggr_size_cmd_tlv, 14292 .send_vdev_set_qdepth_thresh_cmd = 14293 send_vdev_set_qdepth_thresh_cmd_tlv, 14294 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 14295 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 14296 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 14297 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 14298 .send_periodic_chan_stats_config_cmd = 14299 send_periodic_chan_stats_config_cmd_tlv, 14300 #ifdef WLAN_IOT_SIM_SUPPORT 14301 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 14302 #endif 14303 .send_vdev_spectral_configure_cmd = 14304 send_vdev_spectral_configure_cmd_tlv, 14305 .send_vdev_spectral_enable_cmd = 14306 send_vdev_spectral_enable_cmd_tlv, 14307 #ifdef WLAN_CONV_SPECTRAL_ENABLE 14308 .extract_pdev_sscan_fw_cmd_fixed_param = 14309 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 14310 .extract_pdev_sscan_fft_bin_index = 14311 extract_pdev_sscan_fft_bin_index_tlv, 14312 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 14313 .send_thermal_mitigation_param_cmd = 14314 send_thermal_mitigation_param_cmd_tlv, 14315 .send_process_update_edca_param_cmd = 14316 send_process_update_edca_param_cmd_tlv, 14317 .send_bss_color_change_enable_cmd = 14318 send_bss_color_change_enable_cmd_tlv, 14319 .send_coex_config_cmd = send_coex_config_cmd_tlv, 14320 .send_set_country_cmd = send_set_country_cmd_tlv, 14321 .send_addba_send_cmd = send_addba_send_cmd_tlv, 14322 .send_delba_send_cmd = send_delba_send_cmd_tlv, 14323 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 14324 .get_target_cap_from_service_ready = extract_service_ready_tlv, 14325 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 14326 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 14327 .extract_host_mem_req = extract_host_mem_req_tlv, 14328 .save_service_bitmap = save_service_bitmap_tlv, 14329 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 14330 .is_service_enabled = is_service_enabled_tlv, 14331 .save_fw_version = save_fw_version_in_service_ready_tlv, 14332 .ready_extract_init_status = ready_extract_init_status_tlv, 14333 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 14334 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 14335 .extract_ready_event_params = extract_ready_event_params_tlv, 14336 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 14337 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 14338 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 14339 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 14340 #ifdef FEATURE_WLAN_SCAN_PNO 14341 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 14342 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 14343 #endif 14344 .extract_all_stats_count = extract_all_stats_counts_tlv, 14345 .extract_pdev_stats = extract_pdev_stats_tlv, 14346 .extract_unit_test = extract_unit_test_tlv, 14347 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 14348 .extract_vdev_stats = extract_vdev_stats_tlv, 14349 .extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv, 14350 .extract_peer_stats = extract_peer_stats_tlv, 14351 .extract_bcn_stats = extract_bcn_stats_tlv, 14352 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 14353 .extract_peer_extd_stats = extract_peer_extd_stats_tlv, 14354 .extract_peer_adv_stats = extract_peer_adv_stats_tlv, 14355 .extract_chan_stats = extract_chan_stats_tlv, 14356 #ifdef WLAN_FEATURE_MIB_STATS 14357 .extract_mib_stats = extract_mib_stats_tlv, 14358 #endif 14359 .extract_profile_ctx = extract_profile_ctx_tlv, 14360 .extract_profile_data = extract_profile_data_tlv, 14361 .send_fw_test_cmd = send_fw_test_cmd_tlv, 14362 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 14363 .extract_service_ready_ext = extract_service_ready_ext_tlv, 14364 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 14365 .extract_hw_mode_cap_service_ready_ext = 14366 extract_hw_mode_cap_service_ready_ext_tlv, 14367 .extract_mac_phy_cap_service_ready_ext = 14368 extract_mac_phy_cap_service_ready_ext_tlv, 14369 .extract_mac_phy_cap_service_ready_ext2 = 14370 extract_mac_phy_cap_service_ready_ext2_tlv, 14371 .extract_reg_cap_service_ready_ext = 14372 extract_reg_cap_service_ready_ext_tlv, 14373 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 14374 .extract_dbr_ring_cap_service_ready_ext = 14375 extract_dbr_ring_cap_service_ready_ext_tlv, 14376 .extract_dbr_ring_cap_service_ready_ext2 = 14377 extract_dbr_ring_cap_service_ready_ext2_tlv, 14378 .extract_sar_cap_service_ready_ext = 14379 extract_sar_cap_service_ready_ext_tlv, 14380 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 14381 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 14382 .extract_fips_event_data = extract_fips_event_data_tlv, 14383 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 14384 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 14385 #endif 14386 #ifdef WLAN_FEATURE_DISA 14387 .extract_encrypt_decrypt_resp_event = 14388 extract_encrypt_decrypt_resp_event_tlv, 14389 #endif 14390 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 14391 .extract_get_pn_data = extract_get_pn_data_tlv, 14392 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 14393 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 14394 #ifdef WLAN_FEATURE_DISA 14395 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 14396 #endif 14397 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 14398 .send_wlan_profile_hist_intvl_cmd = 14399 send_wlan_profile_hist_intvl_cmd_tlv, 14400 .is_management_record = is_management_record_tlv, 14401 .is_diag_event = is_diag_event_tlv, 14402 #ifdef WLAN_FEATURE_ACTION_OUI 14403 .send_action_oui_cmd = send_action_oui_cmd_tlv, 14404 #endif 14405 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 14406 #ifdef QCA_SUPPORT_AGILE_DFS 14407 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 14408 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 14409 #endif 14410 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 14411 .extract_reg_chan_list_update_event = 14412 extract_reg_chan_list_update_event_tlv, 14413 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14414 .extract_num_rf_characterization_entries = 14415 extract_num_rf_characterization_entries_tlv, 14416 .extract_rf_characterization_entries = 14417 extract_rf_characterization_entries_tlv, 14418 #endif 14419 .extract_chainmask_tables = 14420 extract_chainmask_tables_tlv, 14421 .extract_thermal_stats = extract_thermal_stats_tlv, 14422 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 14423 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 14424 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 14425 #ifdef DFS_COMPONENT_ENABLE 14426 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 14427 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 14428 .extract_dfs_radar_detection_event = 14429 extract_dfs_radar_detection_event_tlv, 14430 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 14431 #endif 14432 .convert_pdev_id_host_to_target = 14433 convert_host_pdev_id_to_target_pdev_id_legacy, 14434 .convert_pdev_id_target_to_host = 14435 convert_target_pdev_id_to_host_pdev_id_legacy, 14436 14437 .convert_host_pdev_id_to_target = 14438 convert_host_pdev_id_to_target_pdev_id, 14439 .convert_target_pdev_id_to_host = 14440 convert_target_pdev_id_to_host_pdev_id, 14441 14442 .convert_phy_id_host_to_target = 14443 convert_host_phy_id_to_target_phy_id_legacy, 14444 .convert_phy_id_target_to_host = 14445 convert_target_phy_id_to_host_phy_id_legacy, 14446 14447 .convert_host_phy_id_to_target = 14448 convert_host_phy_id_to_target_phy_id, 14449 .convert_target_phy_id_to_host = 14450 convert_target_phy_id_to_host_phy_id, 14451 14452 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 14453 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 14454 .extract_reg_11d_new_country_event = 14455 extract_reg_11d_new_country_event_tlv, 14456 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 14457 .extract_reg_ch_avoid_event = 14458 extract_reg_ch_avoid_event_tlv, 14459 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 14460 .extract_obss_detection_info = extract_obss_detection_info_tlv, 14461 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 14462 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 14463 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 14464 .wmi_check_command_params = wmitlv_check_command_tlv_params, 14465 .extract_comb_phyerr = extract_comb_phyerr_tlv, 14466 .extract_single_phyerr = extract_single_phyerr_tlv, 14467 #ifdef QCA_SUPPORT_CP_STATS 14468 .extract_cca_stats = extract_cca_stats_tlv, 14469 #endif 14470 .extract_esp_estimation_ev_param = 14471 extract_esp_estimation_ev_param_tlv, 14472 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 14473 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 14474 #ifdef OBSS_PD 14475 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 14476 .send_obss_spatial_reuse_set_def_thresh = 14477 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 14478 .send_self_srg_bss_color_bitmap_set = 14479 send_self_srg_bss_color_bitmap_set_cmd_tlv, 14480 .send_self_srg_partial_bssid_bitmap_set = 14481 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 14482 .send_self_srg_obss_color_enable_bitmap = 14483 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 14484 .send_self_srg_obss_bssid_enable_bitmap = 14485 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 14486 .send_self_non_srg_obss_color_enable_bitmap = 14487 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 14488 .send_self_non_srg_obss_bssid_enable_bitmap = 14489 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 14490 #endif 14491 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 14492 .extract_ctl_failsafe_check_ev_param = 14493 extract_ctl_failsafe_check_ev_param_tlv, 14494 #ifdef WIFI_POS_CONVERGED 14495 .extract_oem_response_param = extract_oem_response_param_tlv, 14496 #endif /* WIFI_POS_CONVERGED */ 14497 #ifdef WLAN_MWS_INFO_DEBUGFS 14498 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 14499 #endif 14500 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 14501 #ifdef FEATURE_ANI_LEVEL_REQUEST 14502 .send_ani_level_cmd = send_ani_level_cmd_tlv, 14503 .extract_ani_level = extract_ani_level_tlv, 14504 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 14505 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 14506 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 14507 .extract_roam_result_stats = extract_roam_result_stats_tlv, 14508 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 14509 #ifdef WLAN_FEATURE_PKT_CAPTURE 14510 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 14511 #endif 14512 14513 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 14514 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 14515 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 14516 .extract_time_sync_ftm_start_stop_event = 14517 extract_time_sync_ftm_start_stop_event_tlv, 14518 .extract_time_sync_ftm_offset_event = 14519 extract_time_sync_ftm_offset_event_tlv, 14520 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 14521 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 14522 .send_injector_config_cmd = send_injector_config_cmd_tlv, 14523 }; 14524 14525 /** 14526 * populate_tlv_event_id() - populates wmi event ids 14527 * 14528 * @param event_ids: Pointer to hold event ids 14529 * Return: None 14530 */ 14531 static void populate_tlv_events_id(uint32_t *event_ids) 14532 { 14533 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 14534 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 14535 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 14536 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 14537 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 14538 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 14539 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 14540 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 14541 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 14542 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 14543 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 14544 event_ids[wmi_service_ready_ext_event_id] = 14545 WMI_SERVICE_READY_EXT_EVENTID; 14546 event_ids[wmi_service_ready_ext2_event_id] = 14547 WMI_SERVICE_READY_EXT2_EVENTID; 14548 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 14549 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 14550 event_ids[wmi_vdev_install_key_complete_event_id] = 14551 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 14552 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 14553 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 14554 14555 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 14556 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 14557 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 14558 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 14559 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 14560 event_ids[wmi_peer_estimated_linkspeed_event_id] = 14561 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 14562 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 14563 event_ids[wmi_peer_delete_response_event_id] = 14564 WMI_PEER_DELETE_RESP_EVENTID; 14565 event_ids[wmi_peer_delete_all_response_event_id] = 14566 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 14567 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 14568 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 14569 event_ids[wmi_tbttoffset_update_event_id] = 14570 WMI_TBTTOFFSET_UPDATE_EVENTID; 14571 event_ids[wmi_ext_tbttoffset_update_event_id] = 14572 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 14573 event_ids[wmi_offload_bcn_tx_status_event_id] = 14574 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 14575 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 14576 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 14577 event_ids[wmi_mgmt_tx_completion_event_id] = 14578 WMI_MGMT_TX_COMPLETION_EVENTID; 14579 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 14580 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 14581 event_ids[wmi_tx_delba_complete_event_id] = 14582 WMI_TX_DELBA_COMPLETE_EVENTID; 14583 event_ids[wmi_tx_addba_complete_event_id] = 14584 WMI_TX_ADDBA_COMPLETE_EVENTID; 14585 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 14586 14587 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 14588 14589 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 14590 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 14591 14592 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 14593 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 14594 14595 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 14596 14597 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 14598 event_ids[wmi_p2p_lo_stop_event_id] = 14599 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 14600 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 14601 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 14602 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 14603 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 14604 event_ids[wmi_d0_wow_disable_ack_event_id] = 14605 WMI_D0_WOW_DISABLE_ACK_EVENTID; 14606 event_ids[wmi_wow_initial_wakeup_event_id] = 14607 WMI_WOW_INITIAL_WAKEUP_EVENTID; 14608 14609 event_ids[wmi_rtt_meas_report_event_id] = 14610 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 14611 event_ids[wmi_tsf_meas_report_event_id] = 14612 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 14613 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 14614 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 14615 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 14616 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 14617 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 14618 event_ids[wmi_diag_event_id_log_supported_event_id] = 14619 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 14620 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 14621 event_ids[wmi_nlo_scan_complete_event_id] = 14622 WMI_NLO_SCAN_COMPLETE_EVENTID; 14623 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 14624 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 14625 14626 event_ids[wmi_gtk_offload_status_event_id] = 14627 WMI_GTK_OFFLOAD_STATUS_EVENTID; 14628 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 14629 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 14630 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 14631 14632 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 14633 14634 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 14635 14636 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 14637 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 14638 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 14639 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 14640 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 14641 event_ids[wmi_wlan_profile_data_event_id] = 14642 WMI_WLAN_PROFILE_DATA_EVENTID; 14643 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 14644 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 14645 event_ids[wmi_vdev_get_keepalive_event_id] = 14646 WMI_VDEV_GET_KEEPALIVE_EVENTID; 14647 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 14648 14649 event_ids[wmi_diag_container_event_id] = 14650 WMI_DIAG_DATA_CONTAINER_EVENTID; 14651 14652 event_ids[wmi_host_auto_shutdown_event_id] = 14653 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 14654 14655 event_ids[wmi_update_whal_mib_stats_event_id] = 14656 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 14657 14658 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 14659 event_ids[wmi_update_vdev_rate_stats_event_id] = 14660 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 14661 14662 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 14663 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 14664 14665 /** Set OCB Sched Response, deprecated */ 14666 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 14667 14668 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 14669 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 14670 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 14671 14672 /* GPIO Event */ 14673 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 14674 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 14675 14676 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 14677 event_ids[wmi_rfkill_state_change_event_id] = 14678 WMI_RFKILL_STATE_CHANGE_EVENTID; 14679 14680 /* TDLS Event */ 14681 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 14682 14683 event_ids[wmi_batch_scan_enabled_event_id] = 14684 WMI_BATCH_SCAN_ENABLED_EVENTID; 14685 event_ids[wmi_batch_scan_result_event_id] = 14686 WMI_BATCH_SCAN_RESULT_EVENTID; 14687 /* OEM Event */ 14688 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 14689 event_ids[wmi_oem_meas_report_event_id] = 14690 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 14691 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 14692 14693 /* NAN Event */ 14694 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 14695 14696 /* LPI Event */ 14697 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 14698 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 14699 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 14700 14701 /* ExtScan events */ 14702 event_ids[wmi_extscan_start_stop_event_id] = 14703 WMI_EXTSCAN_START_STOP_EVENTID; 14704 event_ids[wmi_extscan_operation_event_id] = 14705 WMI_EXTSCAN_OPERATION_EVENTID; 14706 event_ids[wmi_extscan_table_usage_event_id] = 14707 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 14708 event_ids[wmi_extscan_cached_results_event_id] = 14709 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 14710 event_ids[wmi_extscan_wlan_change_results_event_id] = 14711 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 14712 event_ids[wmi_extscan_hotlist_match_event_id] = 14713 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 14714 event_ids[wmi_extscan_capabilities_event_id] = 14715 WMI_EXTSCAN_CAPABILITIES_EVENTID; 14716 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 14717 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 14718 14719 /* mDNS offload events */ 14720 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 14721 14722 /* SAP Authentication offload events */ 14723 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 14724 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 14725 14726 /** Out-of-context-of-bss (OCB) events */ 14727 event_ids[wmi_ocb_set_config_resp_event_id] = 14728 WMI_OCB_SET_CONFIG_RESP_EVENTID; 14729 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 14730 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 14731 event_ids[wmi_dcc_get_stats_resp_event_id] = 14732 WMI_DCC_GET_STATS_RESP_EVENTID; 14733 event_ids[wmi_dcc_update_ndl_resp_event_id] = 14734 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 14735 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 14736 /* System-On-Chip events */ 14737 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 14738 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 14739 event_ids[wmi_soc_hw_mode_transition_event_id] = 14740 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 14741 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 14742 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 14743 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 14744 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 14745 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 14746 event_ids[wmi_vdev_ocac_complete_event_id] = 14747 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 14748 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 14749 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 14750 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 14751 event_ids[wmi_peer_sta_ps_statechg_event_id] = 14752 WMI_PEER_STA_PS_STATECHG_EVENTID; 14753 event_ids[wmi_pdev_channel_hopping_event_id] = 14754 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 14755 event_ids[wmi_offchan_data_tx_completion_event] = 14756 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 14757 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 14758 event_ids[wmi_dfs_radar_detection_event_id] = 14759 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 14760 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 14761 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 14762 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 14763 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 14764 event_ids[wmi_service_available_event_id] = 14765 WMI_SERVICE_AVAILABLE_EVENTID; 14766 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 14767 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 14768 /* NDP events */ 14769 event_ids[wmi_ndp_initiator_rsp_event_id] = 14770 WMI_NDP_INITIATOR_RSP_EVENTID; 14771 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 14772 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 14773 event_ids[wmi_ndp_responder_rsp_event_id] = 14774 WMI_NDP_RESPONDER_RSP_EVENTID; 14775 event_ids[wmi_ndp_end_indication_event_id] = 14776 WMI_NDP_END_INDICATION_EVENTID; 14777 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 14778 event_ids[wmi_ndl_schedule_update_event_id] = 14779 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 14780 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 14781 14782 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 14783 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 14784 event_ids[wmi_pdev_chip_power_stats_event_id] = 14785 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 14786 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 14787 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 14788 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 14789 event_ids[wmi_apf_capability_info_event_id] = 14790 WMI_BPF_CAPABILIY_INFO_EVENTID; 14791 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 14792 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 14793 event_ids[wmi_report_rx_aggr_failure_event_id] = 14794 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 14795 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 14796 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 14797 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 14798 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 14799 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 14800 event_ids[wmi_pdev_hw_mode_transition_event_id] = 14801 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 14802 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 14803 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 14804 event_ids[wmi_coex_bt_activity_event_id] = 14805 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 14806 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 14807 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 14808 event_ids[wmi_radio_tx_power_level_stats_event_id] = 14809 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 14810 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 14811 event_ids[wmi_dma_buf_release_event_id] = 14812 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 14813 event_ids[wmi_sap_obss_detection_report_event_id] = 14814 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 14815 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 14816 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 14817 event_ids[wmi_obss_color_collision_report_event_id] = 14818 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 14819 event_ids[wmi_pdev_div_rssi_antid_event_id] = 14820 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 14821 event_ids[wmi_twt_enable_complete_event_id] = 14822 WMI_TWT_ENABLE_COMPLETE_EVENTID; 14823 event_ids[wmi_twt_disable_complete_event_id] = 14824 WMI_TWT_DISABLE_COMPLETE_EVENTID; 14825 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 14826 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 14827 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 14828 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 14829 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 14830 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 14831 event_ids[wmi_pdev_interop_issues_ap_event_id] = 14832 WMI_PDEV_RAP_INFO_EVENTID; 14833 #endif 14834 #ifdef AST_HKV1_WORKAROUND 14835 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 14836 #endif 14837 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 14838 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 14839 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 14840 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 14841 event_ids[wmi_roam_blacklist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 14842 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 14843 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 14844 event_ids[wmi_pdev_cold_boot_cal_event_id] = 14845 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 14846 #ifdef WLAN_MWS_INFO_DEBUGFS 14847 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 14848 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 14849 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 14850 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 14851 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 14852 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 14853 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 14854 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 14855 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 14856 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 14857 #endif 14858 event_ids[wmi_coex_report_antenna_isolation_event_id] = 14859 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 14860 event_ids[wmi_peer_ratecode_list_event_id] = 14861 WMI_PEER_RATECODE_LIST_EVENTID; 14862 event_ids[wmi_chan_rf_characterization_info_event_id] = 14863 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 14864 event_ids[wmi_roam_auth_offload_event_id] = 14865 WMI_ROAM_PREAUTH_START_EVENTID; 14866 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 14867 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 14868 event_ids[wmi_motion_det_base_line_host_eventid] = 14869 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 14870 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 14871 event_ids[wmi_peer_tx_pn_response_event_id] = 14872 WMI_PEER_TX_PN_RESPONSE_EVENTID; 14873 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 14874 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 14875 event_ids[wmi_mgmt_offload_data_event_id] = 14876 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 14877 event_ids[wmi_nan_dmesg_event_id] = 14878 WMI_NAN_DMESG_EVENTID; 14879 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 14880 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 14881 event_ids[wmi_roam_pmkid_request_event_id] = 14882 WMI_ROAM_PMKID_REQUEST_EVENTID; 14883 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 14884 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 14885 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 14886 event_ids[wmi_wlan_time_sync_q_master_slave_offset_eventid] = 14887 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 14888 #endif 14889 event_ids[wmi_roam_scan_chan_list_id] = 14890 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 14891 event_ids[wmi_muedca_params_config_eventid] = 14892 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 14893 event_ids[wmi_pdev_sscan_fw_param_eventid] = 14894 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 14895 event_ids[wmi_roam_cap_report_event_id] = 14896 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 14897 } 14898 14899 /** 14900 * populate_tlv_service() - populates wmi services 14901 * 14902 * @param wmi_service: Pointer to hold wmi_service 14903 * Return: None 14904 */ 14905 static void populate_tlv_service(uint32_t *wmi_service) 14906 { 14907 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 14908 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 14909 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 14910 wmi_service[wmi_service_roam_scan_offload] = 14911 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 14912 wmi_service[wmi_service_bcn_miss_offload] = 14913 WMI_SERVICE_BCN_MISS_OFFLOAD; 14914 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 14915 wmi_service[wmi_service_sta_advanced_pwrsave] = 14916 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 14917 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 14918 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 14919 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 14920 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 14921 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 14922 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 14923 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 14924 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 14925 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 14926 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 14927 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 14928 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 14929 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 14930 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 14931 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 14932 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 14933 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 14934 wmi_service[wmi_service_packet_power_save] = 14935 WMI_SERVICE_PACKET_POWER_SAVE; 14936 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 14937 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 14938 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 14939 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 14940 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 14941 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 14942 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 14943 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 14944 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 14945 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 14946 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 14947 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 14948 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 14949 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 14950 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 14951 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 14952 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 14953 wmi_service[wmi_service_mcc_bcn_interval_change] = 14954 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 14955 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 14956 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 14957 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 14958 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 14959 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 14960 wmi_service[wmi_service_lte_ant_share_support] = 14961 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 14962 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 14963 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 14964 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 14965 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 14966 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 14967 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 14968 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 14969 wmi_service[wmi_service_bcn_txrate_override] = 14970 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 14971 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 14972 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 14973 wmi_service[wmi_service_estimate_linkspeed] = 14974 WMI_SERVICE_ESTIMATE_LINKSPEED; 14975 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 14976 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 14977 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 14978 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 14979 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 14980 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 14981 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 14982 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 14983 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 14984 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 14985 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 14986 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 14987 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 14988 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 14989 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 14990 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 14991 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 14992 wmi_service[wmi_service_sap_auth_offload] = 14993 WMI_SERVICE_SAP_AUTH_OFFLOAD; 14994 wmi_service[wmi_service_dual_band_simultaneous_support] = 14995 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 14996 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 14997 wmi_service[wmi_service_ap_arpns_offload] = 14998 WMI_SERVICE_AP_ARPNS_OFFLOAD; 14999 wmi_service[wmi_service_per_band_chainmask_support] = 15000 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 15001 wmi_service[wmi_service_packet_filter_offload] = 15002 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 15003 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 15004 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 15005 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 15006 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 15007 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 15008 wmi_service[wmi_service_multiple_vdev_restart] = 15009 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 15010 wmi_service[wmi_service_smart_antenna_sw_support] = 15011 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 15012 wmi_service[wmi_service_smart_antenna_hw_support] = 15013 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 15014 15015 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 15016 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 15017 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 15018 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 15019 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 15020 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 15021 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 15022 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 15023 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 15024 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 15025 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 15026 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 15027 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 15028 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 15029 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 15030 wmi_service[wmi_service_periodic_chan_stat_support] = 15031 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 15032 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 15033 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 15034 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 15035 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 15036 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 15037 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 15038 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 15039 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 15040 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 15041 wmi_service[wmi_service_unified_wow_capability] = 15042 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 15043 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 15044 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 15045 wmi_service[wmi_service_sync_delete_cmds] = 15046 WMI_SERVICE_SYNC_DELETE_CMDS; 15047 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 15048 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 15049 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 15050 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 15051 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 15052 wmi_service[wmi_service_deprecated_replace] = 15053 WMI_SERVICE_DEPRECATED_REPLACE; 15054 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 15055 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 15056 wmi_service[wmi_service_enhanced_mcast_filter] = 15057 WMI_SERVICE_ENHANCED_MCAST_FILTER; 15058 wmi_service[wmi_service_half_rate_quarter_rate_support] = 15059 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 15060 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 15061 wmi_service[wmi_service_p2p_listen_offload_support] = 15062 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 15063 wmi_service[wmi_service_mark_first_wakeup_packet] = 15064 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 15065 wmi_service[wmi_service_multiple_mcast_filter_set] = 15066 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 15067 wmi_service[wmi_service_host_managed_rx_reorder] = 15068 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 15069 wmi_service[wmi_service_flash_rdwr_support] = 15070 WMI_SERVICE_FLASH_RDWR_SUPPORT; 15071 wmi_service[wmi_service_wlan_stats_report] = 15072 WMI_SERVICE_WLAN_STATS_REPORT; 15073 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 15074 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 15075 wmi_service[wmi_service_dfs_phyerr_offload] = 15076 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 15077 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 15078 wmi_service[wmi_service_fw_mem_dump_support] = 15079 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 15080 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 15081 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 15082 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 15083 wmi_service[wmi_service_hw_data_filtering] = 15084 WMI_SERVICE_HW_DATA_FILTERING; 15085 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 15086 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 15087 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 15088 wmi_service[wmi_service_extended_nss_support] = 15089 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 15090 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 15091 wmi_service[wmi_service_bcn_offload_start_stop_support] = 15092 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 15093 wmi_service[wmi_service_offchan_data_tid_support] = 15094 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 15095 wmi_service[wmi_service_support_dma] = 15096 WMI_SERVICE_SUPPORT_DIRECT_DMA; 15097 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 15098 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 15099 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 15100 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 15101 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 15102 wmi_service[wmi_service_11k_neighbour_report_support] = 15103 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 15104 wmi_service[wmi_service_ap_obss_detection_offload] = 15105 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 15106 wmi_service[wmi_service_bss_color_offload] = 15107 WMI_SERVICE_BSS_COLOR_OFFLOAD; 15108 wmi_service[wmi_service_gmac_offload_support] = 15109 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 15110 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 15111 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 15112 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 15113 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 15114 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 15115 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 15116 wmi_service[wmi_service_listen_interval_offload_support] = 15117 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 15118 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 15119 wmi_service[wmi_service_obss_spatial_reuse] = 15120 WMI_SERVICE_OBSS_SPATIAL_REUSE; 15121 wmi_service[wmi_service_per_vdev_chain_support] = 15122 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 15123 wmi_service[wmi_service_new_htt_msg_format] = 15124 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 15125 wmi_service[wmi_service_peer_unmap_cnf_support] = 15126 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 15127 wmi_service[wmi_service_beacon_reception_stats] = 15128 WMI_SERVICE_BEACON_RECEPTION_STATS; 15129 wmi_service[wmi_service_vdev_latency_config] = 15130 WMI_SERVICE_VDEV_LATENCY_CONFIG; 15131 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 15132 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 15133 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 15134 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 15135 wmi_service[wmi_service_nan_disable_support] = 15136 WMI_SERVICE_NAN_DISABLE_SUPPORT; 15137 wmi_service[wmi_service_sta_plus_sta_support] = 15138 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 15139 wmi_service[wmi_service_hw_db2dbm_support] = 15140 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 15141 wmi_service[wmi_service_wlm_stats_support] = 15142 WMI_SERVICE_WLM_STATS_REQUEST; 15143 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 15144 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 15145 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 15146 wmi_service[wmi_service_cfr_capture_support] = 15147 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 15148 wmi_service[wmi_service_bcast_twt_support] = 15149 WMI_SERVICE_BROADCAST_TWT; 15150 wmi_service[wmi_service_wpa3_ft_sae_support] = 15151 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 15152 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 15153 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 15154 wmi_service[wmi_service_ft_fils] = 15155 WMI_SERVICE_WPA3_FT_FILS; 15156 wmi_service[wmi_service_adaptive_11r_support] = 15157 WMI_SERVICE_ADAPTIVE_11R_ROAM; 15158 wmi_service[wmi_service_tx_compl_tsf64] = 15159 WMI_SERVICE_TX_COMPL_TSF64; 15160 wmi_service[wmi_service_data_stall_recovery_support] = 15161 WMI_SERVICE_DSM_ROAM_FILTER; 15162 wmi_service[wmi_service_vdev_delete_all_peer] = 15163 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 15164 wmi_service[wmi_service_three_way_coex_config_legacy] = 15165 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 15166 wmi_service[wmi_service_rx_fse_support] = 15167 WMI_SERVICE_RX_FSE_SUPPORT; 15168 wmi_service[wmi_service_sae_roam_support] = 15169 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 15170 wmi_service[wmi_service_owe_roam_support] = 15171 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 15172 wmi_service[wmi_service_6ghz_support] = 15173 WMI_SERVICE_6GHZ_SUPPORT; 15174 wmi_service[wmi_service_bw_165mhz_support] = 15175 WMI_SERVICE_BW_165MHZ_SUPPORT; 15176 wmi_service[wmi_service_bw_restricted_80p80_support] = 15177 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 15178 wmi_service[wmi_service_packet_capture_support] = 15179 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 15180 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 15181 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 15182 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 15183 wmi_service[wmi_service_multiple_vdev_restart_ext] = 15184 WMI_SERVICE_UNAVAILABLE; 15185 wmi_service[wmi_service_time_sync_ftm] = 15186 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 15187 wmi_service[wmi_service_nss_ratio_to_host_support] = 15188 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 15189 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 15190 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 15191 wmi_service[wmi_beacon_protection_support] = 15192 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 15193 wmi_service[wmi_service_sta_nan_ndi_four_port] = 15194 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 15195 wmi_service[wmi_service_host_scan_stop_vdev_all] = 15196 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 15197 wmi_service[wmi_support_extend_address] = 15198 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 15199 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 15200 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 15201 wmi_service[wmi_service_suiteb_roam_support] = 15202 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 15203 wmi_service[wmi_service_no_interband_mcc_support] = 15204 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 15205 wmi_service[wmi_service_dual_sta_roam_support] = 15206 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 15207 wmi_service[wmi_service_peer_create_conf] = 15208 WMI_SERVICE_PEER_CREATE_CONF; 15209 15210 } 15211 15212 /** 15213 * wmi_ocb_ut_attach() - Attach OCB test framework 15214 * @wmi_handle: wmi handle 15215 * 15216 * Return: None 15217 */ 15218 #ifdef WLAN_OCB_UT 15219 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 15220 #else 15221 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 15222 { 15223 return; 15224 } 15225 #endif 15226 15227 /** 15228 * wmi_tlv_attach() - Attach TLV APIs 15229 * 15230 * Return: None 15231 */ 15232 void wmi_tlv_attach(wmi_unified_t wmi_handle) 15233 { 15234 wmi_handle->ops = &tlv_ops; 15235 wmi_ocb_ut_attach(wmi_handle); 15236 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 15237 #ifdef WMI_INTERFACE_EVENT_LOGGING 15238 /* Skip saving WMI_CMD_HDR and TLV HDR */ 15239 wmi_handle->soc->buf_offset_command = 8; 15240 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 15241 wmi_handle->soc->buf_offset_event = 4; 15242 #endif 15243 populate_tlv_events_id(wmi_handle->wmi_events); 15244 populate_tlv_service(wmi_handle->services); 15245 wmi_twt_attach_tlv(wmi_handle); 15246 wmi_extscan_attach_tlv(wmi_handle); 15247 wmi_smart_ant_attach_tlv(wmi_handle); 15248 wmi_dbr_attach_tlv(wmi_handle); 15249 wmi_atf_attach_tlv(wmi_handle); 15250 wmi_ap_attach_tlv(wmi_handle); 15251 wmi_bcn_attach_tlv(wmi_handle); 15252 wmi_ocb_attach_tlv(wmi_handle); 15253 wmi_nan_attach_tlv(wmi_handle); 15254 wmi_p2p_attach_tlv(wmi_handle); 15255 wmi_interop_issues_ap_attach_tlv(wmi_handle); 15256 wmi_dcs_attach_tlv(wmi_handle); 15257 wmi_roam_attach_tlv(wmi_handle); 15258 wmi_concurrency_attach_tlv(wmi_handle); 15259 wmi_pmo_attach_tlv(wmi_handle); 15260 wmi_sta_attach_tlv(wmi_handle); 15261 wmi_11ax_bss_color_attach_tlv(wmi_handle); 15262 wmi_fwol_attach_tlv(wmi_handle); 15263 wmi_vdev_attach_tlv(wmi_handle); 15264 wmi_cfr_attach_tlv(wmi_handle); 15265 } 15266 qdf_export_symbol(wmi_tlv_attach); 15267 15268 /** 15269 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 15270 * 15271 * Return: None 15272 */ 15273 void wmi_tlv_init(void) 15274 { 15275 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 15276 } 15277