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