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