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