1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "wmi_unified_api.h" 21 #include "wmi.h" 22 #include "wmi_version.h" 23 #include "wmi_unified_priv.h" 24 #include "wmi_version_allowlist.h" 25 #include "wifi_pos_public_struct.h" 26 #include <qdf_module.h> 27 #include <wlan_defs.h> 28 #include <wlan_cmn.h> 29 #include <htc_services.h> 30 #ifdef FEATURE_WLAN_APF 31 #include "wmi_unified_apf_tlv.h" 32 #endif 33 #ifdef WLAN_FEATURE_ACTION_OUI 34 #include "wmi_unified_action_oui_tlv.h" 35 #endif 36 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD 37 #include "wlan_pmo_hw_filter_public_struct.h" 38 #endif 39 #include <wlan_utility.h> 40 #ifdef WLAN_SUPPORT_GREEN_AP 41 #include "wlan_green_ap_api.h" 42 #endif 43 44 #include "wmi_unified_twt_api.h" 45 #include "wmi_unified_wds_api.h" 46 47 #ifdef WLAN_POLICY_MGR_ENABLE 48 #include "wlan_policy_mgr_public_struct.h" 49 #endif 50 51 #ifdef WMI_SMART_ANT_SUPPORT 52 #include "wmi_unified_smart_ant_api.h" 53 #endif 54 55 #ifdef WMI_DBR_SUPPORT 56 #include "wmi_unified_dbr_api.h" 57 #endif 58 59 #ifdef WMI_ATF_SUPPORT 60 #include "wmi_unified_atf_api.h" 61 #endif 62 63 #ifdef WMI_AP_SUPPORT 64 #include "wmi_unified_ap_api.h" 65 #endif 66 67 #include <wmi_unified_vdev_api.h> 68 #include <wmi_unified_vdev_tlv.h> 69 #include <wmi_unified_11be_tlv.h> 70 71 #ifdef FEATURE_SET 72 #include "wlan_mlme_public_struct.h" 73 #endif 74 75 /* 76 * If FW supports WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 77 * then channel_list may fill the upper 12 bits with channel flags, 78 * while using only the lower 20 bits for channel frequency. 79 * If FW doesn't support WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL, 80 * then channel_list only holds the frequency value. 81 */ 82 #define CHAN_LIST_FLAG_MASK_POS 20 83 #define TARGET_SET_FREQ_IN_CHAN_LIST_TLV(buf, freq) \ 84 ((buf) |= ((freq) & WMI_SCAN_CHANNEL_FREQ_MASK)) 85 #define TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(buf, flags) \ 86 ((buf) |= ((flags) << CHAN_LIST_FLAG_MASK_POS)) 87 88 /* HTC service ids for WMI for multi-radio */ 89 static const uint32_t multi_svc_ids[] = {WMI_CONTROL_SVC, 90 WMI_CONTROL_SVC_WMAC1, 91 WMI_CONTROL_SVC_WMAC2}; 92 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 93 uint32_t service_id); 94 95 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 96 /*Populate peer_param array whose index as host id and 97 *value as target id 98 */ 99 static const uint32_t peer_param_tlv[] = { 100 [WMI_HOST_PEER_MIMO_PS_STATE] = WMI_PEER_MIMO_PS_STATE, 101 [WMI_HOST_PEER_AMPDU] = WMI_PEER_AMPDU, 102 [WMI_HOST_PEER_AUTHORIZE] = WMI_PEER_AUTHORIZE, 103 [WMI_HOST_PEER_CHWIDTH] = WMI_PEER_CHWIDTH, 104 [WMI_HOST_PEER_NSS] = WMI_PEER_NSS, 105 [WMI_HOST_PEER_USE_4ADDR] = WMI_PEER_USE_4ADDR, 106 [WMI_HOST_PEER_MEMBERSHIP] = WMI_PEER_MEMBERSHIP, 107 [WMI_HOST_PEER_USERPOS] = WMI_PEER_USERPOS, 108 [WMI_HOST_PEER_CRIT_PROTO_HINT_ENABLED] = 109 WMI_PEER_CRIT_PROTO_HINT_ENABLED, 110 [WMI_HOST_PEER_TX_FAIL_CNT_THR] = WMI_PEER_TX_FAIL_CNT_THR, 111 [WMI_HOST_PEER_SET_HW_RETRY_CTS2S] = WMI_PEER_SET_HW_RETRY_CTS2S, 112 [WMI_HOST_PEER_IBSS_ATIM_WINDOW_LENGTH] = 113 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, 114 [WMI_HOST_PEER_PHYMODE] = WMI_PEER_PHYMODE, 115 [WMI_HOST_PEER_USE_FIXED_PWR] = WMI_PEER_USE_FIXED_PWR, 116 [WMI_HOST_PEER_PARAM_FIXED_RATE] = WMI_PEER_PARAM_FIXED_RATE, 117 [WMI_HOST_PEER_SET_MU_ALLOWLIST] = WMI_PEER_SET_MU_ALLOWLIST, 118 [WMI_HOST_PEER_SET_MAX_TX_RATE] = WMI_PEER_SET_MAX_TX_RATE, 119 [WMI_HOST_PEER_SET_MIN_TX_RATE] = WMI_PEER_SET_MIN_TX_RATE, 120 [WMI_HOST_PEER_SET_DEFAULT_ROUTING] = WMI_PEER_SET_DEFAULT_ROUTING, 121 [WMI_HOST_PEER_NSS_VHT160] = WMI_PEER_NSS_VHT160, 122 [WMI_HOST_PEER_NSS_VHT80_80] = WMI_PEER_NSS_VHT80_80, 123 [WMI_HOST_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL] = 124 WMI_PEER_PARAM_SU_TXBF_SOUNDING_INTERVAL, 125 [WMI_HOST_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL] = 126 WMI_PEER_PARAM_MU_TXBF_SOUNDING_INTERVAL, 127 [WMI_HOST_PEER_PARAM_TXBF_SOUNDING_ENABLE] = 128 WMI_PEER_PARAM_TXBF_SOUNDING_ENABLE, 129 [WMI_HOST_PEER_PARAM_MU_ENABLE] = WMI_PEER_PARAM_MU_ENABLE, 130 [WMI_HOST_PEER_PARAM_OFDMA_ENABLE] = WMI_PEER_PARAM_OFDMA_ENABLE, 131 [WMI_HOST_PEER_PARAM_ENABLE_FT] = WMI_PEER_PARAM_ENABLE_FT, 132 [WMI_HOST_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP] = 133 WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP, 134 [WMI_HOST_PEER_FT_ROAMING_PEER_UPDATE] = 135 WMI_PEER_FT_ROAMING_PEER_UPDATE, 136 [WMI_HOST_PEER_PARAM_DMS_SUPPORT] = WMI_PEER_PARAM_DMS_SUPPORT, 137 [WMI_HOST_PEER_PARAM_UL_OFDMA_RTD] = WMI_PEER_PARAM_UL_OFDMA_RTD, 138 }; 139 140 #define PARAM_MAP(name, NAME) [wmi_ ## name] = WMI_ ##NAME 141 142 /* Populate pdev_param whose index is host param and value is target */ 143 static const uint32_t pdev_param_tlv[] = { 144 PARAM_MAP(pdev_param_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 145 PARAM_MAP(pdev_param_rx_chain_mask, PDEV_PARAM_RX_CHAIN_MASK), 146 PARAM_MAP(pdev_param_txpower_limit2g, PDEV_PARAM_TXPOWER_LIMIT2G), 147 PARAM_MAP(pdev_param_txpower_limit5g, PDEV_PARAM_TXPOWER_LIMIT5G), 148 PARAM_MAP(pdev_param_txpower_scale, PDEV_PARAM_TXPOWER_SCALE), 149 PARAM_MAP(pdev_param_beacon_gen_mode, PDEV_PARAM_BEACON_GEN_MODE), 150 PARAM_MAP(pdev_param_beacon_tx_mode, PDEV_PARAM_BEACON_TX_MODE), 151 PARAM_MAP(pdev_param_resmgr_offchan_mode, 152 PDEV_PARAM_RESMGR_OFFCHAN_MODE), 153 PARAM_MAP(pdev_param_protection_mode, PDEV_PARAM_PROTECTION_MODE), 154 PARAM_MAP(pdev_param_dynamic_bw, PDEV_PARAM_DYNAMIC_BW), 155 PARAM_MAP(pdev_param_non_agg_sw_retry_th, 156 PDEV_PARAM_NON_AGG_SW_RETRY_TH), 157 PARAM_MAP(pdev_param_agg_sw_retry_th, PDEV_PARAM_AGG_SW_RETRY_TH), 158 PARAM_MAP(pdev_param_sta_kickout_th, PDEV_PARAM_STA_KICKOUT_TH), 159 PARAM_MAP(pdev_param_ac_aggrsize_scaling, 160 PDEV_PARAM_AC_AGGRSIZE_SCALING), 161 PARAM_MAP(pdev_param_ltr_enable, PDEV_PARAM_LTR_ENABLE), 162 PARAM_MAP(pdev_param_ltr_ac_latency_be, 163 PDEV_PARAM_LTR_AC_LATENCY_BE), 164 PARAM_MAP(pdev_param_ltr_ac_latency_bk, PDEV_PARAM_LTR_AC_LATENCY_BK), 165 PARAM_MAP(pdev_param_ltr_ac_latency_vi, PDEV_PARAM_LTR_AC_LATENCY_VI), 166 PARAM_MAP(pdev_param_ltr_ac_latency_vo, PDEV_PARAM_LTR_AC_LATENCY_VO), 167 PARAM_MAP(pdev_param_ltr_ac_latency_timeout, 168 PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT), 169 PARAM_MAP(pdev_param_ltr_sleep_override, PDEV_PARAM_LTR_SLEEP_OVERRIDE), 170 PARAM_MAP(pdev_param_ltr_rx_override, PDEV_PARAM_LTR_RX_OVERRIDE), 171 PARAM_MAP(pdev_param_ltr_tx_activity_timeout, 172 PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT), 173 PARAM_MAP(pdev_param_l1ss_enable, PDEV_PARAM_L1SS_ENABLE), 174 PARAM_MAP(pdev_param_dsleep_enable, PDEV_PARAM_DSLEEP_ENABLE), 175 PARAM_MAP(pdev_param_pcielp_txbuf_flush, PDEV_PARAM_PCIELP_TXBUF_FLUSH), 176 PARAM_MAP(pdev_param_pcielp_txbuf_watermark, 177 PDEV_PARAM_PCIELP_TXBUF_WATERMARK), 178 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_en, 179 PDEV_PARAM_PCIELP_TXBUF_TMO_EN), 180 PARAM_MAP(pdev_param_pcielp_txbuf_tmo_value, 181 PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE), 182 PARAM_MAP(pdev_param_pdev_stats_update_period, 183 PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD), 184 PARAM_MAP(pdev_param_vdev_stats_update_period, 185 PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD), 186 PARAM_MAP(pdev_param_peer_stats_update_period, 187 PDEV_PARAM_PEER_STATS_UPDATE_PERIOD), 188 PARAM_MAP(pdev_param_bcnflt_stats_update_period, 189 PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD), 190 PARAM_MAP(pdev_param_pmf_qos, PDEV_PARAM_PMF_QOS), 191 PARAM_MAP(pdev_param_arp_ac_override, PDEV_PARAM_ARP_AC_OVERRIDE), 192 PARAM_MAP(pdev_param_dcs, PDEV_PARAM_DCS), 193 PARAM_MAP(pdev_param_ani_enable, PDEV_PARAM_ANI_ENABLE), 194 PARAM_MAP(pdev_param_ani_poll_period, PDEV_PARAM_ANI_POLL_PERIOD), 195 PARAM_MAP(pdev_param_ani_listen_period, PDEV_PARAM_ANI_LISTEN_PERIOD), 196 PARAM_MAP(pdev_param_ani_ofdm_level, PDEV_PARAM_ANI_OFDM_LEVEL), 197 PARAM_MAP(pdev_param_ani_cck_level, PDEV_PARAM_ANI_CCK_LEVEL), 198 PARAM_MAP(pdev_param_dyntxchain, PDEV_PARAM_DYNTXCHAIN), 199 PARAM_MAP(pdev_param_proxy_sta, PDEV_PARAM_PROXY_STA), 200 PARAM_MAP(pdev_param_idle_ps_config, PDEV_PARAM_IDLE_PS_CONFIG), 201 PARAM_MAP(pdev_param_power_gating_sleep, PDEV_PARAM_POWER_GATING_SLEEP), 202 PARAM_MAP(pdev_param_rfkill_enable, PDEV_PARAM_RFKILL_ENABLE), 203 PARAM_MAP(pdev_param_burst_dur, PDEV_PARAM_BURST_DUR), 204 PARAM_MAP(pdev_param_burst_enable, PDEV_PARAM_BURST_ENABLE), 205 PARAM_MAP(pdev_param_hw_rfkill_config, PDEV_PARAM_HW_RFKILL_CONFIG), 206 PARAM_MAP(pdev_param_low_power_rf_enable, 207 PDEV_PARAM_LOW_POWER_RF_ENABLE), 208 PARAM_MAP(pdev_param_l1ss_track, PDEV_PARAM_L1SS_TRACK), 209 PARAM_MAP(pdev_param_hyst_en, PDEV_PARAM_HYST_EN), 210 PARAM_MAP(pdev_param_power_collapse_enable, 211 PDEV_PARAM_POWER_COLLAPSE_ENABLE), 212 PARAM_MAP(pdev_param_led_sys_state, PDEV_PARAM_LED_SYS_STATE), 213 PARAM_MAP(pdev_param_led_enable, PDEV_PARAM_LED_ENABLE), 214 PARAM_MAP(pdev_param_audio_over_wlan_latency, 215 PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY), 216 PARAM_MAP(pdev_param_audio_over_wlan_enable, 217 PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE), 218 PARAM_MAP(pdev_param_whal_mib_stats_update_enable, 219 PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE), 220 PARAM_MAP(pdev_param_vdev_rate_stats_update_period, 221 PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD), 222 PARAM_MAP(pdev_param_cts_cbw, PDEV_PARAM_CTS_CBW), 223 PARAM_MAP(pdev_param_wnts_config, PDEV_PARAM_WNTS_CONFIG), 224 PARAM_MAP(pdev_param_adaptive_early_rx_enable, 225 PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE), 226 PARAM_MAP(pdev_param_adaptive_early_rx_min_sleep_slop, 227 PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP), 228 PARAM_MAP(pdev_param_adaptive_early_rx_inc_dec_step, 229 PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP), 230 PARAM_MAP(pdev_param_early_rx_fix_sleep_slop, 231 PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP), 232 PARAM_MAP(pdev_param_bmiss_based_adaptive_bto_enable, 233 PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE), 234 PARAM_MAP(pdev_param_bmiss_bto_min_bcn_timeout, 235 PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT), 236 PARAM_MAP(pdev_param_bmiss_bto_inc_dec_step, 237 PDEV_PARAM_BMISS_BTO_INC_DEC_STEP), 238 PARAM_MAP(pdev_param_bto_fix_bcn_timeout, 239 PDEV_PARAM_BTO_FIX_BCN_TIMEOUT), 240 PARAM_MAP(pdev_param_ce_based_adaptive_bto_enable, 241 PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE), 242 PARAM_MAP(pdev_param_ce_bto_combo_ce_value, 243 PDEV_PARAM_CE_BTO_COMBO_CE_VALUE), 244 PARAM_MAP(pdev_param_tx_chain_mask_2g, PDEV_PARAM_TX_CHAIN_MASK_2G), 245 PARAM_MAP(pdev_param_rx_chain_mask_2g, PDEV_PARAM_RX_CHAIN_MASK_2G), 246 PARAM_MAP(pdev_param_tx_chain_mask_5g, PDEV_PARAM_TX_CHAIN_MASK_5G), 247 PARAM_MAP(pdev_param_rx_chain_mask_5g, PDEV_PARAM_RX_CHAIN_MASK_5G), 248 PARAM_MAP(pdev_param_tx_chain_mask_cck, PDEV_PARAM_TX_CHAIN_MASK_CCK), 249 PARAM_MAP(pdev_param_tx_chain_mask_1ss, PDEV_PARAM_TX_CHAIN_MASK_1SS), 250 PARAM_MAP(pdev_param_soft_tx_chain_mask, PDEV_PARAM_TX_CHAIN_MASK), 251 PARAM_MAP(pdev_param_rx_filter, PDEV_PARAM_RX_FILTER), 252 PARAM_MAP(pdev_set_mcast_to_ucast_tid, PDEV_SET_MCAST_TO_UCAST_TID), 253 PARAM_MAP(pdev_param_mgmt_retry_limit, PDEV_PARAM_MGMT_RETRY_LIMIT), 254 PARAM_MAP(pdev_param_aggr_burst, PDEV_PARAM_AGGR_BURST), 255 PARAM_MAP(pdev_peer_sta_ps_statechg_enable, 256 PDEV_PEER_STA_PS_STATECHG_ENABLE), 257 PARAM_MAP(pdev_param_proxy_sta_mode, PDEV_PARAM_PROXY_STA_MODE), 258 PARAM_MAP(pdev_param_mu_group_policy, PDEV_PARAM_MU_GROUP_POLICY), 259 PARAM_MAP(pdev_param_noise_detection, PDEV_PARAM_NOISE_DETECTION), 260 PARAM_MAP(pdev_param_noise_threshold, PDEV_PARAM_NOISE_THRESHOLD), 261 PARAM_MAP(pdev_param_dpd_enable, PDEV_PARAM_DPD_ENABLE), 262 PARAM_MAP(pdev_param_set_mcast_bcast_echo, 263 PDEV_PARAM_SET_MCAST_BCAST_ECHO), 264 PARAM_MAP(pdev_param_atf_strict_sch, PDEV_PARAM_ATF_STRICT_SCH), 265 PARAM_MAP(pdev_param_atf_sched_duration, PDEV_PARAM_ATF_SCHED_DURATION), 266 PARAM_MAP(pdev_param_ant_plzn, PDEV_PARAM_ANT_PLZN), 267 PARAM_MAP(pdev_param_sensitivity_level, PDEV_PARAM_SENSITIVITY_LEVEL), 268 PARAM_MAP(pdev_param_signed_txpower_2g, PDEV_PARAM_SIGNED_TXPOWER_2G), 269 PARAM_MAP(pdev_param_signed_txpower_5g, PDEV_PARAM_SIGNED_TXPOWER_5G), 270 PARAM_MAP(pdev_param_enable_per_tid_amsdu, 271 PDEV_PARAM_ENABLE_PER_TID_AMSDU), 272 PARAM_MAP(pdev_param_enable_per_tid_ampdu, 273 PDEV_PARAM_ENABLE_PER_TID_AMPDU), 274 PARAM_MAP(pdev_param_cca_threshold, PDEV_PARAM_CCA_THRESHOLD), 275 PARAM_MAP(pdev_param_rts_fixed_rate, PDEV_PARAM_RTS_FIXED_RATE), 276 PARAM_MAP(pdev_param_cal_period, UNAVAILABLE_PARAM), 277 PARAM_MAP(pdev_param_pdev_reset, PDEV_PARAM_PDEV_RESET), 278 PARAM_MAP(pdev_param_wapi_mbssid_offset, PDEV_PARAM_WAPI_MBSSID_OFFSET), 279 PARAM_MAP(pdev_param_arp_srcaddr, PDEV_PARAM_ARP_DBG_SRCADDR), 280 PARAM_MAP(pdev_param_arp_dstaddr, PDEV_PARAM_ARP_DBG_DSTADDR), 281 PARAM_MAP(pdev_param_txpower_decr_db, PDEV_PARAM_TXPOWER_DECR_DB), 282 PARAM_MAP(pdev_param_rx_batchmode, UNAVAILABLE_PARAM), 283 PARAM_MAP(pdev_param_packet_aggr_delay, UNAVAILABLE_PARAM), 284 PARAM_MAP(pdev_param_atf_obss_noise_sch, PDEV_PARAM_ATF_OBSS_NOISE_SCH), 285 PARAM_MAP(pdev_param_atf_obss_noise_scaling_factor, 286 PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR), 287 PARAM_MAP(pdev_param_cust_txpower_scale, PDEV_PARAM_CUST_TXPOWER_SCALE), 288 PARAM_MAP(pdev_param_atf_dynamic_enable, PDEV_PARAM_ATF_DYNAMIC_ENABLE), 289 PARAM_MAP(pdev_param_atf_ssid_group_policy, UNAVAILABLE_PARAM), 290 PARAM_MAP(pdev_param_igmpmld_override, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 291 PARAM_MAP(pdev_param_igmpmld_tid, PDEV_PARAM_IGMPMLD_AC_OVERRIDE), 292 PARAM_MAP(pdev_param_antenna_gain, PDEV_PARAM_ANTENNA_GAIN), 293 PARAM_MAP(pdev_param_block_interbss, PDEV_PARAM_BLOCK_INTERBSS), 294 PARAM_MAP(pdev_param_set_disable_reset_cmdid, 295 PDEV_PARAM_SET_DISABLE_RESET_CMDID), 296 PARAM_MAP(pdev_param_set_msdu_ttl_cmdid, PDEV_PARAM_SET_MSDU_TTL_CMDID), 297 PARAM_MAP(pdev_param_txbf_sound_period_cmdid, 298 PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID), 299 PARAM_MAP(pdev_param_set_burst_mode_cmdid, 300 PDEV_PARAM_SET_BURST_MODE_CMDID), 301 PARAM_MAP(pdev_param_en_stats, PDEV_PARAM_EN_STATS), 302 PARAM_MAP(pdev_param_mesh_mcast_enable, PDEV_PARAM_MESH_MCAST_ENABLE), 303 PARAM_MAP(pdev_param_set_promisc_mode_cmdid, 304 PDEV_PARAM_SET_PROMISC_MODE_CMDID), 305 PARAM_MAP(pdev_param_set_ppdu_duration_cmdid, 306 PDEV_PARAM_SET_PPDU_DURATION_CMDID), 307 PARAM_MAP(pdev_param_remove_mcast2ucast_buffer, 308 PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER), 309 PARAM_MAP(pdev_param_set_mcast2ucast_buffer, 310 PDEV_PARAM_SET_MCAST2UCAST_BUFFER), 311 PARAM_MAP(pdev_param_set_mcast2ucast_mode, 312 PDEV_PARAM_SET_MCAST2UCAST_MODE), 313 PARAM_MAP(pdev_param_smart_antenna_default_antenna, 314 PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA), 315 PARAM_MAP(pdev_param_fast_channel_reset, 316 PDEV_PARAM_FAST_CHANNEL_RESET), 317 PARAM_MAP(pdev_param_rx_decap_mode, PDEV_PARAM_RX_DECAP_MODE), 318 PARAM_MAP(pdev_param_tx_ack_timeout, PDEV_PARAM_ACK_TIMEOUT), 319 PARAM_MAP(pdev_param_cck_tx_enable, PDEV_PARAM_CCK_TX_ENABLE), 320 PARAM_MAP(pdev_param_antenna_gain_half_db, 321 PDEV_PARAM_ANTENNA_GAIN_HALF_DB), 322 PARAM_MAP(pdev_param_esp_indication_period, 323 PDEV_PARAM_ESP_INDICATION_PERIOD), 324 PARAM_MAP(pdev_param_esp_ba_window, PDEV_PARAM_ESP_BA_WINDOW), 325 PARAM_MAP(pdev_param_esp_airtime_fraction, 326 PDEV_PARAM_ESP_AIRTIME_FRACTION), 327 PARAM_MAP(pdev_param_esp_ppdu_duration, PDEV_PARAM_ESP_PPDU_DURATION), 328 PARAM_MAP(pdev_param_ru26_allowed, PDEV_PARAM_UL_RU26_ALLOWED), 329 PARAM_MAP(pdev_param_use_nol, PDEV_PARAM_USE_NOL), 330 PARAM_MAP(pdev_param_ul_trig_int, PDEV_PARAM_SET_UL_BSR_TRIG_INTERVAL), 331 PARAM_MAP(pdev_param_sub_channel_marking, 332 PDEV_PARAM_SUB_CHANNEL_MARKING), 333 PARAM_MAP(pdev_param_ul_ppdu_duration, PDEV_PARAM_SET_UL_PPDU_DURATION), 334 PARAM_MAP(pdev_param_equal_ru_allocation_enable, 335 PDEV_PARAM_EQUAL_RU_ALLOCATION_ENABLE), 336 PARAM_MAP(pdev_param_per_peer_prd_cfr_enable, 337 PDEV_PARAM_PER_PEER_PERIODIC_CFR_ENABLE), 338 PARAM_MAP(pdev_param_nav_override_config, 339 PDEV_PARAM_NAV_OVERRIDE_CONFIG), 340 PARAM_MAP(pdev_param_set_mgmt_ttl, PDEV_PARAM_SET_MGMT_TTL), 341 PARAM_MAP(pdev_param_set_prb_rsp_ttl, 342 PDEV_PARAM_SET_PROBE_RESP_TTL), 343 PARAM_MAP(pdev_param_set_mu_ppdu_duration, 344 PDEV_PARAM_SET_MU_PPDU_DURATION), 345 PARAM_MAP(pdev_param_set_tbtt_ctrl, 346 PDEV_PARAM_SET_TBTT_CTRL), 347 PARAM_MAP(pdev_param_set_cmd_obss_pd_threshold, 348 PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 349 PARAM_MAP(pdev_param_set_cmd_obss_pd_per_ac, 350 PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 351 PARAM_MAP(pdev_param_set_cong_ctrl_max_msdus, 352 PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS), 353 PARAM_MAP(pdev_param_enable_fw_dynamic_he_edca, 354 PDEV_PARAM_ENABLE_FW_DYNAMIC_HE_EDCA), 355 PARAM_MAP(pdev_param_enable_srp, PDEV_PARAM_ENABLE_SRP), 356 PARAM_MAP(pdev_param_enable_sr_prohibit, PDEV_PARAM_ENABLE_SR_PROHIBIT), 357 PARAM_MAP(pdev_param_sr_trigger_margin, PDEV_PARAM_SR_TRIGGER_MARGIN), 358 PARAM_MAP(pdev_param_pream_punct_bw, PDEV_PARAM_SET_PREAM_PUNCT_BW), 359 PARAM_MAP(pdev_param_enable_mbssid_ctrl_frame, 360 PDEV_PARAM_ENABLE_MBSSID_CTRL_FRAME), 361 PARAM_MAP(pdev_param_set_mesh_params, PDEV_PARAM_SET_MESH_PARAMS), 362 PARAM_MAP(pdev_param_mpd_userpd_ssr, PDEV_PARAM_MPD_USERPD_SSR), 363 PARAM_MAP(pdev_param_low_latency_mode, 364 PDEV_PARAM_LOW_LATENCY_SCHED_MODE), 365 PARAM_MAP(pdev_param_scan_radio_tx_on_dfs, 366 PDEV_PARAM_SCAN_RADIO_TX_ON_DFS), 367 PARAM_MAP(pdev_param_en_probe_all_bw, 368 PDEV_PARAM_EN_PROBE_ALL_BW), 369 PARAM_MAP(pdev_param_obss_min_duration_check_for_sr, 370 PDEV_PARAM_OBSS_MIN_DURATION_CHECK_FOR_SR), 371 PARAM_MAP(pdev_param_truncate_sr, PDEV_PARAM_TRUNCATE_SR), 372 PARAM_MAP(pdev_param_ctrl_frame_obss_pd_threshold, 373 PDEV_PARAM_CTRL_FRAME_OBSS_PD_THRESHOLD), 374 PARAM_MAP(pdev_param_rate_upper_cap, PDEV_PARAM_RATE_UPPER_CAP), 375 PARAM_MAP(pdev_param_set_disabled_sched_modes, 376 PDEV_PARAM_SET_DISABLED_SCHED_MODES), 377 PARAM_MAP(pdev_param_rate_retry_mcs_drop, 378 PDEV_PARAM_SET_RATE_DROP_DOWN_RETRY_THRESH), 379 PARAM_MAP(pdev_param_mcs_probe_intvl, 380 PDEV_PARAM_MIN_MAX_MCS_PROBE_INTERVAL), 381 PARAM_MAP(pdev_param_nss_probe_intvl, 382 PDEV_PARAM_MIN_MAX_NSS_PROBE_INTERVAL), 383 PARAM_MAP(pdev_param_dtim_synth, PDEV_PARAM_DTIM_SYNTH), 384 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 385 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 386 PARAM_MAP(pdev_param_tx_sch_delay, PDEV_PARAM_TX_SCH_DELAY), 387 PARAM_MAP(pdev_param_en_update_scram_seed, 388 PDEV_PARAM_EN_UPDATE_SCRAM_SEED), 389 PARAM_MAP(pdev_param_secondary_retry_enable, 390 PDEV_PARAM_SECONDARY_RETRY_ENABLE), 391 PARAM_MAP(pdev_param_set_sap_xlna_bypass, 392 PDEV_PARAM_SET_SAP_XLNA_BYPASS), 393 PARAM_MAP(pdev_param_set_dfs_chan_ageout_time, 394 PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME), 395 PARAM_MAP(pdev_param_pdev_stats_tx_xretry_ext, 396 PDEV_PARAM_PDEV_STATS_TX_XRETRY_EXT), 397 PARAM_MAP(pdev_param_smart_chainmask_scheme, 398 PDEV_PARAM_SMART_CHAINMASK_SCHEME), 399 PARAM_MAP(pdev_param_alternative_chainmask_scheme, 400 PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME), 401 PARAM_MAP(pdev_param_enable_rts_sifs_bursting, 402 PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING), 403 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 404 PARAM_MAP(pdev_param_set_iot_pattern, PDEV_PARAM_SET_IOT_PATTERN), 405 PARAM_MAP(pdev_param_mwscoex_scc_chavd_delay, 406 PDEV_PARAM_MWSCOEX_SCC_CHAVD_DELAY), 407 PARAM_MAP(pdev_param_mwscoex_pcc_chavd_delay, 408 PDEV_PARAM_MWSCOEX_PCC_CHAVD_DELAY), 409 PARAM_MAP(pdev_param_mwscoex_set_5gnr_pwr_limit, 410 PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT), 411 PARAM_MAP(pdev_param_mwscoex_4g_allow_quick_ftdm, 412 PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM), 413 PARAM_MAP(pdev_param_fast_pwr_transition, 414 PDEV_PARAM_FAST_PWR_TRANSITION), 415 PARAM_MAP(pdev_auto_detect_power_failure, 416 PDEV_AUTO_DETECT_POWER_FAILURE), 417 PARAM_MAP(pdev_param_gcmp_support_enable, 418 PDEV_PARAM_GCMP_SUPPORT_ENABLE), 419 PARAM_MAP(pdev_param_abg_mode_tx_chain_num, 420 PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 421 PARAM_MAP(pdev_param_peer_stats_info_enable, 422 PDEV_PARAM_PEER_STATS_INFO_ENABLE), 423 PARAM_MAP(pdev_param_enable_cck_txfir_override, 424 PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE), 425 PARAM_MAP(pdev_param_twt_ac_config, PDEV_PARAM_TWT_AC_CONFIG), 426 PARAM_MAP(pdev_param_pcie_hw_ilp, PDEV_PARAM_PCIE_HW_ILP), 427 PARAM_MAP(pdev_param_disable_hw_assist, PDEV_PARAM_DISABLE_HW_ASSIST), 428 PARAM_MAP(pdev_param_ant_div_usrcfg, PDEV_PARAM_ANT_DIV_USRCFG), 429 PARAM_MAP(pdev_param_ctrl_retry_limit, PDEV_PARAM_CTRL_RETRY_LIMIT), 430 PARAM_MAP(pdev_param_propagation_delay, PDEV_PARAM_PROPAGATION_DELAY), 431 PARAM_MAP(pdev_param_ena_ant_div, PDEV_PARAM_ENA_ANT_DIV), 432 PARAM_MAP(pdev_param_force_chain_ant, PDEV_PARAM_FORCE_CHAIN_ANT), 433 PARAM_MAP(pdev_param_ant_div_selftest, PDEV_PARAM_ANT_DIV_SELFTEST), 434 PARAM_MAP(pdev_param_ant_div_selftest_intvl, 435 PDEV_PARAM_ANT_DIV_SELFTEST_INTVL), 436 PARAM_MAP(pdev_param_1ch_dtim_optimized_chain_selection, 437 PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION), 438 PARAM_MAP(pdev_param_data_stall_detect_enable, 439 PDEV_PARAM_DATA_STALL_DETECT_ENABLE), 440 PARAM_MAP(pdev_param_max_mpdus_in_ampdu, 441 PDEV_PARAM_MAX_MPDUS_IN_AMPDU), 442 PARAM_MAP(pdev_param_stats_observation_period, 443 PDEV_PARAM_STATS_OBSERVATION_PERIOD), 444 PARAM_MAP(pdev_param_cts2self_for_p2p_go_config, 445 PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG), 446 PARAM_MAP(pdev_param_txpower_reason_sar, PDEV_PARAM_TXPOWER_REASON_SAR), 447 PARAM_MAP(pdev_param_default_6ghz_rate, PDEV_PARAM_DEFAULT_6GHZ_RATE), 448 PARAM_MAP(pdev_param_scan_blanking_mode, 449 PDEV_PARAM_SET_SCAN_BLANKING_MODE), 450 PARAM_MAP(pdev_param_set_conc_low_latency_mode, 451 PDEV_PARAM_SET_CONC_LOW_LATENCY_MODE), 452 PARAM_MAP(pdev_param_rtt_11az_rsid_range, 453 PDEV_PARAM_RTT_11AZ_RSID_RANGE), 454 PARAM_MAP(pdev_param_pcie_config, PDEV_PARAM_PCIE_CONFIG), 455 PARAM_MAP(pdev_param_probe_resp_retry_limit, 456 PDEV_PARAM_PROBE_RESP_RETRY_LIMIT), 457 PARAM_MAP(pdev_param_cts_timeout, PDEV_PARAM_CTS_TIMEOUT), 458 PARAM_MAP(pdev_param_slot_time, PDEV_PARAM_SLOT_TIME), 459 PARAM_MAP(pdev_param_atf_vo_dedicated_time, 460 PDEV_PARAM_ATF_VO_DEDICATED_TIME), 461 PARAM_MAP(pdev_param_atf_vi_dedicated_time, 462 PDEV_PARAM_ATF_VI_DEDICATED_TIME), 463 PARAM_MAP(pdev_param_ul_ofdma_rtd, PDEV_PARAM_UL_OFDMA_RTD), 464 PARAM_MAP(pdev_param_tid_mapping_3link_mlo, 465 PDEV_PARAM_TID_MAPPING_3LINK_MLO), 466 }; 467 468 /* Populate vdev_param array whose index is host param, value is target param */ 469 static const uint32_t vdev_param_tlv[] = { 470 PARAM_MAP(vdev_param_rts_threshold, VDEV_PARAM_RTS_THRESHOLD), 471 PARAM_MAP(vdev_param_fragmentation_threshold, 472 VDEV_PARAM_FRAGMENTATION_THRESHOLD), 473 PARAM_MAP(vdev_param_beacon_interval, VDEV_PARAM_BEACON_INTERVAL), 474 PARAM_MAP(vdev_param_listen_interval, VDEV_PARAM_LISTEN_INTERVAL), 475 PARAM_MAP(vdev_param_multicast_rate, VDEV_PARAM_MULTICAST_RATE), 476 PARAM_MAP(vdev_param_mgmt_tx_rate, VDEV_PARAM_MGMT_TX_RATE), 477 PARAM_MAP(vdev_param_slot_time, VDEV_PARAM_SLOT_TIME), 478 PARAM_MAP(vdev_param_preamble, VDEV_PARAM_PREAMBLE), 479 PARAM_MAP(vdev_param_swba_time, VDEV_PARAM_SWBA_TIME), 480 PARAM_MAP(vdev_stats_update_period, VDEV_STATS_UPDATE_PERIOD), 481 PARAM_MAP(vdev_pwrsave_ageout_time, VDEV_PWRSAVE_AGEOUT_TIME), 482 PARAM_MAP(vdev_host_swba_interval, VDEV_HOST_SWBA_INTERVAL), 483 PARAM_MAP(vdev_param_dtim_period, VDEV_PARAM_DTIM_PERIOD), 484 PARAM_MAP(vdev_oc_scheduler_air_time_limit, 485 VDEV_OC_SCHEDULER_AIR_TIME_LIMIT), 486 PARAM_MAP(vdev_param_wds, VDEV_PARAM_WDS), 487 PARAM_MAP(vdev_param_atim_window, VDEV_PARAM_ATIM_WINDOW), 488 PARAM_MAP(vdev_param_bmiss_count_max, VDEV_PARAM_BMISS_COUNT_MAX), 489 PARAM_MAP(vdev_param_bmiss_first_bcnt, VDEV_PARAM_BMISS_FIRST_BCNT), 490 PARAM_MAP(vdev_param_bmiss_final_bcnt, VDEV_PARAM_BMISS_FINAL_BCNT), 491 PARAM_MAP(vdev_param_feature_wmm, VDEV_PARAM_FEATURE_WMM), 492 PARAM_MAP(vdev_param_chwidth, VDEV_PARAM_CHWIDTH), 493 PARAM_MAP(vdev_param_chextoffset, VDEV_PARAM_CHEXTOFFSET), 494 PARAM_MAP(vdev_param_disable_htprotection, 495 VDEV_PARAM_DISABLE_HTPROTECTION), 496 PARAM_MAP(vdev_param_sta_quickkickout, VDEV_PARAM_STA_QUICKKICKOUT), 497 PARAM_MAP(vdev_param_mgmt_rate, VDEV_PARAM_MGMT_RATE), 498 PARAM_MAP(vdev_param_protection_mode, VDEV_PARAM_PROTECTION_MODE), 499 PARAM_MAP(vdev_param_fixed_rate, VDEV_PARAM_FIXED_RATE), 500 PARAM_MAP(vdev_param_sgi, VDEV_PARAM_SGI), 501 PARAM_MAP(vdev_param_ldpc, VDEV_PARAM_LDPC), 502 PARAM_MAP(vdev_param_tx_stbc, VDEV_PARAM_TX_STBC), 503 PARAM_MAP(vdev_param_rx_stbc, VDEV_PARAM_RX_STBC), 504 PARAM_MAP(vdev_param_intra_bss_fwd, VDEV_PARAM_INTRA_BSS_FWD), 505 PARAM_MAP(vdev_param_def_keyid, VDEV_PARAM_DEF_KEYID), 506 PARAM_MAP(vdev_param_nss, VDEV_PARAM_NSS), 507 PARAM_MAP(vdev_param_bcast_data_rate, VDEV_PARAM_BCAST_DATA_RATE), 508 PARAM_MAP(vdev_param_mcast_data_rate, VDEV_PARAM_MCAST_DATA_RATE), 509 PARAM_MAP(vdev_param_mcast_indicate, VDEV_PARAM_MCAST_INDICATE), 510 PARAM_MAP(vdev_param_dhcp_indicate, VDEV_PARAM_DHCP_INDICATE), 511 PARAM_MAP(vdev_param_unknown_dest_indicate, 512 VDEV_PARAM_UNKNOWN_DEST_INDICATE), 513 PARAM_MAP(vdev_param_ap_keepalive_min_idle_inactive_time_secs, 514 VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS), 515 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_time_secs, 516 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 517 PARAM_MAP(vdev_param_ap_keepalive_max_unresponsive_time_secs, 518 VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS), 519 PARAM_MAP(vdev_param_ap_enable_nawds, VDEV_PARAM_AP_ENABLE_NAWDS), 520 PARAM_MAP(vdev_param_enable_rtscts, VDEV_PARAM_ENABLE_RTSCTS), 521 PARAM_MAP(vdev_param_txbf, VDEV_PARAM_TXBF), 522 PARAM_MAP(vdev_param_packet_powersave, VDEV_PARAM_PACKET_POWERSAVE), 523 PARAM_MAP(vdev_param_drop_unencry, VDEV_PARAM_DROP_UNENCRY), 524 PARAM_MAP(vdev_param_tx_encap_type, VDEV_PARAM_TX_ENCAP_TYPE), 525 PARAM_MAP(vdev_param_ap_detect_out_of_sync_sleeping_sta_time_secs, 526 VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS), 527 PARAM_MAP(vdev_param_early_rx_adjust_enable, 528 VDEV_PARAM_EARLY_RX_ADJUST_ENABLE), 529 PARAM_MAP(vdev_param_early_rx_tgt_bmiss_num, 530 VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM), 531 PARAM_MAP(vdev_param_early_rx_bmiss_sample_cycle, 532 VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE), 533 PARAM_MAP(vdev_param_early_rx_slop_step, VDEV_PARAM_EARLY_RX_SLOP_STEP), 534 PARAM_MAP(vdev_param_early_rx_init_slop, VDEV_PARAM_EARLY_RX_INIT_SLOP), 535 PARAM_MAP(vdev_param_early_rx_adjust_pause, 536 VDEV_PARAM_EARLY_RX_ADJUST_PAUSE), 537 PARAM_MAP(vdev_param_tx_pwrlimit, VDEV_PARAM_TX_PWRLIMIT), 538 PARAM_MAP(vdev_param_snr_num_for_cal, VDEV_PARAM_SNR_NUM_FOR_CAL), 539 PARAM_MAP(vdev_param_roam_fw_offload, VDEV_PARAM_ROAM_FW_OFFLOAD), 540 PARAM_MAP(vdev_param_enable_rmc, VDEV_PARAM_ENABLE_RMC), 541 PARAM_MAP(vdev_param_ibss_max_bcn_lost_ms, 542 VDEV_PARAM_IBSS_MAX_BCN_LOST_MS), 543 PARAM_MAP(vdev_param_max_rate, VDEV_PARAM_MAX_RATE), 544 PARAM_MAP(vdev_param_early_rx_drift_sample, 545 VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE), 546 PARAM_MAP(vdev_param_set_ibss_tx_fail_cnt_thr, 547 VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR), 548 PARAM_MAP(vdev_param_ebt_resync_timeout, 549 VDEV_PARAM_EBT_RESYNC_TIMEOUT), 550 PARAM_MAP(vdev_param_aggr_trig_event_enable, 551 VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE), 552 PARAM_MAP(vdev_param_is_ibss_power_save_allowed, 553 VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED), 554 PARAM_MAP(vdev_param_is_power_collapse_allowed, 555 VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED), 556 PARAM_MAP(vdev_param_is_awake_on_txrx_enabled, 557 VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED), 558 PARAM_MAP(vdev_param_inactivity_cnt, VDEV_PARAM_INACTIVITY_CNT), 559 PARAM_MAP(vdev_param_txsp_end_inactivity_time_ms, 560 VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS), 561 PARAM_MAP(vdev_param_dtim_policy, VDEV_PARAM_DTIM_POLICY), 562 PARAM_MAP(vdev_param_ibss_ps_warmup_time_secs, 563 VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS), 564 PARAM_MAP(vdev_param_ibss_ps_1rx_chain_in_atim_window_enable, 565 VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE), 566 PARAM_MAP(vdev_param_rx_leak_window, VDEV_PARAM_RX_LEAK_WINDOW), 567 PARAM_MAP(vdev_param_stats_avg_factor, 568 VDEV_PARAM_STATS_AVG_FACTOR), 569 PARAM_MAP(vdev_param_disconnect_th, VDEV_PARAM_DISCONNECT_TH), 570 PARAM_MAP(vdev_param_rtscts_rate, VDEV_PARAM_RTSCTS_RATE), 571 PARAM_MAP(vdev_param_mcc_rtscts_protection_enable, 572 VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE), 573 PARAM_MAP(vdev_param_mcc_broadcast_probe_enable, 574 VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE), 575 PARAM_MAP(vdev_param_mgmt_tx_power, VDEV_PARAM_MGMT_TX_POWER), 576 PARAM_MAP(vdev_param_beacon_rate, VDEV_PARAM_BEACON_RATE), 577 PARAM_MAP(vdev_param_rx_decap_type, VDEV_PARAM_RX_DECAP_TYPE), 578 PARAM_MAP(vdev_param_he_dcm_enable, VDEV_PARAM_HE_DCM), 579 PARAM_MAP(vdev_param_he_range_ext_enable, VDEV_PARAM_HE_RANGE_EXT), 580 PARAM_MAP(vdev_param_he_bss_color, VDEV_PARAM_BSS_COLOR), 581 PARAM_MAP(vdev_param_set_hemu_mode, VDEV_PARAM_SET_HEMU_MODE), 582 PARAM_MAP(vdev_param_set_he_sounding_mode, 583 VDEV_PARAM_SET_HE_SOUNDING_MODE), 584 PARAM_MAP(vdev_param_set_heop, VDEV_PARAM_HEOPS_0_31), 585 PARAM_MAP(vdev_param_set_ehtop, VDEV_PARAM_EHTOPS_0_31), 586 PARAM_MAP(vdev_param_set_eht_mu_mode, VDEV_PARAM_SET_EHT_MU_MODE), 587 PARAM_MAP(vdev_param_set_eht_puncturing_mode, 588 VDEV_PARAM_SET_EHT_PUNCTURING_MODE), 589 PARAM_MAP(vdev_param_set_eht_ltf, VDEV_PARAM_EHT_LTF), 590 PARAM_MAP(vdev_param_set_ul_eht_ltf, VDEV_PARAM_UL_EHT_LTF), 591 PARAM_MAP(vdev_param_set_eht_dcm, VDEV_PARAM_EHT_DCM), 592 PARAM_MAP(vdev_param_set_eht_range_ext, VDEV_PARAM_EHT_RANGE_EXT), 593 PARAM_MAP(vdev_param_set_non_data_eht_range_ext, 594 VDEV_PARAM_NON_DATA_EHT_RANGE_EXT), 595 PARAM_MAP(vdev_param_sensor_ap, VDEV_PARAM_SENSOR_AP), 596 PARAM_MAP(vdev_param_dtim_enable_cts, VDEV_PARAM_DTIM_ENABLE_CTS), 597 PARAM_MAP(vdev_param_atf_ssid_sched_policy, 598 VDEV_PARAM_ATF_SSID_SCHED_POLICY), 599 PARAM_MAP(vdev_param_disable_dyn_bw_rts, VDEV_PARAM_DISABLE_DYN_BW_RTS), 600 PARAM_MAP(vdev_param_mcast2ucast_set, VDEV_PARAM_MCAST2UCAST_SET), 601 PARAM_MAP(vdev_param_rc_num_retries, VDEV_PARAM_RC_NUM_RETRIES), 602 PARAM_MAP(vdev_param_cabq_maxdur, VDEV_PARAM_CABQ_MAXDUR), 603 PARAM_MAP(vdev_param_mfptest_set, VDEV_PARAM_MFPTEST_SET), 604 PARAM_MAP(vdev_param_rts_fixed_rate, VDEV_PARAM_RTS_FIXED_RATE), 605 PARAM_MAP(vdev_param_vht_sgimask, VDEV_PARAM_VHT_SGIMASK), 606 PARAM_MAP(vdev_param_vht80_ratemask, VDEV_PARAM_VHT80_RATEMASK), 607 PARAM_MAP(vdev_param_proxy_sta, VDEV_PARAM_PROXY_STA), 608 PARAM_MAP(vdev_param_bw_nss_ratemask, VDEV_PARAM_BW_NSS_RATEMASK), 609 PARAM_MAP(vdev_param_set_he_ltf, VDEV_PARAM_HE_LTF), 610 PARAM_MAP(vdev_param_disable_cabq, VDEV_PARAM_DISABLE_CABQ), 611 PARAM_MAP(vdev_param_rate_dropdown_bmap, VDEV_PARAM_RATE_DROPDOWN_BMAP), 612 PARAM_MAP(vdev_param_set_ba_mode, VDEV_PARAM_BA_MODE), 613 PARAM_MAP(vdev_param_capabilities, VDEV_PARAM_CAPABILITIES), 614 PARAM_MAP(vdev_param_autorate_misc_cfg, VDEV_PARAM_AUTORATE_MISC_CFG), 615 PARAM_MAP(vdev_param_ul_shortgi, VDEV_PARAM_UL_GI), 616 PARAM_MAP(vdev_param_ul_he_ltf, VDEV_PARAM_UL_HE_LTF), 617 PARAM_MAP(vdev_param_ul_nss, VDEV_PARAM_UL_NSS), 618 PARAM_MAP(vdev_param_ul_ppdu_bw, VDEV_PARAM_UL_PPDU_BW), 619 PARAM_MAP(vdev_param_ul_ldpc, VDEV_PARAM_UL_LDPC), 620 PARAM_MAP(vdev_param_ul_stbc, VDEV_PARAM_UL_STBC), 621 PARAM_MAP(vdev_param_ul_fixed_rate, VDEV_PARAM_UL_FIXED_RATE), 622 PARAM_MAP(vdev_param_rawmode_open_war, VDEV_PARAM_RAW_IS_ENCRYPTED), 623 PARAM_MAP(vdev_param_max_mtu_size, VDEV_PARAM_MAX_MTU_SIZE), 624 PARAM_MAP(vdev_param_mcast_rc_stale_period, 625 VDEV_PARAM_MCAST_RC_STALE_PERIOD), 626 PARAM_MAP(vdev_param_enable_multi_group_key, 627 VDEV_PARAM_ENABLE_MULTI_GROUP_KEY), 628 PARAM_MAP(vdev_param_max_group_keys, VDEV_PARAM_NUM_GROUP_KEYS), 629 PARAM_MAP(vdev_param_enable_mcast_rc, VDEV_PARAM_ENABLE_MCAST_RC), 630 PARAM_MAP(vdev_param_6ghz_params, VDEV_PARAM_6GHZ_PARAMS), 631 PARAM_MAP(vdev_param_enable_disable_roam_reason_vsie, 632 VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE), 633 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 634 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 635 PARAM_MAP(vdev_param_set_cmd_obss_pd_per_ac, 636 VDEV_PARAM_SET_CMD_OBSS_PD_PER_AC), 637 PARAM_MAP(vdev_param_enable_srp, VDEV_PARAM_ENABLE_SRP), 638 PARAM_MAP(vdev_param_nan_config_features, 639 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 640 PARAM_MAP(vdev_param_enable_disable_rtt_responder_role, 641 VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE), 642 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_role, 643 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE), 644 PARAM_MAP(vdev_param_mcast_steer, VDEV_PARAM_MCAST_STEERING), 645 PARAM_MAP(vdev_param_set_normal_latency_flags_config, 646 VDEV_PARAM_NORMAL_LATENCY_FLAGS_CONFIGURATION), 647 PARAM_MAP(vdev_param_set_xr_latency_flags_config, 648 VDEV_PARAM_XR_LATENCY_FLAGS_CONFIGURATION), 649 PARAM_MAP(vdev_param_set_low_latency_flags_config, 650 VDEV_PARAM_LOW_LATENCY_FLAGS_CONFIGURATION), 651 PARAM_MAP(vdev_param_set_ultra_low_latency_flags_config, 652 VDEV_PARAM_ULTRA_LOW_LATENCY_FLAGS_CONFIGURATION), 653 PARAM_MAP(vdev_param_set_normal_latency_ul_dl_config, 654 VDEV_PARAM_NORMAL_LATENCY_UL_DL_CONFIGURATION), 655 PARAM_MAP(vdev_param_set_xr_latency_ul_dl_config, 656 VDEV_PARAM_XR_LATENCY_UL_DL_CONFIGURATION), 657 PARAM_MAP(vdev_param_set_low_latency_ul_dl_config, 658 VDEV_PARAM_LOW_LATENCY_UL_DL_CONFIGURATION), 659 PARAM_MAP(vdev_param_set_ultra_low_latency_ul_dl_config, 660 VDEV_PARAM_ULTRA_LOW_LATENCY_UL_DL_CONFIGURATION), 661 PARAM_MAP(vdev_param_set_default_ll_config, 662 VDEV_PARAM_DEFAULT_LATENCY_LEVEL_CONFIGURATION), 663 PARAM_MAP(vdev_param_set_multi_client_ll_feature_config, 664 VDEV_PARAM_MULTI_CLIENT_LL_FEATURE_CONFIGURATION), 665 PARAM_MAP(vdev_param_set_traffic_config, 666 VDEV_PARAM_VDEV_TRAFFIC_CONFIG), 667 PARAM_MAP(vdev_param_he_range_ext, VDEV_PARAM_HE_RANGE_EXT), 668 PARAM_MAP(vdev_param_non_data_he_range_ext, 669 VDEV_PARAM_NON_DATA_HE_RANGE_EXT), 670 PARAM_MAP(vdev_param_ndp_inactivity_timeout, 671 VDEV_PARAM_NDP_INACTIVITY_TIMEOUT), 672 PARAM_MAP(vdev_param_ndp_keepalive_timeout, 673 VDEV_PARAM_NDP_KEEPALIVE_TIMEOUT), 674 PARAM_MAP(vdev_param_final_bmiss_time_sec, 675 VDEV_PARAM_FINAL_BMISS_TIME_SEC), 676 PARAM_MAP(vdev_param_final_bmiss_time_wow_sec, 677 VDEV_PARAM_FINAL_BMISS_TIME_WOW_SEC), 678 PARAM_MAP(vdev_param_ap_keepalive_max_idle_inactive_secs, 679 VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS), 680 PARAM_MAP(vdev_param_per_band_mgmt_tx_rate, 681 VDEV_PARAM_PER_BAND_MGMT_TX_RATE), 682 PARAM_MAP(vdev_param_max_li_of_moddtim, 683 VDEV_PARAM_MAX_LI_OF_MODDTIM), 684 PARAM_MAP(vdev_param_moddtim_cnt, VDEV_PARAM_MODDTIM_CNT), 685 PARAM_MAP(vdev_param_max_li_of_moddtim_ms, 686 VDEV_PARAM_MAX_LI_OF_MODDTIM_MS), 687 PARAM_MAP(vdev_param_dyndtim_cnt, VDEV_PARAM_DYNDTIM_CNT), 688 PARAM_MAP(vdev_param_wmm_txop_enable, VDEV_PARAM_WMM_TXOP_ENABLE), 689 PARAM_MAP(vdev_param_enable_bcast_probe_response, 690 VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE), 691 PARAM_MAP(vdev_param_fils_max_channel_guard_time, 692 VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME), 693 PARAM_MAP(vdev_param_probe_delay, VDEV_PARAM_PROBE_DELAY), 694 PARAM_MAP(vdev_param_repeat_probe_time, VDEV_PARAM_REPEAT_PROBE_TIME), 695 PARAM_MAP(vdev_param_enable_disable_oce_features, 696 VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES), 697 PARAM_MAP(vdev_param_enable_disable_nan_config_features, 698 VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES), 699 PARAM_MAP(vdev_param_rsn_capability, VDEV_PARAM_RSN_CAPABILITY), 700 PARAM_MAP(vdev_param_smps_intolerant, VDEV_PARAM_SMPS_INTOLERANT), 701 PARAM_MAP(vdev_param_abg_mode_tx_chain_num, 702 VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM), 703 PARAM_MAP(vdev_param_nth_beacon_to_host, VDEV_PARAM_NTH_BEACON_TO_HOST), 704 PARAM_MAP(vdev_param_prohibit_data_mgmt, VDEV_PARAM_PROHIBIT_DATA_MGMT), 705 PARAM_MAP(vdev_param_skip_roam_eapol_4way_handshake, 706 VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE), 707 PARAM_MAP(vdev_param_skip_sae_roam_4way_handshake, 708 VDEV_PARAM_SKIP_SAE_ROAM_4WAY_HANDSHAKE), 709 PARAM_MAP(vdev_param_roam_11kv_ctrl, VDEV_PARAM_ROAM_11KV_CTRL), 710 PARAM_MAP(vdev_param_disable_noa_p2p_go, VDEV_PARAM_DISABLE_NOA_P2P_GO), 711 PARAM_MAP(vdev_param_packet_capture_mode, 712 VDEV_PARAM_PACKET_CAPTURE_MODE), 713 PARAM_MAP(vdev_param_smart_monitor_config, 714 VDEV_PARAM_SMART_MONITOR_CONFIG), 715 PARAM_MAP(vdev_param_force_dtim_cnt, VDEV_PARAM_FORCE_DTIM_CNT), 716 PARAM_MAP(vdev_param_sho_config, VDEV_PARAM_SHO_CONFIG), 717 PARAM_MAP(vdev_param_gtx_enable, VDEV_PARAM_GTX_ENABLE), 718 PARAM_MAP(vdev_param_mu_edca_fw_update_en, 719 VDEV_PARAM_MU_EDCA_FW_UPDATE_EN), 720 PARAM_MAP(vdev_param_enable_disable_rtt_initiator_random_mac, 721 VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC), 722 PARAM_MAP(vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 723 VDEV_PARAM_ALLOW_NAN_INITIAL_DISCOVERY_OF_MP0_CLUSTER), 724 PARAM_MAP(vdev_param_txpower_scale_decr_db, 725 VDEV_PARAM_TXPOWER_SCALE_DECR_DB), 726 PARAM_MAP(vdev_param_txpower_scale, VDEV_PARAM_TXPOWER_SCALE), 727 PARAM_MAP(vdev_param_agg_sw_retry_th, VDEV_PARAM_AGG_SW_RETRY_TH), 728 PARAM_MAP(vdev_param_obsspd, VDEV_PARAM_OBSSPD), 729 PARAM_MAP(vdev_param_amsdu_aggregation_size_optimization, 730 VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION), 731 PARAM_MAP(vdev_param_non_agg_sw_retry_th, 732 VDEV_PARAM_NON_AGG_SW_RETRY_TH), 733 PARAM_MAP(vdev_param_set_cmd_obss_pd_threshold, 734 VDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD), 735 PARAM_MAP(vdev_param_set_profile, 736 VDEV_PARAM_SET_PROFILE), 737 PARAM_MAP(vdev_param_set_disabled_modes, 738 VDEV_PARAM_SET_DISABLED_SCHED_MODES), 739 PARAM_MAP(vdev_param_set_sap_ps_with_twt, 740 VDEV_PARAM_SET_SAP_PS_WITH_TWT), 741 PARAM_MAP(vdev_param_rtt_11az_tb_max_session_expiry, 742 VDEV_PARAM_RTT_11AZ_TB_MAX_SESSION_EXPIRY), 743 PARAM_MAP(vdev_param_wifi_standard_version, 744 VDEV_PARAM_WIFI_STANDARD_VERSION), 745 PARAM_MAP(vdev_param_rtt_11az_ntb_max_time_bw_meas, 746 VDEV_PARAM_RTT_11AZ_NTB_MAX_TIME_BW_MEAS), 747 PARAM_MAP(vdev_param_rtt_11az_ntb_min_time_bw_meas, 748 VDEV_PARAM_RTT_11AZ_NTB_MIN_TIME_BW_MEAS), 749 PARAM_MAP(vdev_param_11az_security_config, 750 VDEV_PARAM_11AZ_SECURITY_CONFIG), 751 PARAM_MAP(vdev_param_mlo_max_recom_active_links, 752 VDEV_PARAM_MLO_MAX_RECOM_ACTIVE_LINKS), 753 }; 754 #endif 755 756 #ifndef WMI_PKTLOG_EVENT_CBF 757 #define WMI_PKTLOG_EVENT_CBF 0x100 758 #endif 759 760 /* 761 * Populate the pktlog event tlv array, where 762 * the values are the FW WMI events, which host 763 * uses to communicate with FW for pktlog 764 */ 765 766 static const uint32_t pktlog_event_tlv[] = { 767 [WMI_HOST_PKTLOG_EVENT_RX_BIT] = WMI_PKTLOG_EVENT_RX, 768 [WMI_HOST_PKTLOG_EVENT_TX_BIT] = WMI_PKTLOG_EVENT_TX, 769 [WMI_HOST_PKTLOG_EVENT_RCF_BIT] = WMI_PKTLOG_EVENT_RCF, 770 [WMI_HOST_PKTLOG_EVENT_RCU_BIT] = WMI_PKTLOG_EVENT_RCU, 771 [WMI_HOST_PKTLOG_EVENT_DBG_PRINT_BIT] = 0, 772 [WMI_HOST_PKTLOG_EVENT_SMART_ANTENNA_BIT] = 773 WMI_PKTLOG_EVENT_SMART_ANTENNA, 774 [WMI_HOST_PKTLOG_EVENT_H_INFO_BIT] = 0, 775 [WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0, 776 [WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0, 777 [WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY, 778 [WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF, 779 #ifdef BE_PKTLOG_SUPPORT 780 [WMI_HOST_PKTLOG_EVENT_HYBRID_TX_BIT] = WMI_PKTLOG_EVENT_HYBRID_TX, 781 #endif 782 }; 783 784 /** 785 * convert_host_pdev_id_to_target_pdev_id() - Convert pdev_id from 786 * host to target defines. 787 * @wmi_handle: pointer to wmi_handle 788 * @pdev_id: host pdev_id to be converted. 789 * Return: target pdev_id after conversion. 790 */ 791 static uint32_t convert_host_pdev_id_to_target_pdev_id(wmi_unified_t wmi_handle, 792 uint32_t pdev_id) 793 { 794 if (pdev_id <= WMI_HOST_PDEV_ID_2 && pdev_id >= WMI_HOST_PDEV_ID_0) { 795 if (!wmi_handle->soc->is_pdev_is_map_enable) { 796 switch (pdev_id) { 797 case WMI_HOST_PDEV_ID_0: 798 return WMI_PDEV_ID_1ST; 799 case WMI_HOST_PDEV_ID_1: 800 return WMI_PDEV_ID_2ND; 801 case WMI_HOST_PDEV_ID_2: 802 return WMI_PDEV_ID_3RD; 803 } 804 } else { 805 return wmi_handle->cmd_pdev_id_map[pdev_id]; 806 } 807 } else { 808 return WMI_PDEV_ID_SOC; 809 } 810 811 QDF_ASSERT(0); 812 813 return WMI_PDEV_ID_SOC; 814 } 815 816 /** 817 * convert_target_pdev_id_to_host_pdev_id() - Convert pdev_id from 818 * target to host defines. 819 * @wmi_handle: pointer to wmi_handle 820 * @pdev_id: target pdev_id to be converted. 821 * Return: host pdev_id after conversion. 822 */ 823 static uint32_t convert_target_pdev_id_to_host_pdev_id(wmi_unified_t wmi_handle, 824 uint32_t pdev_id) 825 { 826 827 if (pdev_id <= WMI_PDEV_ID_3RD && pdev_id >= WMI_PDEV_ID_1ST) { 828 if (!wmi_handle->soc->is_pdev_is_map_enable) { 829 switch (pdev_id) { 830 case WMI_PDEV_ID_1ST: 831 return WMI_HOST_PDEV_ID_0; 832 case WMI_PDEV_ID_2ND: 833 return WMI_HOST_PDEV_ID_1; 834 case WMI_PDEV_ID_3RD: 835 return WMI_HOST_PDEV_ID_2; 836 } 837 } else { 838 return wmi_handle->evt_pdev_id_map[pdev_id - 1]; 839 } 840 } else if (pdev_id == WMI_PDEV_ID_SOC) { 841 return WMI_HOST_PDEV_ID_SOC; 842 } else { 843 wmi_err("Invalid pdev_id"); 844 } 845 846 return WMI_HOST_PDEV_ID_INVALID; 847 } 848 849 /** 850 * convert_host_phy_id_to_target_phy_id() - Convert phy_id from 851 * host to target defines. 852 * @wmi_handle: pointer to wmi_handle 853 * @phy_id: host pdev_id to be converted. 854 * Return: target phy_id after conversion. 855 */ 856 static uint32_t convert_host_phy_id_to_target_phy_id(wmi_unified_t wmi_handle, 857 uint32_t phy_id) 858 { 859 if (!wmi_handle->soc->is_phy_id_map_enable || 860 phy_id >= WMI_MAX_RADIOS) { 861 return phy_id; 862 } 863 864 return wmi_handle->cmd_phy_id_map[phy_id]; 865 } 866 867 /** 868 * convert_target_phy_id_to_host_phy_id() - Convert phy_id from 869 * target to host defines. 870 * @wmi_handle: pointer to wmi_handle 871 * @phy_id: target phy_id to be converted. 872 * Return: host phy_id after conversion. 873 */ 874 static uint32_t convert_target_phy_id_to_host_phy_id(wmi_unified_t wmi_handle, 875 uint32_t phy_id) 876 { 877 if (!wmi_handle->soc->is_phy_id_map_enable || 878 phy_id >= WMI_MAX_RADIOS) { 879 return phy_id; 880 } 881 882 return wmi_handle->evt_phy_id_map[phy_id]; 883 } 884 885 /** 886 * wmi_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion 887 * @wmi_handle: WMI handle 888 * @pdev_id_map: pointer to mapping table 889 * @size: number of entries in @pdev_id_map 890 * 891 * Return: None. 892 */ 893 static void wmi_tlv_pdev_id_conversion_enable(wmi_unified_t wmi_handle, 894 uint32_t *pdev_id_map, 895 uint8_t size) 896 { 897 int i = 0; 898 899 if (pdev_id_map && (size <= WMI_MAX_RADIOS)) { 900 for (i = 0; i < size; i++) { 901 wmi_handle->cmd_pdev_id_map[i] = pdev_id_map[i]; 902 wmi_handle->evt_pdev_id_map[i] = 903 WMI_HOST_PDEV_ID_INVALID; 904 wmi_handle->cmd_phy_id_map[i] = pdev_id_map[i] - 1; 905 wmi_handle->evt_phy_id_map[i] = 906 WMI_HOST_PDEV_ID_INVALID; 907 } 908 909 for (i = 0; i < size; i++) { 910 if (wmi_handle->cmd_pdev_id_map[i] != 911 WMI_HOST_PDEV_ID_INVALID) { 912 wmi_handle->evt_pdev_id_map 913 [wmi_handle->cmd_pdev_id_map[i] - 1] = i; 914 } 915 if (wmi_handle->cmd_phy_id_map[i] != 916 WMI_HOST_PDEV_ID_INVALID) { 917 wmi_handle->evt_phy_id_map 918 [wmi_handle->cmd_phy_id_map[i]] = i; 919 } 920 } 921 wmi_handle->soc->is_pdev_is_map_enable = true; 922 wmi_handle->soc->is_phy_id_map_enable = true; 923 } else { 924 wmi_handle->soc->is_pdev_is_map_enable = false; 925 wmi_handle->soc->is_phy_id_map_enable = false; 926 } 927 928 wmi_handle->ops->convert_pdev_id_host_to_target = 929 convert_host_pdev_id_to_target_pdev_id; 930 wmi_handle->ops->convert_pdev_id_target_to_host = 931 convert_target_pdev_id_to_host_pdev_id; 932 933 /* phy_id convert function assignments */ 934 wmi_handle->ops->convert_phy_id_host_to_target = 935 convert_host_phy_id_to_target_phy_id; 936 wmi_handle->ops->convert_phy_id_target_to_host = 937 convert_target_phy_id_to_host_phy_id; 938 } 939 940 /* copy_vdev_create_pdev_id() - copy pdev from host params to target command 941 * buffer. 942 * @wmi_handle: pointer to wmi_handle 943 * @cmd: pointer target vdev create command buffer 944 * @param: pointer host params for vdev create 945 * 946 * Return: None 947 */ 948 static inline void copy_vdev_create_pdev_id( 949 struct wmi_unified *wmi_handle, 950 wmi_vdev_create_cmd_fixed_param * cmd, 951 struct vdev_create_params *param) 952 { 953 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 954 wmi_handle, 955 param->pdev_id); 956 } 957 958 void wmi_mtrace(uint32_t message_id, uint16_t vdev_id, uint32_t data) 959 { 960 uint16_t mtrace_message_id; 961 962 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) | 963 (QDF_WMI_MTRACE_GRP_ID(message_id) << 964 QDF_WMI_MTRACE_CMD_NUM_BITS); 965 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_TARGET, 966 mtrace_message_id, vdev_id, data); 967 } 968 qdf_export_symbol(wmi_mtrace); 969 970 QDF_STATUS wmi_unified_cmd_send_pm_chk(struct wmi_unified *wmi_handle, 971 wmi_buf_t buf, 972 uint32_t buflen, uint32_t cmd_id, 973 bool is_qmi_send_support) 974 { 975 if (!is_qmi_send_support) 976 goto send_over_wmi; 977 978 if (!wmi_is_qmi_stats_enabled(wmi_handle)) 979 goto send_over_wmi; 980 981 if (wmi_is_target_suspended(wmi_handle)) { 982 if (QDF_IS_STATUS_SUCCESS( 983 wmi_unified_cmd_send_over_qmi(wmi_handle, buf, 984 buflen, cmd_id))) 985 return QDF_STATUS_SUCCESS; 986 } 987 988 send_over_wmi: 989 qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0); 990 991 return wmi_unified_cmd_send(wmi_handle, buf, buflen, cmd_id); 992 } 993 994 /** 995 * send_vdev_create_cmd_tlv() - send VDEV create command to fw 996 * @wmi_handle: wmi handle 997 * @param: pointer to hold vdev create parameter 998 * @macaddr: vdev mac address 999 * 1000 * Return: QDF_STATUS_SUCCESS for success or error code 1001 */ 1002 static QDF_STATUS send_vdev_create_cmd_tlv(wmi_unified_t wmi_handle, 1003 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 1004 struct vdev_create_params *param) 1005 { 1006 wmi_vdev_create_cmd_fixed_param *cmd; 1007 wmi_buf_t buf; 1008 int32_t len = sizeof(*cmd); 1009 QDF_STATUS ret; 1010 int num_bands = 2; 1011 uint8_t *buf_ptr; 1012 wmi_vdev_txrx_streams *txrx_streams; 1013 1014 len += (num_bands * sizeof(*txrx_streams) + WMI_TLV_HDR_SIZE); 1015 len += vdev_create_mlo_params_size(param); 1016 1017 buf = wmi_buf_alloc(wmi_handle, len); 1018 if (!buf) 1019 return QDF_STATUS_E_NOMEM; 1020 1021 cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); 1022 WMITLV_SET_HDR(&cmd->tlv_header, 1023 WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, 1024 WMITLV_GET_STRUCT_TLVLEN 1025 (wmi_vdev_create_cmd_fixed_param)); 1026 cmd->vdev_id = param->vdev_id; 1027 cmd->vdev_type = param->type; 1028 cmd->vdev_subtype = param->subtype; 1029 cmd->flags = param->mbssid_flags; 1030 cmd->flags |= (param->special_vdev_mode ? VDEV_FLAGS_SCAN_MODE_VAP : 0); 1031 cmd->vdevid_trans = param->vdevid_trans; 1032 cmd->num_cfg_txrx_streams = num_bands; 1033 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 1034 cmd->vdev_stats_id_valid = param->vdev_stats_id_valid; 1035 cmd->vdev_stats_id = param->vdev_stats_id; 1036 #endif 1037 copy_vdev_create_pdev_id(wmi_handle, cmd, param); 1038 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); 1039 wmi_debug("ID = %d[pdev:%d] VAP Addr = "QDF_MAC_ADDR_FMT, 1040 param->vdev_id, cmd->pdev_id, 1041 QDF_MAC_ADDR_REF(macaddr)); 1042 buf_ptr = (uint8_t *)cmd + sizeof(*cmd); 1043 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1044 (num_bands * sizeof(wmi_vdev_txrx_streams))); 1045 buf_ptr += WMI_TLV_HDR_SIZE; 1046 1047 wmi_debug("type %d, subtype %d, nss_2g %d, nss_5g %d", 1048 param->type, param->subtype, 1049 param->nss_2g, param->nss_5g); 1050 txrx_streams = (wmi_vdev_txrx_streams *)buf_ptr; 1051 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_2G; 1052 txrx_streams->supported_tx_streams = param->nss_2g; 1053 txrx_streams->supported_rx_streams = param->nss_2g; 1054 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1055 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1056 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1057 1058 txrx_streams++; 1059 txrx_streams->band = WMI_TPC_CHAINMASK_CONFIG_BAND_5G; 1060 txrx_streams->supported_tx_streams = param->nss_5g; 1061 txrx_streams->supported_rx_streams = param->nss_5g; 1062 WMITLV_SET_HDR(&txrx_streams->tlv_header, 1063 WMITLV_TAG_STRUC_wmi_vdev_txrx_streams, 1064 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_txrx_streams)); 1065 1066 buf_ptr += (num_bands * sizeof(wmi_vdev_txrx_streams)); 1067 buf_ptr = vdev_create_add_mlo_params(buf_ptr, param); 1068 1069 wmi_mtrace(WMI_VDEV_CREATE_CMDID, cmd->vdev_id, 0); 1070 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); 1071 if (QDF_IS_STATUS_ERROR(ret)) { 1072 wmi_err("Failed to send WMI_VDEV_CREATE_CMDID"); 1073 wmi_buf_free(buf); 1074 } 1075 1076 return ret; 1077 } 1078 1079 /** 1080 * send_vdev_delete_cmd_tlv() - send VDEV delete command to fw 1081 * @wmi_handle: wmi handle 1082 * @if_id: vdev id 1083 * 1084 * Return: QDF_STATUS_SUCCESS for success or error code 1085 */ 1086 static QDF_STATUS send_vdev_delete_cmd_tlv(wmi_unified_t wmi_handle, 1087 uint8_t if_id) 1088 { 1089 wmi_vdev_delete_cmd_fixed_param *cmd; 1090 wmi_buf_t buf; 1091 QDF_STATUS ret; 1092 1093 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1094 if (!buf) 1095 return QDF_STATUS_E_NOMEM; 1096 1097 cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); 1098 WMITLV_SET_HDR(&cmd->tlv_header, 1099 WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, 1100 WMITLV_GET_STRUCT_TLVLEN 1101 (wmi_vdev_delete_cmd_fixed_param)); 1102 cmd->vdev_id = if_id; 1103 wmi_mtrace(WMI_VDEV_DELETE_CMDID, cmd->vdev_id, 0); 1104 ret = wmi_unified_cmd_send(wmi_handle, buf, 1105 sizeof(wmi_vdev_delete_cmd_fixed_param), 1106 WMI_VDEV_DELETE_CMDID); 1107 if (QDF_IS_STATUS_ERROR(ret)) { 1108 wmi_err("Failed to send WMI_VDEV_DELETE_CMDID"); 1109 wmi_buf_free(buf); 1110 } 1111 wmi_debug("vdev id = %d", if_id); 1112 1113 return ret; 1114 } 1115 1116 /** 1117 * send_vdev_nss_chain_params_cmd_tlv() - send VDEV nss chain params to fw 1118 * @wmi_handle: wmi handle 1119 * @vdev_id: vdev id 1120 * @user_cfg: user configured nss chain params 1121 * 1122 * Return: QDF_STATUS_SUCCESS for success or error code 1123 */ 1124 static QDF_STATUS 1125 send_vdev_nss_chain_params_cmd_tlv(wmi_unified_t wmi_handle, 1126 uint8_t vdev_id, 1127 struct vdev_nss_chains *user_cfg) 1128 { 1129 wmi_vdev_chainmask_config_cmd_fixed_param *cmd; 1130 wmi_buf_t buf; 1131 QDF_STATUS ret; 1132 1133 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 1134 if (!buf) 1135 return QDF_STATUS_E_NOMEM; 1136 1137 cmd = (wmi_vdev_chainmask_config_cmd_fixed_param *)wmi_buf_data(buf); 1138 WMITLV_SET_HDR(&cmd->tlv_header, 1139 WMITLV_TAG_STRUC_wmi_vdev_chainmask_config_cmd_fixed_param, 1140 WMITLV_GET_STRUCT_TLVLEN 1141 (wmi_vdev_chainmask_config_cmd_fixed_param)); 1142 cmd->vdev_id = vdev_id; 1143 cmd->disable_rx_mrc_2g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ]; 1144 cmd->disable_tx_mrc_2g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ]; 1145 cmd->disable_rx_mrc_5g = user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ]; 1146 cmd->disable_tx_mrc_5g = user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ]; 1147 cmd->num_rx_chains_2g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ]; 1148 cmd->num_tx_chains_2g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 1149 cmd->num_rx_chains_5g = user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]; 1150 cmd->num_tx_chains_5g = user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 1151 cmd->rx_nss_2g = user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; 1152 cmd->tx_nss_2g = user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; 1153 cmd->rx_nss_5g = user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; 1154 cmd->tx_nss_5g = user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; 1155 cmd->num_tx_chains_a = user_cfg->num_tx_chains_11a; 1156 cmd->num_tx_chains_b = user_cfg->num_tx_chains_11b; 1157 cmd->num_tx_chains_g = user_cfg->num_tx_chains_11g; 1158 1159 wmi_mtrace(WMI_VDEV_CHAINMASK_CONFIG_CMDID, cmd->vdev_id, 0); 1160 ret = wmi_unified_cmd_send(wmi_handle, buf, 1161 sizeof(wmi_vdev_chainmask_config_cmd_fixed_param), 1162 WMI_VDEV_CHAINMASK_CONFIG_CMDID); 1163 if (QDF_IS_STATUS_ERROR(ret)) { 1164 wmi_err("Failed to send WMI_VDEV_CHAINMASK_CONFIG_CMDID"); 1165 wmi_buf_free(buf); 1166 } 1167 wmi_debug("vdev_id %d", vdev_id); 1168 1169 return ret; 1170 } 1171 1172 /** 1173 * send_vdev_stop_cmd_tlv() - send vdev stop command to fw 1174 * @wmi: wmi handle 1175 * @params: VDEV stop params 1176 * 1177 * Return: QDF_STATUS_SUCCESS for success or error code 1178 */ 1179 static QDF_STATUS send_vdev_stop_cmd_tlv(wmi_unified_t wmi, 1180 struct vdev_stop_params *params) 1181 { 1182 wmi_vdev_stop_cmd_fixed_param *cmd; 1183 wmi_buf_t buf; 1184 int32_t len = sizeof(*cmd); 1185 uint8_t *buf_ptr; 1186 1187 len += vdev_stop_mlo_params_size(params); 1188 1189 buf = wmi_buf_alloc(wmi, len); 1190 if (!buf) 1191 return QDF_STATUS_E_NOMEM; 1192 1193 buf_ptr = wmi_buf_data(buf); 1194 cmd = (wmi_vdev_stop_cmd_fixed_param *)buf_ptr; 1195 WMITLV_SET_HDR(&cmd->tlv_header, 1196 WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, 1197 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); 1198 cmd->vdev_id = params->vdev_id; 1199 buf_ptr += sizeof(wmi_vdev_stop_cmd_fixed_param); 1200 buf_ptr = vdev_stop_add_mlo_params(buf_ptr, params); 1201 1202 wmi_mtrace(WMI_VDEV_STOP_CMDID, cmd->vdev_id, 0); 1203 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { 1204 wmi_err("Failed to send vdev stop command"); 1205 wmi_buf_free(buf); 1206 return QDF_STATUS_E_FAILURE; 1207 } 1208 wmi_debug("vdev id = %d", cmd->vdev_id); 1209 1210 return 0; 1211 } 1212 1213 /** 1214 * send_vdev_down_cmd_tlv() - send vdev down command to fw 1215 * @wmi: wmi handle 1216 * @vdev_id: vdev id 1217 * 1218 * Return: QDF_STATUS_SUCCESS for success or error code 1219 */ 1220 static QDF_STATUS send_vdev_down_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 1221 { 1222 wmi_vdev_down_cmd_fixed_param *cmd; 1223 wmi_buf_t buf; 1224 int32_t len = sizeof(*cmd); 1225 1226 buf = wmi_buf_alloc(wmi, len); 1227 if (!buf) 1228 return QDF_STATUS_E_NOMEM; 1229 1230 cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); 1231 WMITLV_SET_HDR(&cmd->tlv_header, 1232 WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, 1233 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); 1234 cmd->vdev_id = vdev_id; 1235 wmi_mtrace(WMI_VDEV_DOWN_CMDID, cmd->vdev_id, 0); 1236 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { 1237 wmi_err("Failed to send vdev down"); 1238 wmi_buf_free(buf); 1239 return QDF_STATUS_E_FAILURE; 1240 } 1241 wmi_debug("vdev_id %d", vdev_id); 1242 1243 return 0; 1244 } 1245 1246 static inline void copy_channel_info( 1247 wmi_vdev_start_request_cmd_fixed_param * cmd, 1248 wmi_channel *chan, 1249 struct vdev_start_params *req) 1250 { 1251 chan->mhz = req->channel.mhz; 1252 1253 WMI_SET_CHANNEL_MODE(chan, req->channel.phy_mode); 1254 1255 chan->band_center_freq1 = req->channel.cfreq1; 1256 chan->band_center_freq2 = req->channel.cfreq2; 1257 1258 if (req->channel.half_rate) 1259 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE); 1260 else if (req->channel.quarter_rate) 1261 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE); 1262 1263 if (req->channel.dfs_set) { 1264 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); 1265 cmd->disable_hw_ack = req->disable_hw_ack; 1266 } 1267 1268 if (req->channel.dfs_set_cfreq2) 1269 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS_CFREQ2); 1270 1271 if (req->channel.is_stadfs_en) 1272 WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_STA_DFS); 1273 1274 /* According to firmware both reg power and max tx power 1275 * on set channel power is used and set it to max reg 1276 * power from regulatory. 1277 */ 1278 WMI_SET_CHANNEL_MIN_POWER(chan, req->channel.minpower); 1279 WMI_SET_CHANNEL_MAX_POWER(chan, req->channel.maxpower); 1280 WMI_SET_CHANNEL_REG_POWER(chan, req->channel.maxregpower); 1281 WMI_SET_CHANNEL_ANTENNA_MAX(chan, req->channel.antennamax); 1282 WMI_SET_CHANNEL_REG_CLASSID(chan, req->channel.reg_class_id); 1283 WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->channel.maxregpower); 1284 1285 } 1286 1287 /** 1288 * vdev_start_cmd_fill_11be() - 11be information filling in vdev_start 1289 * @cmd: wmi cmd 1290 * @req: vdev start params 1291 * 1292 * Return: QDF status 1293 */ 1294 #ifdef WLAN_FEATURE_11BE 1295 static void 1296 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1297 struct vdev_start_params *req) 1298 { 1299 cmd->eht_ops = req->eht_ops; 1300 cmd->puncture_20mhz_bitmap = ~req->channel.puncture_bitmap; 1301 wmi_info("EHT ops: %x puncture_bitmap %x wmi cmd puncture bitmap %x", 1302 req->eht_ops, req->channel.puncture_bitmap, 1303 cmd->puncture_20mhz_bitmap); 1304 } 1305 #else 1306 static void 1307 vdev_start_cmd_fill_11be(wmi_vdev_start_request_cmd_fixed_param *cmd, 1308 struct vdev_start_params *req) 1309 { 1310 } 1311 #endif 1312 1313 /** 1314 * send_vdev_start_cmd_tlv() - send vdev start request to fw 1315 * @wmi_handle: wmi handle 1316 * @req: vdev start params 1317 * 1318 * Return: QDF status 1319 */ 1320 static QDF_STATUS send_vdev_start_cmd_tlv(wmi_unified_t wmi_handle, 1321 struct vdev_start_params *req) 1322 { 1323 wmi_vdev_start_request_cmd_fixed_param *cmd; 1324 wmi_buf_t buf; 1325 wmi_channel *chan; 1326 int32_t len, ret; 1327 uint8_t *buf_ptr; 1328 1329 len = sizeof(*cmd) + sizeof(wmi_channel) + WMI_TLV_HDR_SIZE; 1330 if (!req->is_restart) 1331 len += vdev_start_mlo_params_size(req); 1332 buf = wmi_buf_alloc(wmi_handle, len); 1333 if (!buf) 1334 return QDF_STATUS_E_NOMEM; 1335 1336 buf_ptr = (uint8_t *) wmi_buf_data(buf); 1337 cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; 1338 chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); 1339 WMITLV_SET_HDR(&cmd->tlv_header, 1340 WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, 1341 WMITLV_GET_STRUCT_TLVLEN 1342 (wmi_vdev_start_request_cmd_fixed_param)); 1343 WMITLV_SET_HDR(&chan->tlv_header, WMITLV_TAG_STRUC_wmi_channel, 1344 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 1345 cmd->vdev_id = req->vdev_id; 1346 1347 /* Fill channel info */ 1348 copy_channel_info(cmd, chan, req); 1349 cmd->beacon_interval = req->beacon_interval; 1350 cmd->dtim_period = req->dtim_period; 1351 1352 cmd->bcn_tx_rate = req->bcn_tx_rate_code; 1353 if (req->bcn_tx_rate_code) 1354 wmi_enable_bcn_ratecode(&cmd->flags); 1355 1356 if (!req->is_restart) { 1357 if (req->pmf_enabled) 1358 cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; 1359 1360 cmd->mbss_capability_flags = req->mbssid_flags; 1361 cmd->vdevid_trans = req->vdevid_trans; 1362 cmd->mbssid_multi_group_flag = req->mbssid_multi_group_flag; 1363 cmd->mbssid_multi_group_id = req->mbssid_multi_group_id; 1364 } 1365 1366 /* Copy the SSID */ 1367 if (req->ssid.length) { 1368 if (req->ssid.length < sizeof(cmd->ssid.ssid)) 1369 cmd->ssid.ssid_len = req->ssid.length; 1370 else 1371 cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); 1372 qdf_mem_copy(cmd->ssid.ssid, req->ssid.ssid, 1373 cmd->ssid.ssid_len); 1374 } 1375 1376 if (req->hidden_ssid) 1377 cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; 1378 1379 cmd->flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED; 1380 cmd->num_noa_descriptors = req->num_noa_descriptors; 1381 cmd->preferred_rx_streams = req->preferred_rx_streams; 1382 cmd->preferred_tx_streams = req->preferred_tx_streams; 1383 cmd->cac_duration_ms = req->cac_duration_ms; 1384 cmd->regdomain = req->regdomain; 1385 cmd->he_ops = req->he_ops; 1386 1387 buf_ptr = (uint8_t *) (((uintptr_t) cmd) + sizeof(*cmd) + 1388 sizeof(wmi_channel)); 1389 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 1390 cmd->num_noa_descriptors * 1391 sizeof(wmi_p2p_noa_descriptor)); 1392 if (!req->is_restart) { 1393 buf_ptr += WMI_TLV_HDR_SIZE + 1394 (cmd->num_noa_descriptors * sizeof(wmi_p2p_noa_descriptor)); 1395 1396 buf_ptr = vdev_start_add_mlo_params(buf_ptr, req); 1397 buf_ptr = vdev_start_add_ml_partner_links(buf_ptr, req); 1398 } 1399 wmi_info("vdev_id %d freq %d chanmode %d ch_info: 0x%x is_dfs %d " 1400 "beacon interval %d dtim %d center_chan %d center_freq2 %d " 1401 "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x " 1402 "Tx SS %d, Rx SS %d, ldpc_rx: %d, cac %d, regd %d, HE ops: %d" 1403 "req->dis_hw_ack: %d ", req->vdev_id, 1404 chan->mhz, req->channel.phy_mode, chan->info, 1405 req->channel.dfs_set, req->beacon_interval, cmd->dtim_period, 1406 chan->band_center_freq1, chan->band_center_freq2, 1407 chan->reg_info_1, chan->reg_info_2, req->channel.maxregpower, 1408 req->preferred_tx_streams, req->preferred_rx_streams, 1409 req->ldpc_rx_enabled, req->cac_duration_ms, 1410 req->regdomain, req->he_ops, 1411 req->disable_hw_ack); 1412 1413 vdev_start_cmd_fill_11be(cmd, req); 1414 1415 if (req->is_restart) { 1416 wmi_mtrace(WMI_VDEV_RESTART_REQUEST_CMDID, cmd->vdev_id, 0); 1417 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1418 WMI_VDEV_RESTART_REQUEST_CMDID); 1419 } else { 1420 wmi_mtrace(WMI_VDEV_START_REQUEST_CMDID, cmd->vdev_id, 0); 1421 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 1422 WMI_VDEV_START_REQUEST_CMDID); 1423 } 1424 if (ret) { 1425 wmi_err("Failed to send vdev start command"); 1426 wmi_buf_free(buf); 1427 return QDF_STATUS_E_FAILURE; 1428 } 1429 1430 return QDF_STATUS_SUCCESS; 1431 } 1432 1433 /** 1434 * send_peer_flush_tids_cmd_tlv() - flush peer tids packets in fw 1435 * @wmi: wmi handle 1436 * @peer_addr: peer mac address 1437 * @param: pointer to hold peer flush tid parameter 1438 * 1439 * Return: QDF_STATUS_SUCCESS for success or error code 1440 */ 1441 static QDF_STATUS send_peer_flush_tids_cmd_tlv(wmi_unified_t wmi, 1442 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1443 struct peer_flush_params *param) 1444 { 1445 wmi_peer_flush_tids_cmd_fixed_param *cmd; 1446 wmi_buf_t buf; 1447 int32_t len = sizeof(*cmd); 1448 1449 buf = wmi_buf_alloc(wmi, len); 1450 if (!buf) 1451 return QDF_STATUS_E_NOMEM; 1452 1453 cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); 1454 WMITLV_SET_HDR(&cmd->tlv_header, 1455 WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, 1456 WMITLV_GET_STRUCT_TLVLEN 1457 (wmi_peer_flush_tids_cmd_fixed_param)); 1458 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1459 cmd->peer_tid_bitmap = param->peer_tid_bitmap; 1460 cmd->vdev_id = param->vdev_id; 1461 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d and peer bitmap %d", 1462 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id, 1463 param->peer_tid_bitmap); 1464 wmi_mtrace(WMI_PEER_FLUSH_TIDS_CMDID, cmd->vdev_id, 0); 1465 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { 1466 wmi_err("Failed to send flush tid command"); 1467 wmi_buf_free(buf); 1468 return QDF_STATUS_E_FAILURE; 1469 } 1470 1471 return 0; 1472 } 1473 1474 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 1475 /** 1476 * map_to_wmi_flush_policy() - Map flush policy to firmware defined values 1477 * @policy: The target i/f flush policy value 1478 * 1479 * Return: WMI layer flush policy 1480 */ 1481 static wmi_peer_flush_policy 1482 map_to_wmi_flush_policy(enum peer_txq_flush_policy policy) 1483 { 1484 switch (policy) { 1485 case PEER_TXQ_FLUSH_POLICY_NONE: 1486 return WMI_NO_FLUSH; 1487 case PEER_TXQ_FLUSH_POLICY_TWT_SP_END: 1488 return WMI_TWT_FLUSH; 1489 default: 1490 return WMI_MAX_FLUSH_POLICY; 1491 } 1492 } 1493 1494 /** 1495 * send_peer_txq_flush_config_cmd_tlv() - Send peer TID queue flush config 1496 * @wmi: wmi handle 1497 * @param: Peer txq flush configuration 1498 * 1499 * Return: QDF_STATUS_SUCCESS for success or error code 1500 */ 1501 static QDF_STATUS 1502 send_peer_txq_flush_config_cmd_tlv(wmi_unified_t wmi, 1503 struct peer_txq_flush_config_params *param) 1504 { 1505 wmi_peer_flush_policy_cmd_fixed_param *cmd; 1506 wmi_buf_t buf; 1507 int32_t len = sizeof(*cmd); 1508 1509 buf = wmi_buf_alloc(wmi, len); 1510 if (!buf) 1511 return QDF_STATUS_E_NOMEM; 1512 1513 cmd = (wmi_peer_flush_policy_cmd_fixed_param *)wmi_buf_data(buf); 1514 1515 WMITLV_SET_HDR(&cmd->tlv_header, 1516 WMITLV_TAG_STRUC_wmi_peer_flush_policy_cmd_fixed_param, 1517 WMITLV_GET_STRUCT_TLVLEN 1518 (wmi_peer_flush_policy_cmd_fixed_param)); 1519 1520 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer, &cmd->peer_macaddr); 1521 cmd->peer_tid_bitmap = param->tid_mask; 1522 cmd->vdev_id = param->vdev_id; 1523 cmd->flush_policy = map_to_wmi_flush_policy(param->policy); 1524 if (cmd->flush_policy == WMI_MAX_FLUSH_POLICY) { 1525 wmi_buf_free(buf); 1526 wmi_err("Invalid policy"); 1527 return QDF_STATUS_E_INVAL; 1528 } 1529 wmi_debug("peer_addr " QDF_MAC_ADDR_FMT "vdev %d tid %x policy %d", 1530 QDF_MAC_ADDR_REF(param->peer), param->vdev_id, 1531 param->tid_mask, param->policy); 1532 wmi_mtrace(WMI_PEER_FLUSH_POLICY_CMDID, cmd->vdev_id, 0); 1533 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_POLICY_CMDID)) { 1534 wmi_err("Failed to send flush policy command"); 1535 wmi_buf_free(buf); 1536 return QDF_STATUS_E_FAILURE; 1537 } 1538 1539 return QDF_STATUS_SUCCESS; 1540 } 1541 #endif 1542 /** 1543 * send_peer_delete_cmd_tlv() - send PEER delete command to fw 1544 * @wmi: wmi handle 1545 * @peer_addr: peer mac addr 1546 * @param: peer delete parameters 1547 * 1548 * Return: QDF_STATUS_SUCCESS for success or error code 1549 */ 1550 static QDF_STATUS send_peer_delete_cmd_tlv(wmi_unified_t wmi, 1551 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1552 struct peer_delete_cmd_params *param) 1553 { 1554 wmi_peer_delete_cmd_fixed_param *cmd; 1555 wmi_buf_t buf; 1556 int32_t len = sizeof(*cmd); 1557 uint8_t *buf_ptr; 1558 1559 len += peer_delete_mlo_params_size(param); 1560 buf = wmi_buf_alloc(wmi, len); 1561 if (!buf) 1562 return QDF_STATUS_E_NOMEM; 1563 1564 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1565 cmd = (wmi_peer_delete_cmd_fixed_param *)buf_ptr; 1566 WMITLV_SET_HDR(&cmd->tlv_header, 1567 WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, 1568 WMITLV_GET_STRUCT_TLVLEN 1569 (wmi_peer_delete_cmd_fixed_param)); 1570 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1571 cmd->vdev_id = param->vdev_id; 1572 buf_ptr = (uint8_t *)(((uintptr_t) cmd) + sizeof(*cmd)); 1573 buf_ptr = peer_delete_add_mlo_params(buf_ptr, param); 1574 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1575 QDF_MAC_ADDR_REF(peer_addr), param->vdev_id); 1576 wmi_mtrace(WMI_PEER_DELETE_CMDID, cmd->vdev_id, 0); 1577 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { 1578 wmi_err("Failed to send peer delete command"); 1579 wmi_buf_free(buf); 1580 return QDF_STATUS_E_FAILURE; 1581 } 1582 return 0; 1583 } 1584 1585 static void 1586 wmi_get_converted_peer_bitmap(uint32_t src_peer_bitmap, uint32_t *dst_bitmap) 1587 { 1588 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_SELF)) 1589 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1590 WMI_PEER_TYPE_DEFAULT); 1591 1592 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_AP)) 1593 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1594 WMI_PEER_TYPE_BSS); 1595 1596 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_TDLS)) 1597 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1598 WMI_PEER_TYPE_TDLS); 1599 1600 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_NDP)) 1601 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1602 WMI_PEER_TYPE_NAN_DATA); 1603 1604 if (QDF_HAS_PARAM(src_peer_bitmap, WLAN_PEER_RTT_PASN)) 1605 WMI_VDEV_DELETE_ALL_PEER_BITMAP_SET(dst_bitmap, 1606 WMI_PEER_TYPE_PASN); 1607 } 1608 1609 /** 1610 * send_peer_delete_all_cmd_tlv() - send PEER delete all command to fw 1611 * @wmi: wmi handle 1612 * @param: pointer to hold peer delete all parameter 1613 * 1614 * Return: QDF_STATUS_SUCCESS for success or error code 1615 */ 1616 static QDF_STATUS send_peer_delete_all_cmd_tlv( 1617 wmi_unified_t wmi, 1618 struct peer_delete_all_params *param) 1619 { 1620 wmi_vdev_delete_all_peer_cmd_fixed_param *cmd; 1621 wmi_buf_t buf; 1622 int32_t len = sizeof(*cmd); 1623 1624 buf = wmi_buf_alloc(wmi, len); 1625 if (!buf) 1626 return QDF_STATUS_E_NOMEM; 1627 1628 cmd = (wmi_vdev_delete_all_peer_cmd_fixed_param *)wmi_buf_data(buf); 1629 WMITLV_SET_HDR( 1630 &cmd->tlv_header, 1631 WMITLV_TAG_STRUC_wmi_vdev_delete_all_peer_cmd_fixed_param, 1632 WMITLV_GET_STRUCT_TLVLEN 1633 (wmi_vdev_delete_all_peer_cmd_fixed_param)); 1634 cmd->vdev_id = param->vdev_id; 1635 wmi_get_converted_peer_bitmap(param->peer_type_bitmap, 1636 cmd->peer_type_bitmap); 1637 1638 wmi_debug("vdev_id %d peer_type_bitmap:%d", cmd->vdev_id, 1639 param->peer_type_bitmap); 1640 wmi_mtrace(WMI_VDEV_DELETE_ALL_PEER_CMDID, cmd->vdev_id, 0); 1641 if (wmi_unified_cmd_send(wmi, buf, len, 1642 WMI_VDEV_DELETE_ALL_PEER_CMDID)) { 1643 wmi_err("Failed to send peer del all command"); 1644 wmi_buf_free(buf); 1645 return QDF_STATUS_E_FAILURE; 1646 } 1647 1648 return QDF_STATUS_SUCCESS; 1649 } 1650 1651 /** 1652 * convert_host_peer_param_id_to_target_id_tlv - convert host peer param_id 1653 * to target id. 1654 * @peer_param_id: host param id. 1655 * 1656 * Return: Target param id. 1657 */ 1658 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1659 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1660 uint32_t peer_param_id) 1661 { 1662 if (peer_param_id < QDF_ARRAY_SIZE(peer_param_tlv)) 1663 return peer_param_tlv[peer_param_id]; 1664 return WMI_UNAVAILABLE_PARAM; 1665 } 1666 #else 1667 static inline uint32_t convert_host_peer_param_id_to_target_id_tlv( 1668 uint32_t peer_param_id) 1669 { 1670 return peer_param_id; 1671 } 1672 #endif 1673 1674 /** 1675 * wmi_host_chan_bw_to_target_chan_bw - convert wmi_host_channel_width to 1676 * wmi_channel_width 1677 * @bw: wmi_host_channel_width channel width 1678 * 1679 * Return: wmi_channel_width 1680 */ 1681 static wmi_channel_width wmi_host_chan_bw_to_target_chan_bw( 1682 wmi_host_channel_width bw) 1683 { 1684 wmi_channel_width target_bw = WMI_CHAN_WIDTH_20; 1685 1686 switch (bw) { 1687 case WMI_HOST_CHAN_WIDTH_20: 1688 target_bw = WMI_CHAN_WIDTH_20; 1689 break; 1690 case WMI_HOST_CHAN_WIDTH_40: 1691 target_bw = WMI_CHAN_WIDTH_40; 1692 break; 1693 case WMI_HOST_CHAN_WIDTH_80: 1694 target_bw = WMI_CHAN_WIDTH_80; 1695 break; 1696 case WMI_HOST_CHAN_WIDTH_160: 1697 target_bw = WMI_CHAN_WIDTH_160; 1698 break; 1699 case WMI_HOST_CHAN_WIDTH_80P80: 1700 target_bw = WMI_CHAN_WIDTH_80P80; 1701 break; 1702 case WMI_HOST_CHAN_WIDTH_5: 1703 target_bw = WMI_CHAN_WIDTH_5; 1704 break; 1705 case WMI_HOST_CHAN_WIDTH_10: 1706 target_bw = WMI_CHAN_WIDTH_10; 1707 break; 1708 case WMI_HOST_CHAN_WIDTH_165: 1709 target_bw = WMI_CHAN_WIDTH_165; 1710 break; 1711 case WMI_HOST_CHAN_WIDTH_160P160: 1712 target_bw = WMI_CHAN_WIDTH_160P160; 1713 break; 1714 case WMI_HOST_CHAN_WIDTH_320: 1715 target_bw = WMI_CHAN_WIDTH_320; 1716 break; 1717 default: 1718 break; 1719 } 1720 1721 return target_bw; 1722 } 1723 1724 /** 1725 * convert_host_peer_param_value_to_target_value_tlv() - convert host peer 1726 * param value to target 1727 * @param_id: target param id 1728 * @param_value: host param value 1729 * 1730 * Return: target param value 1731 */ 1732 static uint32_t convert_host_peer_param_value_to_target_value_tlv( 1733 uint32_t param_id, uint32_t param_value) 1734 { 1735 uint32_t fw_param_value = 0; 1736 wmi_host_channel_width bw; 1737 uint16_t punc; 1738 1739 switch (param_id) { 1740 case WMI_PEER_CHWIDTH_PUNCTURE_20MHZ_BITMAP: 1741 bw = QDF_GET_BITS(param_value, 0, 8); 1742 punc = QDF_GET_BITS(param_value, 8, 16); 1743 QDF_SET_BITS(fw_param_value, 0, 8, 1744 wmi_host_chan_bw_to_target_chan_bw(bw)); 1745 QDF_SET_BITS(fw_param_value, 8, 16, ~punc); 1746 break; 1747 default: 1748 fw_param_value = param_value; 1749 break; 1750 } 1751 1752 return fw_param_value; 1753 } 1754 1755 #ifdef WLAN_SUPPORT_PPEDS 1756 /** 1757 * peer_ppe_ds_param_send_tlv() - Set peer PPE DS config 1758 * @wmi: wmi handle 1759 * @param: pointer to hold PPE DS config 1760 * 1761 * Return: QDF_STATUS_SUCCESS for success or error code 1762 */ 1763 static QDF_STATUS peer_ppe_ds_param_send_tlv(wmi_unified_t wmi, 1764 struct peer_ppe_ds_param *param) 1765 { 1766 wmi_peer_config_ppe_ds_cmd_fixed_param *cmd; 1767 wmi_buf_t buf; 1768 int32_t err; 1769 uint32_t len = sizeof(wmi_peer_config_ppe_ds_cmd_fixed_param); 1770 1771 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1772 if (!buf) 1773 return QDF_STATUS_E_NOMEM; 1774 1775 cmd = (wmi_peer_config_ppe_ds_cmd_fixed_param *)wmi_buf_data(buf); 1776 WMITLV_SET_HDR(&cmd->tlv_header, 1777 WMITLV_TAG_STRUC_wmi_peer_config_ppe_ds_cmd_fixed_param, 1778 WMITLV_GET_STRUCT_TLVLEN 1779 (wmi_peer_config_ppe_ds_cmd_fixed_param)); 1780 1781 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 1782 1783 if (param->ppe_routing_enabled) 1784 cmd->ppe_routing_enable = param->use_ppe ? 1785 WMI_AST_USE_PPE_ENABLED : WMI_AST_USE_PPE_DISABLED; 1786 else 1787 cmd->ppe_routing_enable = WMI_PPE_ROUTING_DISABLED; 1788 1789 cmd->service_code = param->service_code; 1790 cmd->priority_valid = param->priority_valid; 1791 cmd->src_info = param->src_info; 1792 cmd->vdev_id = param->vdev_id; 1793 1794 wmi_debug("vdev_id %d peer_mac: QDF_MAC_ADDR_FMT\n" 1795 "ppe_routing_enable: %u service_code: %u\n" 1796 "priority_valid:%d src_info:%u", 1797 param->vdev_id, 1798 QDF_MAC_ADDR_REF(param->peer_macaddr), 1799 param->ppe_routing_enabled, 1800 param->service_code, 1801 param->priority_valid, 1802 param->src_info); 1803 1804 wmi_mtrace(WMI_PEER_CONFIG_PPE_DS_CMDID, cmd->vdev_id, 0); 1805 err = wmi_unified_cmd_send(wmi, buf, 1806 len, 1807 WMI_PEER_CONFIG_PPE_DS_CMDID); 1808 if (err) { 1809 wmi_err("Failed to send ppeds config cmd"); 1810 wmi_buf_free(buf); 1811 return QDF_STATUS_E_FAILURE; 1812 } 1813 1814 return 0; 1815 } 1816 #endif /* WLAN_SUPPORT_PPEDS */ 1817 1818 /** 1819 * send_peer_param_cmd_tlv() - set peer parameter in fw 1820 * @wmi: wmi handle 1821 * @peer_addr: peer mac address 1822 * @param: pointer to hold peer set parameter 1823 * 1824 * Return: QDF_STATUS_SUCCESS for success or error code 1825 */ 1826 static QDF_STATUS send_peer_param_cmd_tlv(wmi_unified_t wmi, 1827 uint8_t peer_addr[QDF_MAC_ADDR_SIZE], 1828 struct peer_set_params *param) 1829 { 1830 wmi_peer_set_param_cmd_fixed_param *cmd; 1831 wmi_buf_t buf; 1832 int32_t err; 1833 uint32_t param_id; 1834 uint32_t param_value; 1835 1836 param_id = convert_host_peer_param_id_to_target_id_tlv(param->param_id); 1837 if (param_id == WMI_UNAVAILABLE_PARAM) { 1838 wmi_err("Unavailable param %d", param->param_id); 1839 return QDF_STATUS_E_NOSUPPORT; 1840 } 1841 param_value = convert_host_peer_param_value_to_target_value_tlv( 1842 param_id, param->param_value); 1843 buf = wmi_buf_alloc(wmi, sizeof(*cmd)); 1844 if (!buf) 1845 return QDF_STATUS_E_NOMEM; 1846 1847 cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); 1848 WMITLV_SET_HDR(&cmd->tlv_header, 1849 WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, 1850 WMITLV_GET_STRUCT_TLVLEN 1851 (wmi_peer_set_param_cmd_fixed_param)); 1852 cmd->vdev_id = param->vdev_id; 1853 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 1854 cmd->param_id = param_id; 1855 cmd->param_value = param_value; 1856 1857 wmi_debug("vdev_id %d peer_mac: "QDF_MAC_ADDR_FMT" param_id: %u param_value: %x", 1858 cmd->vdev_id, 1859 QDF_MAC_ADDR_REF(peer_addr), param->param_id, 1860 cmd->param_value); 1861 1862 wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, cmd->vdev_id, 0); 1863 err = wmi_unified_cmd_send(wmi, buf, 1864 sizeof(wmi_peer_set_param_cmd_fixed_param), 1865 WMI_PEER_SET_PARAM_CMDID); 1866 if (err) { 1867 wmi_err("Failed to send set_param cmd"); 1868 wmi_buf_free(buf); 1869 return QDF_STATUS_E_FAILURE; 1870 } 1871 1872 return 0; 1873 } 1874 1875 /** 1876 * send_vdev_up_cmd_tlv() - send vdev up command in fw 1877 * @wmi: wmi handle 1878 * @bssid: bssid 1879 * @params: pointer to hold vdev up parameter 1880 * 1881 * Return: QDF_STATUS_SUCCESS for success or error code 1882 */ 1883 static QDF_STATUS send_vdev_up_cmd_tlv(wmi_unified_t wmi, 1884 uint8_t bssid[QDF_MAC_ADDR_SIZE], 1885 struct vdev_up_params *params) 1886 { 1887 wmi_vdev_up_cmd_fixed_param *cmd; 1888 wmi_buf_t buf; 1889 int32_t len = sizeof(*cmd); 1890 1891 wmi_debug("VDEV_UP"); 1892 wmi_debug("vdev_id %d aid %d profile idx %d count %d bssid " 1893 QDF_MAC_ADDR_FMT " trans bssid " QDF_MAC_ADDR_FMT, 1894 params->vdev_id, params->assoc_id, 1895 params->profile_idx, params->profile_num, 1896 QDF_MAC_ADDR_REF(bssid), QDF_MAC_ADDR_REF(params->trans_bssid)); 1897 buf = wmi_buf_alloc(wmi, len); 1898 if (!buf) 1899 return QDF_STATUS_E_NOMEM; 1900 1901 cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); 1902 WMITLV_SET_HDR(&cmd->tlv_header, 1903 WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, 1904 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); 1905 cmd->vdev_id = params->vdev_id; 1906 cmd->vdev_assoc_id = params->assoc_id; 1907 cmd->profile_idx = params->profile_idx; 1908 cmd->profile_num = params->profile_num; 1909 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->trans_bssid, &cmd->trans_bssid); 1910 WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); 1911 wmi_mtrace(WMI_VDEV_UP_CMDID, cmd->vdev_id, 0); 1912 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { 1913 wmi_err("Failed to send vdev up command"); 1914 wmi_buf_free(buf); 1915 return QDF_STATUS_E_FAILURE; 1916 } 1917 1918 return 0; 1919 } 1920 1921 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 1922 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1923 { 1924 /* Host sets the peer_type as 0 for the peer create command sent to FW 1925 * other than PASN and BRIDGE peer create command. 1926 */ 1927 if (peer_type == WLAN_PEER_RTT_PASN) 1928 return WMI_PEER_TYPE_PASN; 1929 1930 if (peer_type == WLAN_PEER_MLO_BRIDGE) 1931 return WMI_PEER_TYPE_BRIDGE; 1932 1933 return peer_type; 1934 } 1935 #else 1936 static uint32_t convert_peer_type_host_to_target(uint32_t peer_type) 1937 { 1938 return peer_type; 1939 } 1940 #endif 1941 /** 1942 * send_peer_create_cmd_tlv() - send peer create command to fw 1943 * @wmi: wmi handle 1944 * @param: peer create parameters 1945 * 1946 * Return: QDF_STATUS_SUCCESS for success or error code 1947 */ 1948 static QDF_STATUS send_peer_create_cmd_tlv(wmi_unified_t wmi, 1949 struct peer_create_params *param) 1950 { 1951 wmi_peer_create_cmd_fixed_param *cmd; 1952 wmi_buf_t buf; 1953 uint8_t *buf_ptr; 1954 int32_t len = sizeof(*cmd); 1955 1956 len += peer_create_mlo_params_size(param); 1957 buf = wmi_buf_alloc(wmi, len); 1958 if (!buf) 1959 return QDF_STATUS_E_NOMEM; 1960 1961 cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); 1962 WMITLV_SET_HDR(&cmd->tlv_header, 1963 WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, 1964 WMITLV_GET_STRUCT_TLVLEN 1965 (wmi_peer_create_cmd_fixed_param)); 1966 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 1967 cmd->peer_type = convert_peer_type_host_to_target(param->peer_type); 1968 cmd->vdev_id = param->vdev_id; 1969 1970 buf_ptr = (uint8_t *)wmi_buf_data(buf); 1971 buf_ptr += sizeof(*cmd); 1972 buf_ptr = peer_create_add_mlo_params(buf_ptr, param); 1973 wmi_mtrace(WMI_PEER_CREATE_CMDID, cmd->vdev_id, 0); 1974 if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { 1975 wmi_err("Failed to send WMI_PEER_CREATE_CMDID"); 1976 wmi_buf_free(buf); 1977 return QDF_STATUS_E_FAILURE; 1978 } 1979 wmi_debug("peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d", 1980 QDF_MAC_ADDR_REF(param->peer_addr), 1981 param->vdev_id); 1982 1983 return 0; 1984 } 1985 1986 /** 1987 * send_peer_rx_reorder_queue_setup_cmd_tlv() - send rx reorder setup 1988 * command to fw 1989 * @wmi: wmi handle 1990 * @param: Rx reorder queue setup parameters 1991 * 1992 * Return: QDF_STATUS_SUCCESS for success or error code 1993 */ 1994 static 1995 QDF_STATUS send_peer_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 1996 struct rx_reorder_queue_setup_params *param) 1997 { 1998 wmi_peer_reorder_queue_setup_cmd_fixed_param *cmd; 1999 wmi_buf_t buf; 2000 int32_t len = sizeof(*cmd); 2001 2002 buf = wmi_buf_alloc(wmi, len); 2003 if (!buf) 2004 return QDF_STATUS_E_NOMEM; 2005 2006 cmd = (wmi_peer_reorder_queue_setup_cmd_fixed_param *)wmi_buf_data(buf); 2007 WMITLV_SET_HDR(&cmd->tlv_header, 2008 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_setup_cmd_fixed_param, 2009 WMITLV_GET_STRUCT_TLVLEN 2010 (wmi_peer_reorder_queue_setup_cmd_fixed_param)); 2011 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2012 cmd->vdev_id = param->vdev_id; 2013 cmd->tid = param->tid; 2014 cmd->queue_ptr_lo = param->hw_qdesc_paddr_lo; 2015 cmd->queue_ptr_hi = param->hw_qdesc_paddr_hi; 2016 cmd->queue_no = param->queue_no; 2017 cmd->ba_window_size_valid = param->ba_window_size_valid; 2018 cmd->ba_window_size = param->ba_window_size; 2019 2020 2021 wmi_mtrace(WMI_PEER_REORDER_QUEUE_SETUP_CMDID, cmd->vdev_id, 0); 2022 if (wmi_unified_cmd_send(wmi, buf, len, 2023 WMI_PEER_REORDER_QUEUE_SETUP_CMDID)) { 2024 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_SETUP_CMDID"); 2025 wmi_buf_free(buf); 2026 return QDF_STATUS_E_FAILURE; 2027 } 2028 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid %d", 2029 QDF_MAC_ADDR_REF(param->peer_macaddr), 2030 param->vdev_id, param->tid); 2031 2032 return QDF_STATUS_SUCCESS; 2033 } 2034 2035 /** 2036 * send_peer_multi_rx_reorder_queue_setup_cmd_tlv() - Send multi rx reorder 2037 * setup cmd to fw. 2038 * @wmi: wmi handle 2039 * @param: Multi rx reorder queue setup parameters 2040 * 2041 * Return: QDF_STATUS_SUCCESS for success or error code 2042 */ 2043 static 2044 QDF_STATUS send_peer_multi_rx_reorder_queue_setup_cmd_tlv(wmi_unified_t wmi, 2045 struct multi_rx_reorder_queue_setup_params *param) 2046 { 2047 wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param *cmd; 2048 wmi_buf_t buf; 2049 uint8_t *buf_ptr; 2050 wmi_peer_per_reorder_q_setup_params_t *q_params; 2051 struct rx_reorder_queue_params_list *param_ptr; 2052 int tid; 2053 int32_t len; 2054 2055 len = sizeof(wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param) + 2056 WMI_TLV_HDR_SIZE + 2057 sizeof(wmi_peer_per_reorder_q_setup_params_t) * param->tid_num; 2058 2059 buf = wmi_buf_alloc(wmi, len); 2060 if (!buf) 2061 return QDF_STATUS_E_NOMEM; 2062 2063 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2064 cmd = (wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param *) 2065 wmi_buf_data(buf); 2066 2067 WMITLV_SET_HDR(&cmd->tlv_header, 2068 WMITLV_TAG_STRUC_wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param, 2069 WMITLV_GET_STRUCT_TLVLEN 2070 (wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param)); 2071 2072 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2073 cmd->vdev_id = param->vdev_id; 2074 2075 buf_ptr += 2076 sizeof(wmi_peer_multiple_reorder_queue_setup_cmd_fixed_param); 2077 2078 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 2079 sizeof(wmi_peer_per_reorder_q_setup_params_t) * 2080 param->tid_num); 2081 2082 q_params = (wmi_peer_per_reorder_q_setup_params_t *)(buf_ptr + 2083 WMI_TLV_HDR_SIZE); 2084 2085 for (tid = 0; tid < WMI_MAX_TIDS; tid++) { 2086 if (!(BIT(tid) & param->tid_bitmap)) 2087 continue; 2088 2089 WMITLV_SET_HDR(q_params, 2090 WMITLV_TAG_STRUC_wmi_peer_per_reorder_q_setup_params_t, 2091 WMITLV_GET_STRUCT_TLVLEN( 2092 wmi_peer_per_reorder_q_setup_params_t)); 2093 2094 param_ptr = ¶m->queue_params_list[tid]; 2095 q_params->tid = tid; 2096 q_params->queue_ptr_lo = param_ptr->hw_qdesc_paddr & 0xffffffff; 2097 q_params->queue_ptr_hi = 2098 (uint64_t)param_ptr->hw_qdesc_paddr >> 32; 2099 q_params->queue_no = param_ptr->queue_no; 2100 q_params->ba_window_size_valid = 2101 param_ptr->ba_window_size_valid; 2102 q_params->ba_window_size = param_ptr->ba_window_size; 2103 q_params++; 2104 } 2105 2106 wmi_mtrace(WMI_PEER_MULTIPLE_REORDER_QUEUE_SETUP_CMDID, 2107 cmd->vdev_id, 0); 2108 if (wmi_unified_cmd_send(wmi, buf, len, 2109 WMI_PEER_MULTIPLE_REORDER_QUEUE_SETUP_CMDID)) { 2110 wmi_err("Send WMI_PEER_MULTILE_REORDER_QUEUE_SETUP_CMDID fail"); 2111 wmi_buf_free(buf); 2112 return QDF_STATUS_E_FAILURE; 2113 } 2114 2115 wmi_debug("peer_mac "QDF_MAC_ADDR_FMT" vdev_id %d, bitmap 0x%x, num %d", 2116 QDF_MAC_ADDR_REF(param->peer_macaddr), 2117 param->vdev_id, param->tid_bitmap, param->tid_num); 2118 2119 return QDF_STATUS_SUCCESS; 2120 } 2121 2122 /** 2123 * send_peer_rx_reorder_queue_remove_cmd_tlv() - send rx reorder remove 2124 * command to fw 2125 * @wmi: wmi handle 2126 * @param: Rx reorder queue remove parameters 2127 * 2128 * Return: QDF_STATUS_SUCCESS for success or error code 2129 */ 2130 static 2131 QDF_STATUS send_peer_rx_reorder_queue_remove_cmd_tlv(wmi_unified_t wmi, 2132 struct rx_reorder_queue_remove_params *param) 2133 { 2134 wmi_peer_reorder_queue_remove_cmd_fixed_param *cmd; 2135 wmi_buf_t buf; 2136 int32_t len = sizeof(*cmd); 2137 2138 buf = wmi_buf_alloc(wmi, len); 2139 if (!buf) 2140 return QDF_STATUS_E_NOMEM; 2141 2142 cmd = (wmi_peer_reorder_queue_remove_cmd_fixed_param *) 2143 wmi_buf_data(buf); 2144 WMITLV_SET_HDR(&cmd->tlv_header, 2145 WMITLV_TAG_STRUC_wmi_peer_reorder_queue_remove_cmd_fixed_param, 2146 WMITLV_GET_STRUCT_TLVLEN 2147 (wmi_peer_reorder_queue_remove_cmd_fixed_param)); 2148 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_macaddr, &cmd->peer_macaddr); 2149 cmd->vdev_id = param->vdev_id; 2150 cmd->tid_mask = param->peer_tid_bitmap; 2151 2152 wmi_mtrace(WMI_PEER_REORDER_QUEUE_REMOVE_CMDID, cmd->vdev_id, 0); 2153 if (wmi_unified_cmd_send(wmi, buf, len, 2154 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID)) { 2155 wmi_err("Fail to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID"); 2156 wmi_buf_free(buf); 2157 return QDF_STATUS_E_FAILURE; 2158 } 2159 wmi_debug("peer_macaddr "QDF_MAC_ADDR_FMT" vdev_id %d, tid_map %d", 2160 QDF_MAC_ADDR_REF(param->peer_macaddr), 2161 param->vdev_id, param->peer_tid_bitmap); 2162 2163 return QDF_STATUS_SUCCESS; 2164 } 2165 2166 #ifdef WLAN_SUPPORT_GREEN_AP 2167 /** 2168 * send_green_ap_ps_cmd_tlv() - enable green ap powersave command 2169 * @wmi_handle: wmi handle 2170 * @value: value 2171 * @pdev_id: pdev id to have radio context 2172 * 2173 * Return: QDF_STATUS_SUCCESS for success or error code 2174 */ 2175 static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle, 2176 uint32_t value, uint8_t pdev_id) 2177 { 2178 wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; 2179 wmi_buf_t buf; 2180 int32_t len = sizeof(*cmd); 2181 2182 wmi_debug("Set Green AP PS val %d", value); 2183 2184 buf = wmi_buf_alloc(wmi_handle, len); 2185 if (!buf) 2186 return QDF_STATUS_E_NOMEM; 2187 2188 cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); 2189 WMITLV_SET_HDR(&cmd->tlv_header, 2190 WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, 2191 WMITLV_GET_STRUCT_TLVLEN 2192 (wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); 2193 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2194 wmi_handle, 2195 pdev_id); 2196 cmd->enable = value; 2197 2198 wmi_mtrace(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, NO_SESSION, 0); 2199 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2200 WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { 2201 wmi_err("Set Green AP PS param Failed val %d", value); 2202 wmi_buf_free(buf); 2203 return QDF_STATUS_E_FAILURE; 2204 } 2205 2206 return 0; 2207 } 2208 #endif 2209 2210 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 2211 static QDF_STATUS send_green_ap_ll_ps_cmd_tlv(wmi_unified_t wmi_handle, 2212 struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params) 2213 { 2214 uint32_t len; 2215 wmi_buf_t buf; 2216 wmi_xgap_enable_cmd_fixed_param *cmd; 2217 2218 len = sizeof(*cmd); 2219 2220 wmi_debug("Green AP low latency PS: bcn interval: %u state: %u cookie: %u", 2221 green_ap_ll_ps_params->bcn_interval, 2222 green_ap_ll_ps_params->state, 2223 green_ap_ll_ps_params->cookie); 2224 2225 buf = wmi_buf_alloc(wmi_handle, len); 2226 if (!buf) 2227 return QDF_STATUS_E_NOMEM; 2228 2229 cmd = (wmi_xgap_enable_cmd_fixed_param *)wmi_buf_data(buf); 2230 WMITLV_SET_HDR(&cmd->tlv_header, 2231 WMITLV_TAG_STRUC_wmi_xgap_enable_cmd_fixed_param, 2232 WMITLV_GET_STRUCT_TLVLEN 2233 (wmi_xgap_enable_cmd_fixed_param)); 2234 2235 cmd->beacon_interval = green_ap_ll_ps_params->bcn_interval; 2236 cmd->sap_lp_flag = green_ap_ll_ps_params->state; 2237 cmd->dialog_token = green_ap_ll_ps_params->cookie; 2238 2239 wmi_mtrace(WMI_XGAP_ENABLE_CMDID, NO_SESSION, 0); 2240 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2241 WMI_XGAP_ENABLE_CMDID)) { 2242 wmi_err("Green AP Low latency PS cmd Failed"); 2243 wmi_buf_free(buf); 2244 return QDF_STATUS_E_FAILURE; 2245 } 2246 2247 return QDF_STATUS_SUCCESS; 2248 } 2249 #endif 2250 2251 /** 2252 * send_pdev_utf_cmd_tlv() - send utf command to fw 2253 * @wmi_handle: wmi handle 2254 * @param: pointer to pdev_utf_params 2255 * @mac_id: mac id to have radio context 2256 * 2257 * Return: QDF_STATUS_SUCCESS for success or error code 2258 */ 2259 static QDF_STATUS 2260 send_pdev_utf_cmd_tlv(wmi_unified_t wmi_handle, 2261 struct pdev_utf_params *param, 2262 uint8_t mac_id) 2263 { 2264 wmi_buf_t buf; 2265 uint8_t *cmd; 2266 /* if param->len is 0 no data is sent, return error */ 2267 QDF_STATUS ret = QDF_STATUS_E_INVAL; 2268 static uint8_t msgref = 1; 2269 uint8_t segNumber = 0, segInfo, numSegments; 2270 uint16_t chunk_len, total_bytes; 2271 uint8_t *bufpos; 2272 struct seg_hdr_info segHdrInfo; 2273 wmi_pdev_utf_cmd_fixed_param *utf_cmd; 2274 uint16_t len; 2275 bool is_pdev_id_over_utf; 2276 2277 bufpos = param->utf_payload; 2278 total_bytes = param->len; 2279 ASSERT(total_bytes / MAX_WMI_UTF_LEN == 2280 (uint8_t) (total_bytes / MAX_WMI_UTF_LEN)); 2281 numSegments = (uint8_t) (total_bytes / MAX_WMI_UTF_LEN); 2282 2283 if (param->len - (numSegments * MAX_WMI_UTF_LEN)) 2284 numSegments++; 2285 2286 while (param->len) { 2287 if (param->len > MAX_WMI_UTF_LEN) 2288 chunk_len = MAX_WMI_UTF_LEN; /* MAX message */ 2289 else 2290 chunk_len = param->len; 2291 2292 is_pdev_id_over_utf = is_service_enabled_tlv(wmi_handle, 2293 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI); 2294 if (is_pdev_id_over_utf) 2295 len = chunk_len + sizeof(segHdrInfo) + 2296 WMI_TLV_HDR_SIZE + sizeof(*utf_cmd); 2297 else 2298 len = chunk_len + sizeof(segHdrInfo) + WMI_TLV_HDR_SIZE; 2299 2300 buf = wmi_buf_alloc(wmi_handle, len); 2301 if (!buf) 2302 return QDF_STATUS_E_NOMEM; 2303 2304 cmd = (uint8_t *) wmi_buf_data(buf); 2305 2306 segHdrInfo.len = total_bytes; 2307 segHdrInfo.msgref = msgref; 2308 segInfo = ((numSegments << 4) & 0xF0) | (segNumber & 0xF); 2309 segHdrInfo.segmentInfo = segInfo; 2310 segHdrInfo.pad = 0; 2311 2312 wmi_debug("segHdrInfo.len = %u, segHdrInfo.msgref = %u, segHdrInfo.segmentInfo = %u", 2313 segHdrInfo.len, segHdrInfo.msgref, 2314 segHdrInfo.segmentInfo); 2315 2316 wmi_debug("total_bytes %u segNumber %u totalSegments %u chunk len %u", 2317 total_bytes, segNumber, numSegments, chunk_len); 2318 2319 segNumber++; 2320 2321 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, 2322 (chunk_len + sizeof(segHdrInfo))); 2323 cmd += WMI_TLV_HDR_SIZE; 2324 memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 words */ 2325 cmd += sizeof(segHdrInfo); 2326 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(cmd, 2327 bufpos, chunk_len); 2328 2329 if (is_pdev_id_over_utf) { 2330 cmd += chunk_len; 2331 utf_cmd = (wmi_pdev_utf_cmd_fixed_param *)cmd; 2332 WMITLV_SET_HDR(&utf_cmd->tlv_header, 2333 WMITLV_TAG_STRUC_wmi_pdev_utf_cmd_fixed_param, 2334 WMITLV_GET_STRUCT_TLVLEN( 2335 wmi_pdev_utf_cmd_fixed_param)); 2336 2337 if (wmi_handle->ops->convert_host_pdev_id_to_target) 2338 utf_cmd->pdev_id = 2339 wmi_handle->ops->convert_host_pdev_id_to_target( 2340 wmi_handle, mac_id); 2341 2342 wmi_debug("pdev_id %u", utf_cmd->pdev_id); 2343 } 2344 wmi_mtrace(WMI_PDEV_UTF_CMDID, NO_SESSION, 0); 2345 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2346 WMI_PDEV_UTF_CMDID); 2347 2348 if (QDF_IS_STATUS_ERROR(ret)) { 2349 wmi_err("Failed to send WMI_PDEV_UTF_CMDID command"); 2350 wmi_buf_free(buf); 2351 break; 2352 } 2353 2354 param->len -= chunk_len; 2355 bufpos += chunk_len; 2356 } 2357 2358 msgref++; 2359 2360 return ret; 2361 } 2362 2363 #ifdef ENABLE_HOST_TO_TARGET_CONVERSION 2364 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2365 { 2366 if (host_param < QDF_ARRAY_SIZE(pdev_param_tlv)) 2367 return pdev_param_tlv[host_param]; 2368 return WMI_UNAVAILABLE_PARAM; 2369 } 2370 2371 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2372 { 2373 if (host_param < QDF_ARRAY_SIZE(vdev_param_tlv)) 2374 return vdev_param_tlv[host_param]; 2375 return WMI_UNAVAILABLE_PARAM; 2376 } 2377 #else 2378 static inline uint32_t convert_host_pdev_param_tlv(uint32_t host_param) 2379 { 2380 return host_param; 2381 } 2382 2383 static inline uint32_t convert_host_vdev_param_tlv(uint32_t host_param) 2384 { 2385 return host_param; 2386 } 2387 #endif /* end of ENABLE_HOST_TO_TARGET_CONVERSION */ 2388 2389 /** 2390 * send_pdev_param_cmd_tlv() - set pdev parameters 2391 * @wmi_handle: wmi handle 2392 * @param: pointer to pdev parameter 2393 * @mac_id: radio context 2394 * 2395 * Return: QDF_STATUS_SUCCESS for success or error code 2396 */ 2397 static QDF_STATUS 2398 send_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2399 struct pdev_params *param, 2400 uint8_t mac_id) 2401 { 2402 QDF_STATUS ret; 2403 wmi_pdev_set_param_cmd_fixed_param *cmd; 2404 wmi_buf_t buf; 2405 uint16_t len = sizeof(*cmd); 2406 uint32_t pdev_param; 2407 2408 pdev_param = convert_host_pdev_param_tlv(param->param_id); 2409 if (pdev_param == WMI_UNAVAILABLE_PARAM) { 2410 wmi_err("Unavailable param %d", param->param_id); 2411 return QDF_STATUS_E_INVAL; 2412 } 2413 2414 buf = wmi_buf_alloc(wmi_handle, len); 2415 if (!buf) 2416 return QDF_STATUS_E_NOMEM; 2417 2418 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 2419 WMITLV_SET_HDR(&cmd->tlv_header, 2420 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, 2421 WMITLV_GET_STRUCT_TLVLEN 2422 (wmi_pdev_set_param_cmd_fixed_param)); 2423 if (param->is_host_pdev_id) 2424 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 2425 wmi_handle, 2426 mac_id); 2427 else 2428 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2429 wmi_handle, 2430 mac_id); 2431 cmd->param_id = pdev_param; 2432 cmd->param_value = param->param_value; 2433 wmi_nofl_debug("Set pdev %d param 0x%x to %u", cmd->pdev_id, 2434 cmd->param_id, cmd->param_value); 2435 wmi_mtrace(WMI_PDEV_SET_PARAM_CMDID, NO_SESSION, 0); 2436 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2437 WMI_PDEV_SET_PARAM_CMDID); 2438 if (QDF_IS_STATUS_ERROR(ret)) { 2439 wmi_buf_free(buf); 2440 } 2441 return ret; 2442 } 2443 2444 /** 2445 * send_multi_param_cmd_using_pdev_set_param_tlv() - set pdev parameters 2446 * @wmi_handle: wmi handle 2447 * @params: pointer to hold set_multiple_pdev_vdev_param info 2448 * 2449 * Return: QDF_STATUS_SUCCESS for success or error code 2450 */ 2451 static QDF_STATUS 2452 send_multi_param_cmd_using_pdev_set_param_tlv(wmi_unified_t wmi_handle, 2453 struct set_multiple_pdev_vdev_param *params) 2454 { 2455 uint8_t index; 2456 struct pdev_params pdevparam; 2457 uint8_t n_params = params->n_params; 2458 2459 pdevparam.is_host_pdev_id = params->is_host_pdev_id; 2460 for (index = 0; index < n_params; index++) { 2461 pdevparam.param_id = params->params[index].param_id; 2462 pdevparam.param_value = params->params[index].param_value; 2463 if (QDF_IS_STATUS_ERROR(send_pdev_param_cmd_tlv(wmi_handle, 2464 &pdevparam, 2465 params->dev_id))) { 2466 wmi_err("failed to send pdev setparam:%d", 2467 pdevparam.param_id); 2468 return QDF_STATUS_E_FAILURE; 2469 } 2470 } 2471 return QDF_STATUS_SUCCESS; 2472 } 2473 2474 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 2475 2476 /** 2477 * convert_host_pdev_vdev_param_id_to_target()- convert host params to target params 2478 * @params: pointer to point set_multiple_pdev_vdev_param info 2479 * 2480 * Return: returns QDF_STATUS 2481 */ 2482 static QDF_STATUS 2483 convert_host_pdev_vdev_param_id_to_target(struct set_multiple_pdev_vdev_param *params) 2484 { 2485 uint8_t index; 2486 uint32_t dev_paramid; 2487 uint8_t num = params->n_params; 2488 2489 if (params->param_type == MLME_PDEV_SETPARAM) { 2490 for (index = 0; index < num; index++) { 2491 dev_paramid = convert_host_pdev_param_tlv(params->params[index].param_id); 2492 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2493 wmi_err("pdev param %d not available", 2494 params->params[index].param_id); 2495 return QDF_STATUS_E_INVAL; 2496 } 2497 params->params[index].param_id = dev_paramid; 2498 } 2499 } else if (params->param_type == MLME_VDEV_SETPARAM) { 2500 for (index = 0; index < num; index++) { 2501 dev_paramid = convert_host_vdev_param_tlv(params->params[index].param_id); 2502 if (dev_paramid == WMI_UNAVAILABLE_PARAM) { 2503 wmi_err("vdev param %d not available", 2504 params->params[index].param_id); 2505 return QDF_STATUS_E_INVAL; 2506 } 2507 params->params[index].param_id = dev_paramid; 2508 } 2509 } else { 2510 wmi_err("invalid param type"); 2511 return QDF_STATUS_E_INVAL; 2512 } 2513 return QDF_STATUS_SUCCESS; 2514 } 2515 2516 /** 2517 * send_multi_pdev_vdev_set_param_cmd_tlv()-set pdev/vdev params 2518 * @wmi_handle: wmi handle 2519 * @params: pointer to hold set_multiple_pdev_vdev_param info 2520 * 2521 * Return: returns QDF_STATUS 2522 */ 2523 static QDF_STATUS 2524 send_multi_pdev_vdev_set_param_cmd_tlv( 2525 wmi_unified_t wmi_handle, 2526 struct set_multiple_pdev_vdev_param *params) 2527 { 2528 uint8_t *buf_ptr; 2529 QDF_STATUS ret; 2530 wmi_buf_t buf; 2531 wmi_set_param_info *setparam; 2532 wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *cmd; 2533 uint8_t num = params->n_params; 2534 uint16_t len; 2535 uint8_t index = 0; 2536 const char *dev_string[] = {"pdev", "vdev"}; 2537 2538 if (convert_host_pdev_vdev_param_id_to_target(params)) 2539 return QDF_STATUS_E_INVAL; 2540 2541 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + (num * sizeof(*setparam)); 2542 buf = wmi_buf_alloc(wmi_handle, len); 2543 if (!buf) 2544 return QDF_STATUS_E_NOMEM; 2545 2546 buf_ptr = (uint8_t *)wmi_buf_data(buf); 2547 cmd = (wmi_set_multiple_pdev_vdev_param_cmd_fixed_param *)buf_ptr; 2548 2549 WMITLV_SET_HDR(&cmd->tlv_header, 2550 WMITLV_TAG_STRUC_wmi_set_multiple_pdev_vdev_param_cmd_fixed_param, 2551 WMITLV_GET_STRUCT_TLVLEN(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param)); 2552 2553 cmd->is_vdev = params->param_type; 2554 if (params->param_type == MLME_PDEV_SETPARAM) { 2555 if (params->is_host_pdev_id) 2556 params->dev_id = wmi_handle->ops->convert_host_pdev_id_to_target(wmi_handle, 2557 params->dev_id); 2558 else 2559 params->dev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 2560 params->dev_id); 2561 } 2562 cmd->dev_id = params->dev_id; 2563 buf_ptr += sizeof(wmi_set_multiple_pdev_vdev_param_cmd_fixed_param); 2564 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, (num * sizeof(*setparam))); 2565 buf_ptr += WMI_TLV_HDR_SIZE; 2566 for (index = 0; index < num; index++) { 2567 setparam = (wmi_set_param_info *)buf_ptr; 2568 WMITLV_SET_HDR(&setparam->tlv_header, 2569 WMITLV_TAG_STRUC_wmi_set_param_info, 2570 WMITLV_GET_STRUCT_TLVLEN(*setparam)); 2571 setparam->param_id = params->params[index].param_id; 2572 setparam->param_value = params->params[index].param_value; 2573 wmi_nofl_debug("Set %s %d param 0x%x to %u", 2574 dev_string[cmd->is_vdev], params->dev_id, 2575 setparam->param_id, setparam->param_value); 2576 buf_ptr += sizeof(*setparam); 2577 } 2578 wmi_mtrace(WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID, 2579 cmd->dev_id, 0); 2580 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2581 WMI_SET_MULTIPLE_PDEV_VDEV_PARAM_CMDID); 2582 if (QDF_IS_STATUS_ERROR(ret)) { 2583 wmi_buf_free(buf); 2584 } 2585 return ret; 2586 } 2587 2588 /** 2589 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2590 * @wmi_handle: wmi handle 2591 * @params: pointer to set_multiple_pdev_vdev_param structure 2592 * 2593 * Return: QDF_STATUS_SUCCESS for success or error code 2594 */ 2595 static QDF_STATUS 2596 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2597 struct set_multiple_pdev_vdev_param *params) 2598 { 2599 if (!wmi_service_enabled(wmi_handle, 2600 wmi_service_combined_set_param_support)) 2601 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, 2602 params); 2603 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 2604 } 2605 2606 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2607 /** 2608 * send_multiple_pdev_param_cmd_tlv() - set pdev parameters 2609 * @wmi_handle: wmi handle 2610 * @params: pointer to set_multiple_pdev_vdev_param structure 2611 * 2612 * Return: QDF_STATUS_SUCCESS for success or error code 2613 */ 2614 static QDF_STATUS 2615 send_multiple_pdev_param_cmd_tlv(wmi_unified_t wmi_handle, 2616 struct set_multiple_pdev_vdev_param *params) 2617 { 2618 return send_multi_param_cmd_using_pdev_set_param_tlv(wmi_handle, params); 2619 } 2620 #endif /* end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 2621 2622 /** 2623 * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW 2624 * @wmi_handle: wmi handle 2625 * @hw_mode_index: The HW_Mode field is a enumerated type that is selected 2626 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. 2627 * 2628 * Provides notification to the WLAN firmware that host driver is requesting a 2629 * HardWare (HW) Mode change. This command is needed to support iHelium in the 2630 * configurations that include the Dual Band Simultaneous (DBS) feature. 2631 * 2632 * Return: Success if the cmd is sent successfully to the firmware 2633 */ 2634 static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle, 2635 uint32_t hw_mode_index) 2636 { 2637 wmi_pdev_set_hw_mode_cmd_fixed_param *cmd; 2638 wmi_buf_t buf; 2639 uint32_t len; 2640 2641 len = sizeof(*cmd); 2642 2643 buf = wmi_buf_alloc(wmi_handle, len); 2644 if (!buf) 2645 return QDF_STATUS_E_NOMEM; 2646 2647 cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *)wmi_buf_data(buf); 2648 WMITLV_SET_HDR(&cmd->tlv_header, 2649 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 2650 WMITLV_GET_STRUCT_TLVLEN( 2651 wmi_pdev_set_hw_mode_cmd_fixed_param)); 2652 2653 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2654 wmi_handle, 2655 WMI_HOST_PDEV_ID_SOC); 2656 cmd->hw_mode_index = hw_mode_index; 2657 wmi_debug("HW mode index:%d", cmd->hw_mode_index); 2658 2659 wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0); 2660 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2661 WMI_PDEV_SET_HW_MODE_CMDID)) { 2662 wmi_err("Failed to send WMI_PDEV_SET_HW_MODE_CMDID"); 2663 wmi_buf_free(buf); 2664 return QDF_STATUS_E_FAILURE; 2665 } 2666 2667 return QDF_STATUS_SUCCESS; 2668 } 2669 2670 /** 2671 * send_pdev_set_rf_path_cmd_tlv() - Send WMI_PDEV_SET_RF_PATH_CMDID to FW 2672 * @wmi_handle: wmi handle 2673 * @rf_path_index: the rf path mode to be selected 2674 * @pdev_id: pdev id 2675 * 2676 * Provides notification to the WLAN firmware that host driver is requesting a 2677 * rf path change. 2678 * 2679 * Return: Success if the cmd is sent successfully to the firmware 2680 */ 2681 static QDF_STATUS send_pdev_set_rf_path_cmd_tlv(wmi_unified_t wmi_handle, 2682 uint32_t rf_path_index, 2683 uint8_t pdev_id) 2684 { 2685 wmi_pdev_set_rf_path_cmd_fixed_param *cmd; 2686 wmi_buf_t buf; 2687 uint32_t len; 2688 2689 len = sizeof(*cmd); 2690 2691 buf = wmi_buf_alloc(wmi_handle, len); 2692 if (!buf) 2693 return QDF_STATUS_E_NOMEM; 2694 2695 cmd = (wmi_pdev_set_rf_path_cmd_fixed_param *)wmi_buf_data(buf); 2696 WMITLV_SET_HDR(&cmd->tlv_header, 2697 WMITLV_TAG_STRUC_wmi_pdev_set_rf_path_cmd_fixed_param, 2698 WMITLV_GET_STRUCT_TLVLEN( 2699 wmi_pdev_set_rf_path_cmd_fixed_param)); 2700 2701 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2702 wmi_handle, 2703 pdev_id); 2704 cmd->rf_path = rf_path_index; 2705 wmi_debug("HW mode index:%d", cmd->rf_path); 2706 2707 wmi_mtrace(WMI_PDEV_SET_RF_PATH_CMDID, NO_SESSION, 0); 2708 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2709 WMI_PDEV_SET_RF_PATH_CMDID)) { 2710 wmi_err("Failed to send WMI_PDEV_SET_RF_PATH_CMDID"); 2711 wmi_buf_free(buf); 2712 return QDF_STATUS_E_FAILURE; 2713 } 2714 2715 return QDF_STATUS_SUCCESS; 2716 } 2717 2718 /** 2719 * send_suspend_cmd_tlv() - WMI suspend function 2720 * @wmi_handle: handle to WMI. 2721 * @param: pointer to hold suspend parameter 2722 * @mac_id: radio context 2723 * 2724 * Return: QDF_STATUS_SUCCESS for success or error code 2725 */ 2726 static QDF_STATUS send_suspend_cmd_tlv(wmi_unified_t wmi_handle, 2727 struct suspend_params *param, 2728 uint8_t mac_id) 2729 { 2730 wmi_pdev_suspend_cmd_fixed_param *cmd; 2731 wmi_buf_t wmibuf; 2732 uint32_t len = sizeof(*cmd); 2733 int32_t ret; 2734 2735 /* 2736 * send the command to Target to ignore the 2737 * PCIE reset so as to ensure that Host and target 2738 * states are in sync 2739 */ 2740 wmibuf = wmi_buf_alloc(wmi_handle, len); 2741 if (!wmibuf) 2742 return QDF_STATUS_E_NOMEM; 2743 2744 cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); 2745 WMITLV_SET_HDR(&cmd->tlv_header, 2746 WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, 2747 WMITLV_GET_STRUCT_TLVLEN 2748 (wmi_pdev_suspend_cmd_fixed_param)); 2749 if (param->disable_target_intr) 2750 cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; 2751 else 2752 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2753 2754 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2755 wmi_handle, 2756 mac_id); 2757 2758 wmi_mtrace(WMI_PDEV_SUSPEND_CMDID, NO_SESSION, 0); 2759 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, len, 2760 WMI_PDEV_SUSPEND_CMDID); 2761 if (ret) { 2762 wmi_buf_free(wmibuf); 2763 wmi_err("Failed to send WMI_PDEV_SUSPEND_CMDID command"); 2764 } 2765 2766 return ret; 2767 } 2768 2769 /** 2770 * send_resume_cmd_tlv() - WMI resume function 2771 * @wmi_handle: handle to WMI. 2772 * @mac_id: radio context 2773 * 2774 * Return: QDF_STATUS_SUCCESS for success or error code 2775 */ 2776 static QDF_STATUS send_resume_cmd_tlv(wmi_unified_t wmi_handle, 2777 uint8_t mac_id) 2778 { 2779 wmi_buf_t wmibuf; 2780 wmi_pdev_resume_cmd_fixed_param *cmd; 2781 QDF_STATUS ret; 2782 2783 wmibuf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2784 if (!wmibuf) 2785 return QDF_STATUS_E_NOMEM; 2786 cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); 2787 WMITLV_SET_HDR(&cmd->tlv_header, 2788 WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, 2789 WMITLV_GET_STRUCT_TLVLEN 2790 (wmi_pdev_resume_cmd_fixed_param)); 2791 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 2792 wmi_handle, 2793 mac_id); 2794 wmi_mtrace(WMI_PDEV_RESUME_CMDID, NO_SESSION, 0); 2795 ret = wmi_unified_cmd_send(wmi_handle, wmibuf, sizeof(*cmd), 2796 WMI_PDEV_RESUME_CMDID); 2797 if (QDF_IS_STATUS_ERROR(ret)) { 2798 wmi_err("Failed to send WMI_PDEV_RESUME_CMDID command"); 2799 wmi_buf_free(wmibuf); 2800 } 2801 2802 return ret; 2803 } 2804 2805 /** 2806 * send_wow_enable_cmd_tlv() - WMI wow enable function 2807 * @wmi_handle: handle to WMI. 2808 * @param: pointer to hold wow enable parameter 2809 * @mac_id: radio context 2810 * 2811 * Return: QDF_STATUS_SUCCESS for success or error code 2812 */ 2813 static QDF_STATUS send_wow_enable_cmd_tlv(wmi_unified_t wmi_handle, 2814 struct wow_cmd_params *param, 2815 uint8_t mac_id) 2816 { 2817 wmi_wow_enable_cmd_fixed_param *cmd; 2818 wmi_buf_t buf; 2819 int32_t len; 2820 int32_t ret; 2821 2822 len = sizeof(wmi_wow_enable_cmd_fixed_param); 2823 2824 buf = wmi_buf_alloc(wmi_handle, len); 2825 if (!buf) 2826 return QDF_STATUS_E_NOMEM; 2827 2828 cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); 2829 WMITLV_SET_HDR(&cmd->tlv_header, 2830 WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, 2831 WMITLV_GET_STRUCT_TLVLEN 2832 (wmi_wow_enable_cmd_fixed_param)); 2833 cmd->enable = param->enable; 2834 if (param->can_suspend_link) 2835 cmd->pause_iface_config = WOW_IFACE_PAUSE_ENABLED; 2836 else 2837 cmd->pause_iface_config = WOW_IFACE_PAUSE_DISABLED; 2838 cmd->flags = param->flags; 2839 2840 wmi_debug("suspend type: %s flag is 0x%x", 2841 cmd->pause_iface_config == WOW_IFACE_PAUSE_ENABLED ? 2842 "WOW_IFACE_PAUSE_ENABLED" : "WOW_IFACE_PAUSE_DISABLED", 2843 cmd->flags); 2844 2845 wmi_mtrace(WMI_WOW_ENABLE_CMDID, NO_SESSION, 0); 2846 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2847 WMI_WOW_ENABLE_CMDID); 2848 if (ret) 2849 wmi_buf_free(buf); 2850 2851 return ret; 2852 } 2853 2854 /** 2855 * send_set_ap_ps_param_cmd_tlv() - set ap powersave parameters 2856 * @wmi_handle: wmi handle 2857 * @peer_addr: peer mac address 2858 * @param: pointer to ap_ps parameter structure 2859 * 2860 * Return: QDF_STATUS_SUCCESS for success or error code 2861 */ 2862 static QDF_STATUS send_set_ap_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2863 uint8_t *peer_addr, 2864 struct ap_ps_params *param) 2865 { 2866 wmi_ap_ps_peer_cmd_fixed_param *cmd; 2867 wmi_buf_t buf; 2868 int32_t err; 2869 2870 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 2871 if (!buf) 2872 return QDF_STATUS_E_NOMEM; 2873 2874 cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); 2875 WMITLV_SET_HDR(&cmd->tlv_header, 2876 WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, 2877 WMITLV_GET_STRUCT_TLVLEN 2878 (wmi_ap_ps_peer_cmd_fixed_param)); 2879 cmd->vdev_id = param->vdev_id; 2880 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); 2881 cmd->param = param->param; 2882 cmd->value = param->value; 2883 wmi_mtrace(WMI_AP_PS_PEER_PARAM_CMDID, cmd->vdev_id, 0); 2884 err = wmi_unified_cmd_send(wmi_handle, buf, 2885 sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); 2886 if (err) { 2887 wmi_err("Failed to send set_ap_ps_param cmd"); 2888 wmi_buf_free(buf); 2889 return QDF_STATUS_E_FAILURE; 2890 } 2891 2892 return 0; 2893 } 2894 2895 /** 2896 * send_set_sta_ps_param_cmd_tlv() - set sta powersave parameters 2897 * @wmi_handle: wmi handle 2898 * @param: pointer to sta_ps parameter structure 2899 * 2900 * Return: QDF_STATUS_SUCCESS for success or error code 2901 */ 2902 static QDF_STATUS send_set_sta_ps_param_cmd_tlv(wmi_unified_t wmi_handle, 2903 struct sta_ps_params *param) 2904 { 2905 wmi_sta_powersave_param_cmd_fixed_param *cmd; 2906 wmi_buf_t buf; 2907 int32_t len = sizeof(*cmd); 2908 2909 buf = wmi_buf_alloc(wmi_handle, len); 2910 if (!buf) 2911 return QDF_STATUS_E_NOMEM; 2912 2913 cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); 2914 WMITLV_SET_HDR(&cmd->tlv_header, 2915 WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, 2916 WMITLV_GET_STRUCT_TLVLEN 2917 (wmi_sta_powersave_param_cmd_fixed_param)); 2918 cmd->vdev_id = param->vdev_id; 2919 cmd->param = param->param_id; 2920 cmd->value = param->value; 2921 2922 wmi_mtrace(WMI_STA_POWERSAVE_PARAM_CMDID, cmd->vdev_id, 0); 2923 if (wmi_unified_cmd_send(wmi_handle, buf, len, 2924 WMI_STA_POWERSAVE_PARAM_CMDID)) { 2925 wmi_err("Set Sta Ps param Failed vdevId %d Param %d val %d", 2926 param->vdev_id, param->param_id, param->value); 2927 wmi_buf_free(buf); 2928 return QDF_STATUS_E_FAILURE; 2929 } 2930 2931 return 0; 2932 } 2933 2934 /** 2935 * send_crash_inject_cmd_tlv() - inject fw crash 2936 * @wmi_handle: wmi handle 2937 * @param: pointer to crash inject parameter structure 2938 * 2939 * Return: QDF_STATUS_SUCCESS for success or return error 2940 */ 2941 static QDF_STATUS send_crash_inject_cmd_tlv(wmi_unified_t wmi_handle, 2942 struct crash_inject *param) 2943 { 2944 int32_t ret = 0; 2945 WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; 2946 uint16_t len = sizeof(*cmd); 2947 wmi_buf_t buf; 2948 2949 buf = wmi_buf_alloc(wmi_handle, len); 2950 if (!buf) 2951 return QDF_STATUS_E_NOMEM; 2952 2953 cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); 2954 WMITLV_SET_HDR(&cmd->tlv_header, 2955 WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, 2956 WMITLV_GET_STRUCT_TLVLEN 2957 (WMI_FORCE_FW_HANG_CMD_fixed_param)); 2958 cmd->type = param->type; 2959 cmd->delay_time_ms = param->delay_time_ms; 2960 2961 wmi_mtrace(WMI_FORCE_FW_HANG_CMDID, NO_SESSION, 0); 2962 wmi_info("type:%d delay_time_ms:%d current_time:%ld", 2963 cmd->type, cmd->delay_time_ms, qdf_mc_timer_get_system_time()); 2964 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 2965 WMI_FORCE_FW_HANG_CMDID); 2966 if (ret) { 2967 wmi_err("Failed to send set param command, ret = %d", ret); 2968 wmi_buf_free(buf); 2969 } 2970 2971 return ret; 2972 } 2973 2974 /** 2975 * send_dbglog_cmd_tlv() - set debug log level 2976 * @wmi_handle: handle to WMI. 2977 * @dbglog_param: pointer to hold dbglog level parameter 2978 * 2979 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 2980 */ 2981 static QDF_STATUS 2982 send_dbglog_cmd_tlv(wmi_unified_t wmi_handle, 2983 struct dbglog_params *dbglog_param) 2984 { 2985 wmi_buf_t buf; 2986 wmi_debug_log_config_cmd_fixed_param *configmsg; 2987 QDF_STATUS status; 2988 int32_t i; 2989 int32_t len; 2990 int8_t *buf_ptr; 2991 int32_t *module_id_bitmap_array; /* Used to form the second tlv */ 2992 2993 ASSERT(dbglog_param->bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); 2994 2995 /* Allocate size for 2 tlvs - including tlv hdr space for second tlv */ 2996 len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + 2997 (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); 2998 buf = wmi_buf_alloc(wmi_handle, len); 2999 if (!buf) 3000 return QDF_STATUS_E_NOMEM; 3001 3002 configmsg = 3003 (wmi_debug_log_config_cmd_fixed_param *) (wmi_buf_data(buf)); 3004 buf_ptr = (int8_t *) configmsg; 3005 WMITLV_SET_HDR(&configmsg->tlv_header, 3006 WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, 3007 WMITLV_GET_STRUCT_TLVLEN 3008 (wmi_debug_log_config_cmd_fixed_param)); 3009 configmsg->dbg_log_param = dbglog_param->param; 3010 configmsg->value = dbglog_param->val; 3011 /* Filling in the data part of second tlv -- should 3012 * follow first tlv _ WMI_TLV_HDR_SIZE */ 3013 module_id_bitmap_array = (uint32_t *) (buf_ptr + 3014 sizeof 3015 (wmi_debug_log_config_cmd_fixed_param) 3016 + WMI_TLV_HDR_SIZE); 3017 WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), 3018 WMITLV_TAG_ARRAY_UINT32, 3019 sizeof(uint32_t) * MAX_MODULE_ID_BITMAP_WORDS); 3020 if (dbglog_param->module_id_bitmap) { 3021 for (i = 0; i < dbglog_param->bitmap_len; ++i) { 3022 module_id_bitmap_array[i] = 3023 dbglog_param->module_id_bitmap[i]; 3024 } 3025 } 3026 3027 wmi_mtrace(WMI_DBGLOG_CFG_CMDID, NO_SESSION, 0); 3028 status = wmi_unified_cmd_send(wmi_handle, buf, 3029 len, WMI_DBGLOG_CFG_CMDID); 3030 3031 if (status != QDF_STATUS_SUCCESS) 3032 wmi_buf_free(buf); 3033 3034 return status; 3035 } 3036 3037 /** 3038 * send_vdev_set_param_cmd_tlv() - WMI vdev set parameter function 3039 * @wmi_handle: handle to WMI. 3040 * @param: pointer to hold vdev set parameter 3041 * 3042 * Return: QDF_STATUS_SUCCESS for success or error code 3043 */ 3044 static QDF_STATUS send_vdev_set_param_cmd_tlv(wmi_unified_t wmi_handle, 3045 struct vdev_set_params *param) 3046 { 3047 QDF_STATUS ret; 3048 wmi_vdev_set_param_cmd_fixed_param *cmd; 3049 wmi_buf_t buf; 3050 uint16_t len = sizeof(*cmd); 3051 uint32_t vdev_param; 3052 3053 vdev_param = convert_host_vdev_param_tlv(param->param_id); 3054 if (vdev_param == WMI_UNAVAILABLE_PARAM) { 3055 wmi_err("Vdev param %d not available", param->param_id); 3056 return QDF_STATUS_E_INVAL; 3057 3058 } 3059 3060 buf = wmi_buf_alloc(wmi_handle, len); 3061 if (!buf) 3062 return QDF_STATUS_E_NOMEM; 3063 3064 cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); 3065 WMITLV_SET_HDR(&cmd->tlv_header, 3066 WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, 3067 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_param_cmd_fixed_param)); 3068 cmd->vdev_id = param->vdev_id; 3069 cmd->param_id = vdev_param; 3070 cmd->param_value = param->param_value; 3071 wmi_nofl_debug("Set vdev %d param 0x%x to %u", 3072 cmd->vdev_id, cmd->param_id, cmd->param_value); 3073 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 3074 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_PARAM_CMDID); 3075 if (QDF_IS_STATUS_ERROR(ret)) { 3076 wmi_buf_free(buf); 3077 } 3078 3079 return ret; 3080 } 3081 3082 /** 3083 * send_multi_param_cmd_using_vdev_param_tlv() - vdev set parameter function 3084 * @wmi_handle : handle to WMI. 3085 * @params: pointer to parameters to set 3086 * 3087 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_* 3088 */ 3089 static QDF_STATUS 3090 send_multi_param_cmd_using_vdev_param_tlv(wmi_unified_t wmi_handle, 3091 struct set_multiple_pdev_vdev_param *params) 3092 { 3093 uint8_t index; 3094 struct vdev_set_params vdevparam; 3095 3096 for (index = 0; index < params->n_params; index++) { 3097 vdevparam.param_id = params->params[index].param_id; 3098 vdevparam.param_value = params->params[index].param_value; 3099 vdevparam.vdev_id = params->dev_id; 3100 if (QDF_IS_STATUS_ERROR(send_vdev_set_param_cmd_tlv(wmi_handle, &vdevparam))) { 3101 wmi_err("failed to send param:%d", vdevparam.param_id); 3102 return QDF_STATUS_E_FAILURE; 3103 } 3104 } 3105 return QDF_STATUS_SUCCESS; 3106 } 3107 3108 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 3109 /** 3110 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 3111 * @wmi_handle : handle to WMI. 3112 * @params: pointer to hold set_multiple_pdev_vdev_param info 3113 * 3114 * Return: QDF_STATUS_SUCCESS for success or error code 3115 */ 3116 static QDF_STATUS 3117 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 3118 struct set_multiple_pdev_vdev_param *params) 3119 { 3120 if (!wmi_service_enabled(wmi_handle, 3121 wmi_service_combined_set_param_support)) 3122 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, 3123 params); 3124 return send_multi_pdev_vdev_set_param_cmd_tlv(wmi_handle, params); 3125 } 3126 3127 #else /* WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3128 3129 /** 3130 * send_multiple_vdev_param_cmd_tlv() - WMI vdev set parameter function 3131 * @wmi_handle : handle to WMI. 3132 * @params: pointer to hold set_multiple_pdev_vdev_param info 3133 * 3134 * Return: QDF_STATUS_SUCCESS for success or error code 3135 */ 3136 static QDF_STATUS 3137 send_multiple_vdev_param_cmd_tlv(wmi_unified_t wmi_handle, 3138 struct set_multiple_pdev_vdev_param *params) 3139 { 3140 return send_multi_param_cmd_using_vdev_param_tlv(wmi_handle, params); 3141 } 3142 #endif /*end of WLAN_PDEV_VDEV_SEND_MULTI_PARAM */ 3143 3144 /** 3145 * send_vdev_set_mu_snif_cmd_tlv() - WMI vdev set mu snif function 3146 * @wmi_handle: handle to WMI. 3147 * @param: pointer to hold mu sniffer parameter 3148 * 3149 * Return: QDF_STATUS_SUCCESS for success or error code 3150 */ 3151 static 3152 QDF_STATUS send_vdev_set_mu_snif_cmd_tlv(wmi_unified_t wmi_handle, 3153 struct vdev_set_mu_snif_param *param) 3154 { 3155 QDF_STATUS ret; 3156 wmi_vdev_set_mu_snif_cmd_param *cmd; 3157 wmi_buf_t buf; 3158 uint32_t *tmp_ptr; 3159 uint16_t len = sizeof(*cmd); 3160 uint8_t *buf_ptr; 3161 uint32_t i; 3162 3163 /* Length TLV placeholder for array of uint32_t */ 3164 len += WMI_TLV_HDR_SIZE; 3165 3166 if (param->num_aid) 3167 len += param->num_aid * sizeof(uint32_t); 3168 3169 buf = wmi_buf_alloc(wmi_handle, len); 3170 if (!buf) 3171 return QDF_STATUS_E_NOMEM; 3172 3173 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3174 cmd = (wmi_vdev_set_mu_snif_cmd_param *)buf_ptr; 3175 3176 WMITLV_SET_HDR(&cmd->tlv_header, 3177 WMITLV_TAG_STRUC_wmi_vdev_set_mu_snif_cmd_param, 3178 WMITLV_GET_STRUCT_TLVLEN 3179 (wmi_vdev_set_mu_snif_cmd_param)); 3180 3181 cmd->vdev_id = param->vdev_id; 3182 cmd->mode = param->mode; 3183 cmd->max_num_user = param->num_user; 3184 3185 buf_ptr += sizeof(*cmd); 3186 3187 tmp_ptr = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 3188 3189 for (i = 0; i < param->num_aid; ++i) 3190 tmp_ptr[i] = param->aid[i]; 3191 3192 WMITLV_SET_HDR(buf_ptr, 3193 WMITLV_TAG_ARRAY_UINT32, 3194 (param->num_aid * sizeof(uint32_t))); 3195 3196 wmi_debug("Setting vdev %d mode = %x, max user = %u aids= %u", 3197 cmd->vdev_id, cmd->mode, cmd->max_num_user, param->num_aid); 3198 wmi_mtrace(WMI_VDEV_SET_PARAM_CMDID, cmd->vdev_id, 0); 3199 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3200 WMI_VDEV_SET_MU_SNIF_CMDID); 3201 if (QDF_IS_STATUS_ERROR(ret)) { 3202 wmi_err("Failed to send set param command ret = %d", ret); 3203 wmi_buf_free(buf); 3204 } 3205 3206 return ret; 3207 } 3208 3209 /** 3210 * send_peer_based_pktlog_cmd() - Send WMI command to enable packet-log 3211 * @wmi_handle: handle to WMI. 3212 * @macaddr: Peer mac address to be filter 3213 * @mac_id: mac id to have radio context 3214 * @enb_dsb: Enable MAC based filtering or Disable 3215 * 3216 * Return: QDF_STATUS 3217 */ 3218 static QDF_STATUS send_peer_based_pktlog_cmd(wmi_unified_t wmi_handle, 3219 uint8_t *macaddr, 3220 uint8_t mac_id, 3221 uint8_t enb_dsb) 3222 { 3223 int32_t ret; 3224 wmi_pdev_pktlog_filter_cmd_fixed_param *cmd; 3225 wmi_pdev_pktlog_filter_info *mac_info; 3226 wmi_buf_t buf; 3227 uint8_t *buf_ptr; 3228 uint16_t len = sizeof(wmi_pdev_pktlog_filter_cmd_fixed_param) + 3229 sizeof(wmi_pdev_pktlog_filter_info) + WMI_TLV_HDR_SIZE; 3230 3231 buf = wmi_buf_alloc(wmi_handle, len); 3232 if (!buf) 3233 return QDF_STATUS_E_NOMEM; 3234 3235 buf_ptr = (uint8_t *)wmi_buf_data(buf); 3236 cmd = (wmi_pdev_pktlog_filter_cmd_fixed_param *)buf_ptr; 3237 WMITLV_SET_HDR(&cmd->tlv_header, 3238 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_cmd_fixed_param, 3239 WMITLV_GET_STRUCT_TLVLEN 3240 (wmi_pdev_pktlog_filter_cmd_fixed_param)); 3241 cmd->pdev_id = mac_id; 3242 cmd->enable = enb_dsb; 3243 cmd->num_of_mac_addresses = 1; 3244 wmi_mtrace(WMI_PDEV_PKTLOG_FILTER_CMDID, cmd->pdev_id, 0); 3245 3246 buf_ptr += sizeof(*cmd); 3247 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3248 sizeof(wmi_pdev_pktlog_filter_info)); 3249 buf_ptr += WMI_TLV_HDR_SIZE; 3250 3251 mac_info = (wmi_pdev_pktlog_filter_info *)(buf_ptr); 3252 3253 WMITLV_SET_HDR(&mac_info->tlv_header, 3254 WMITLV_TAG_STRUC_wmi_pdev_pktlog_filter_info, 3255 WMITLV_GET_STRUCT_TLVLEN 3256 (wmi_pdev_pktlog_filter_info)); 3257 3258 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &mac_info->peer_mac_address); 3259 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3260 WMI_PDEV_PKTLOG_FILTER_CMDID); 3261 if (ret) { 3262 wmi_err("Failed to send peer based pktlog command to FW =%d" 3263 , ret); 3264 wmi_buf_free(buf); 3265 } 3266 3267 return ret; 3268 } 3269 3270 /** 3271 * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log 3272 * @wmi_handle: handle to WMI. 3273 * @PKTLOG_EVENT: packet log event 3274 * @mac_id: mac id to have radio context 3275 * 3276 * Return: QDF_STATUS_SUCCESS for success or error code 3277 */ 3278 static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, 3279 WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) 3280 { 3281 int32_t ret, idx, max_idx; 3282 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 3283 wmi_buf_t buf; 3284 uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); 3285 3286 buf = wmi_buf_alloc(wmi_handle, len); 3287 if (!buf) 3288 return -QDF_STATUS_E_NOMEM; 3289 3290 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); 3291 WMITLV_SET_HDR(&cmd->tlv_header, 3292 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 3293 WMITLV_GET_STRUCT_TLVLEN 3294 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 3295 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 3296 cmd->evlist = 0; 3297 for (idx = 0; idx < max_idx; idx++) { 3298 if (PKTLOG_EVENT & (1 << idx)) 3299 cmd->evlist |= pktlog_event_tlv[idx]; 3300 } 3301 cmd->pdev_id = mac_id; 3302 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, cmd->pdev_id, 0); 3303 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3304 WMI_PDEV_PKTLOG_ENABLE_CMDID); 3305 if (ret) { 3306 wmi_err("Failed to send pktlog enable cmd to FW =%d", ret); 3307 wmi_buf_free(buf); 3308 } 3309 3310 return ret; 3311 } 3312 3313 /** 3314 * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log 3315 * @wmi_handle: handle to WMI. 3316 * @mac_id: mac id to have radio context 3317 * 3318 * Return: QDF_STATUS_SUCCESS for success or error code 3319 */ 3320 static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, 3321 uint8_t mac_id) 3322 { 3323 int32_t ret; 3324 wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; 3325 wmi_buf_t buf; 3326 uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); 3327 3328 buf = wmi_buf_alloc(wmi_handle, len); 3329 if (!buf) 3330 return -QDF_STATUS_E_NOMEM; 3331 3332 cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); 3333 WMITLV_SET_HDR(&cmd->tlv_header, 3334 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 3335 WMITLV_GET_STRUCT_TLVLEN 3336 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 3337 cmd->pdev_id = mac_id; 3338 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, cmd->pdev_id, 0); 3339 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3340 WMI_PDEV_PKTLOG_DISABLE_CMDID); 3341 if (ret) { 3342 wmi_err("Failed to send pktlog disable cmd to FW =%d", ret); 3343 wmi_buf_free(buf); 3344 } 3345 3346 return ret; 3347 } 3348 3349 #define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff 3350 /** 3351 * send_time_stamp_sync_cmd_tlv() - Send WMI command to 3352 * sync time between between host and firmware 3353 * @wmi_handle: handle to WMI. 3354 * 3355 * Return: None 3356 */ 3357 static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) 3358 { 3359 wmi_buf_t buf; 3360 QDF_STATUS status = QDF_STATUS_SUCCESS; 3361 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; 3362 int32_t len; 3363 qdf_time_t time_ms; 3364 3365 len = sizeof(*time_stamp); 3366 buf = wmi_buf_alloc(wmi_handle, len); 3367 3368 if (!buf) 3369 return; 3370 3371 time_stamp = 3372 (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) 3373 (wmi_buf_data(buf)); 3374 WMITLV_SET_HDR(&time_stamp->tlv_header, 3375 WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, 3376 WMITLV_GET_STRUCT_TLVLEN( 3377 WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); 3378 3379 time_ms = qdf_get_time_of_the_day_ms(); 3380 time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; 3381 time_stamp->time_stamp_low = time_ms & 3382 WMI_FW_TIME_STAMP_LOW_MASK; 3383 /* 3384 * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms 3385 * won't exceed 27 bit 3386 */ 3387 time_stamp->time_stamp_high = 0; 3388 wmi_debug("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d", 3389 time_stamp->mode, time_stamp->time_stamp_low, 3390 time_stamp->time_stamp_high); 3391 3392 wmi_mtrace(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID, NO_SESSION, 0); 3393 status = wmi_unified_cmd_send(wmi_handle, buf, 3394 len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); 3395 if (status) { 3396 wmi_err("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); 3397 wmi_buf_free(buf); 3398 } 3399 3400 } 3401 3402 /** 3403 * send_fd_tmpl_cmd_tlv() - WMI FILS Discovery send function 3404 * @wmi_handle: handle to WMI. 3405 * @param: pointer to hold FILS Discovery send cmd parameter 3406 * 3407 * Return: QDF_STATUS_SUCCESS for success or error code 3408 */ 3409 static QDF_STATUS send_fd_tmpl_cmd_tlv(wmi_unified_t wmi_handle, 3410 struct fils_discovery_tmpl_params *param) 3411 { 3412 int32_t ret; 3413 wmi_fd_tmpl_cmd_fixed_param *cmd; 3414 wmi_buf_t wmi_buf; 3415 uint8_t *buf_ptr; 3416 uint32_t wmi_buf_len; 3417 3418 wmi_buf_len = sizeof(wmi_fd_tmpl_cmd_fixed_param) + 3419 WMI_TLV_HDR_SIZE + param->tmpl_len_aligned; 3420 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3421 if (!wmi_buf) 3422 return QDF_STATUS_E_NOMEM; 3423 3424 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3425 cmd = (wmi_fd_tmpl_cmd_fixed_param *) buf_ptr; 3426 WMITLV_SET_HDR(&cmd->tlv_header, 3427 WMITLV_TAG_STRUC_wmi_fd_tmpl_cmd_fixed_param, 3428 WMITLV_GET_STRUCT_TLVLEN(wmi_fd_tmpl_cmd_fixed_param)); 3429 cmd->vdev_id = param->vdev_id; 3430 cmd->buf_len = param->tmpl_len; 3431 buf_ptr += sizeof(wmi_fd_tmpl_cmd_fixed_param); 3432 3433 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3434 buf_ptr += WMI_TLV_HDR_SIZE; 3435 qdf_mem_copy(buf_ptr, param->frm, param->tmpl_len); 3436 3437 wmi_mtrace(WMI_FD_TMPL_CMDID, cmd->vdev_id, 0); 3438 ret = wmi_unified_cmd_send(wmi_handle, 3439 wmi_buf, wmi_buf_len, WMI_FD_TMPL_CMDID); 3440 3441 if (ret) { 3442 wmi_err("Failed to send fd tmpl: %d", ret); 3443 wmi_buf_free(wmi_buf); 3444 return ret; 3445 } 3446 3447 return 0; 3448 } 3449 3450 /** 3451 * send_beacon_tmpl_send_cmd_tlv() - WMI beacon send function 3452 * @wmi_handle: handle to WMI. 3453 * @param: pointer to hold beacon send cmd parameter 3454 * 3455 * Return: QDF_STATUS_SUCCESS for success or error code 3456 */ 3457 static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 3458 struct beacon_tmpl_params *param) 3459 { 3460 int32_t ret; 3461 wmi_bcn_tmpl_cmd_fixed_param *cmd; 3462 wmi_bcn_prb_info *bcn_prb_info; 3463 wmi_buf_t wmi_buf; 3464 uint8_t *buf_ptr; 3465 uint32_t wmi_buf_len; 3466 3467 wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + 3468 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 3469 param->tmpl_len_aligned + 3470 bcn_tmpl_mlo_param_size(param) + 3471 bcn_tmpl_ml_info_size(param); 3472 3473 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 3474 if (!wmi_buf) 3475 return QDF_STATUS_E_NOMEM; 3476 3477 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 3478 cmd = (wmi_bcn_tmpl_cmd_fixed_param *) buf_ptr; 3479 WMITLV_SET_HDR(&cmd->tlv_header, 3480 WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, 3481 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); 3482 cmd->vdev_id = param->vdev_id; 3483 cmd->tim_ie_offset = param->tim_ie_offset; 3484 cmd->mbssid_ie_offset = param->mbssid_ie_offset; 3485 cmd->csa_switch_count_offset = param->csa_switch_count_offset; 3486 cmd->ext_csa_switch_count_offset = param->ext_csa_switch_count_offset; 3487 cmd->esp_ie_offset = param->esp_ie_offset; 3488 cmd->mu_edca_ie_offset = param->mu_edca_ie_offset; 3489 cmd->ema_params = param->ema_params; 3490 cmd->buf_len = param->tmpl_len; 3491 cmd->csa_event_bitmap = param->csa_event_bitmap; 3492 3493 WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap, 3494 param->enable_bigtk); 3495 buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); 3496 3497 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 3498 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 3499 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 3500 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 3501 bcn_prb_info->caps = 0; 3502 bcn_prb_info->erp = 0; 3503 buf_ptr += sizeof(wmi_bcn_prb_info); 3504 3505 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->tmpl_len_aligned); 3506 buf_ptr += WMI_TLV_HDR_SIZE; 3507 3508 /* for big endian host, copy engine byte_swap is enabled 3509 * But the frame content is in network byte order 3510 * Need to byte swap the frame content - so when copy engine 3511 * does byte_swap - target gets frame content in the correct order 3512 */ 3513 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(buf_ptr, param->frm, 3514 param->tmpl_len); 3515 3516 buf_ptr += roundup(param->tmpl_len, sizeof(uint32_t)); 3517 buf_ptr = bcn_tmpl_add_ml_partner_links(buf_ptr, param); 3518 3519 buf_ptr = bcn_tmpl_add_ml_info(buf_ptr, param); 3520 3521 wmi_mtrace(WMI_BCN_TMPL_CMDID, cmd->vdev_id, 0); 3522 ret = wmi_unified_cmd_send(wmi_handle, 3523 wmi_buf, wmi_buf_len, WMI_BCN_TMPL_CMDID); 3524 if (ret) { 3525 wmi_err("Failed to send bcn tmpl: %d", ret); 3526 wmi_buf_free(wmi_buf); 3527 } 3528 3529 return 0; 3530 } 3531 3532 #ifdef WLAN_FEATURE_11BE 3533 static inline void copy_peer_flags_tlv_11be( 3534 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3535 struct peer_assoc_params *param) 3536 { 3537 if (param->bw_320) 3538 cmd->peer_flags_ext |= WMI_PEER_EXT_320MHZ; 3539 if (param->eht_flag) 3540 cmd->peer_flags_ext |= WMI_PEER_EXT_EHT; 3541 3542 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3543 } 3544 #else 3545 static inline void copy_peer_flags_tlv_11be( 3546 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3547 struct peer_assoc_params *param) 3548 { 3549 } 3550 #endif 3551 #ifdef WLAN_FEATURE_11BE_MLO 3552 static inline void copy_peer_flags_tlv_vendor( 3553 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3554 struct peer_assoc_params *param) 3555 { 3556 if (!(param->mlo_params.mlo_enabled)) 3557 return; 3558 if (param->qcn_node_flag) 3559 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_QUALCOMM_NODE; 3560 if (param->mesh_node_flag) 3561 cmd->peer_flags_ext |= WMI_PEER_EXT_IS_MESH_NODE; 3562 3563 wmi_debug("peer_flags_ext 0x%x", cmd->peer_flags_ext); 3564 } 3565 #else 3566 static inline void copy_peer_flags_tlv_vendor( 3567 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3568 struct peer_assoc_params *param) 3569 { 3570 } 3571 #endif 3572 3573 static inline void copy_peer_flags_tlv( 3574 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3575 struct peer_assoc_params *param) 3576 { 3577 /* 3578 * The target only needs a subset of the flags maintained in the host. 3579 * Just populate those flags and send it down 3580 */ 3581 cmd->peer_flags = 0; 3582 if (param->peer_dms_capable) 3583 cmd->peer_flags_ext |= WMI_PEER_EXT_DMS_CAPABLE; 3584 /* 3585 * Do not enable HT/VHT if WMM/wme is disabled for vap. 3586 */ 3587 if (param->is_wme_set) { 3588 3589 if (param->qos_flag) 3590 cmd->peer_flags |= WMI_PEER_QOS; 3591 if (param->apsd_flag) 3592 cmd->peer_flags |= WMI_PEER_APSD; 3593 if (param->ht_flag) 3594 cmd->peer_flags |= WMI_PEER_HT; 3595 if (param->bw_40) 3596 cmd->peer_flags |= WMI_PEER_40MHZ; 3597 if (param->bw_80) 3598 cmd->peer_flags |= WMI_PEER_80MHZ; 3599 if (param->bw_160) 3600 cmd->peer_flags |= WMI_PEER_160MHZ; 3601 3602 copy_peer_flags_tlv_11be(cmd, param); 3603 copy_peer_flags_tlv_vendor(cmd, param); 3604 3605 /* Typically if STBC is enabled for VHT it should be enabled 3606 * for HT as well 3607 **/ 3608 if (param->stbc_flag) 3609 cmd->peer_flags |= WMI_PEER_STBC; 3610 3611 /* Typically if LDPC is enabled for VHT it should be enabled 3612 * for HT as well 3613 **/ 3614 if (param->ldpc_flag) 3615 cmd->peer_flags |= WMI_PEER_LDPC; 3616 3617 if (param->static_mimops_flag) 3618 cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; 3619 if (param->dynamic_mimops_flag) 3620 cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; 3621 if (param->spatial_mux_flag) 3622 cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; 3623 if (param->vht_flag) 3624 cmd->peer_flags |= WMI_PEER_VHT; 3625 if (param->he_flag) 3626 cmd->peer_flags |= WMI_PEER_HE; 3627 if (param->p2p_capable_sta) 3628 cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; 3629 } 3630 3631 if (param->is_pmf_enabled) 3632 cmd->peer_flags |= WMI_PEER_PMF; 3633 /* 3634 * Suppress authorization for all AUTH modes that need 4-way handshake 3635 * (during re-association). 3636 * Authorization will be done for these modes on key installation. 3637 */ 3638 if (param->auth_flag) 3639 cmd->peer_flags |= WMI_PEER_AUTH; 3640 if (param->need_ptk_4_way) 3641 cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; 3642 else 3643 cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY; 3644 if (param->need_gtk_2_way) 3645 cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; 3646 /* safe mode bypass the 4-way handshake */ 3647 if (param->safe_mode_enabled) 3648 cmd->peer_flags &= 3649 ~(WMI_PEER_NEED_PTK_4_WAY | WMI_PEER_NEED_GTK_2_WAY); 3650 /* inter BSS peer */ 3651 if (param->inter_bss_peer) 3652 cmd->peer_flags |= WMI_PEER_INTER_BSS_PEER; 3653 /* Disable AMSDU for station transmit, if user configures it */ 3654 /* Disable AMSDU for AP transmit to 11n Stations, if user configures 3655 * it 3656 * if (param->amsdu_disable) Add after FW support 3657 **/ 3658 3659 /* Target asserts if node is marked HT and all MCS is set to 0. 3660 * Mark the node as non-HT if all the mcs rates are disabled through 3661 * iwpriv 3662 **/ 3663 if (param->peer_ht_rates.num_rates == 0) 3664 cmd->peer_flags &= ~WMI_PEER_HT; 3665 3666 if (param->twt_requester) 3667 cmd->peer_flags |= WMI_PEER_TWT_REQ; 3668 3669 if (param->twt_responder) 3670 cmd->peer_flags |= WMI_PEER_TWT_RESP; 3671 } 3672 3673 static inline void copy_peer_mac_addr_tlv( 3674 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3675 struct peer_assoc_params *param) 3676 { 3677 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 3678 } 3679 3680 #ifdef WLAN_FEATURE_11BE 3681 static uint8_t *update_peer_flags_tlv_ehtinfo( 3682 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3683 struct peer_assoc_params *param, uint8_t *buf_ptr) 3684 { 3685 wmi_eht_rate_set *eht_mcs; 3686 int i; 3687 3688 cmd->peer_eht_ops = param->peer_eht_ops; 3689 cmd->puncture_20mhz_bitmap = ~param->puncture_bitmap; 3690 3691 qdf_mem_copy(&cmd->peer_eht_cap_mac, ¶m->peer_eht_cap_macinfo, 3692 sizeof(param->peer_eht_cap_macinfo)); 3693 qdf_mem_copy(&cmd->peer_eht_cap_phy, ¶m->peer_eht_cap_phyinfo, 3694 sizeof(param->peer_eht_cap_phyinfo)); 3695 qdf_mem_copy(&cmd->peer_eht_ppet, ¶m->peer_eht_ppet, 3696 sizeof(param->peer_eht_ppet)); 3697 3698 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3699 (param->peer_eht_mcs_count * sizeof(wmi_eht_rate_set))); 3700 buf_ptr += WMI_TLV_HDR_SIZE; 3701 3702 /* Loop through the EHT rate set */ 3703 for (i = 0; i < param->peer_eht_mcs_count; i++) { 3704 eht_mcs = (wmi_eht_rate_set *)buf_ptr; 3705 WMITLV_SET_HDR(eht_mcs, WMITLV_TAG_STRUC_wmi_eht_rate_set, 3706 WMITLV_GET_STRUCT_TLVLEN(wmi_eht_rate_set)); 3707 3708 eht_mcs->rx_mcs_set = param->peer_eht_rx_mcs_set[i]; 3709 eht_mcs->tx_mcs_set = param->peer_eht_tx_mcs_set[i]; 3710 wmi_debug("EHT idx %d RxMCSmap %x TxMCSmap %x ", 3711 i, eht_mcs->rx_mcs_set, eht_mcs->tx_mcs_set); 3712 buf_ptr += sizeof(wmi_eht_rate_set); 3713 } 3714 3715 wmi_debug("nss %d ru mask 0x%x", 3716 cmd->peer_eht_ppet.numss_m1, cmd->peer_eht_ppet.ru_mask); 3717 for (i = 0; i < WMI_MAX_NUM_SS; i++) { 3718 wmi_debug("ppet idx %d ppet %x ", 3719 i, cmd->peer_eht_ppet.ppet16_ppet8_ru3_ru0[i]); 3720 } 3721 3722 if ((param->eht_flag) && (param->peer_eht_mcs_count > 1) && 3723 (param->peer_eht_rx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3724 == WMI_HOST_EHT_INVALID_MCSNSSMAP || 3725 param->peer_eht_tx_mcs_set[WMI_HOST_EHT_TXRX_MCS_NSS_IDX_160] 3726 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3727 wmi_debug("param->peer_eht_tx_mcs_set[160MHz]=%x", 3728 param->peer_eht_tx_mcs_set 3729 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3730 wmi_debug("param->peer_eht_rx_mcs_set[160MHz]=%x", 3731 param->peer_eht_rx_mcs_set 3732 [WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3733 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3734 QDF_MAC_ADDR_REF(param->peer_mac)); 3735 } 3736 3737 wmi_debug("EHT cap_mac %x %x ehtops %x EHT phy %x %x %x pp %x", 3738 cmd->peer_eht_cap_mac[0], 3739 cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, 3740 cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1], 3741 cmd->peer_eht_cap_phy[2], cmd->puncture_20mhz_bitmap); 3742 3743 return buf_ptr; 3744 } 3745 #else 3746 static uint8_t *update_peer_flags_tlv_ehtinfo( 3747 wmi_peer_assoc_complete_cmd_fixed_param * cmd, 3748 struct peer_assoc_params *param, uint8_t *buf_ptr) 3749 { 3750 return buf_ptr; 3751 } 3752 #endif 3753 3754 #ifdef WLAN_FEATURE_11BE 3755 static 3756 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3757 { 3758 return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count 3759 + WMI_TLV_HDR_SIZE); 3760 } 3761 3762 static void wmi_populate_service_11be(uint32_t *wmi_service) 3763 { 3764 wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; 3765 } 3766 3767 #else 3768 static 3769 uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) 3770 { 3771 return 0; 3772 } 3773 3774 static void wmi_populate_service_11be(uint32_t *wmi_service) 3775 { 3776 } 3777 3778 #endif 3779 3780 /** 3781 * send_peer_assoc_cmd_tlv() - WMI peer assoc function 3782 * @wmi_handle: handle to WMI. 3783 * @param: pointer to peer assoc parameter 3784 * 3785 * Return: QDF_STATUS_SUCCESS for success or error code 3786 */ 3787 static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, 3788 struct peer_assoc_params *param) 3789 { 3790 wmi_peer_assoc_complete_cmd_fixed_param *cmd; 3791 wmi_vht_rate_set *mcs; 3792 wmi_he_rate_set *he_mcs; 3793 wmi_buf_t buf; 3794 int32_t len; 3795 uint8_t *buf_ptr; 3796 QDF_STATUS ret; 3797 uint32_t peer_legacy_rates_align; 3798 uint32_t peer_ht_rates_align; 3799 int32_t i; 3800 3801 3802 peer_legacy_rates_align = wmi_align(param->peer_legacy_rates.num_rates); 3803 peer_ht_rates_align = wmi_align(param->peer_ht_rates.num_rates); 3804 3805 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 3806 (peer_legacy_rates_align * sizeof(uint8_t)) + 3807 WMI_TLV_HDR_SIZE + 3808 (peer_ht_rates_align * sizeof(uint8_t)) + 3809 sizeof(wmi_vht_rate_set) + 3810 (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count 3811 + WMI_TLV_HDR_SIZE) 3812 + wmi_eht_peer_assoc_params_len(param) + 3813 peer_assoc_mlo_params_size(param) + 3814 peer_assoc_t2lm_params_size(param); 3815 3816 buf = wmi_buf_alloc(wmi_handle, len); 3817 if (!buf) 3818 return QDF_STATUS_E_NOMEM; 3819 3820 buf_ptr = (uint8_t *) wmi_buf_data(buf); 3821 cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; 3822 WMITLV_SET_HDR(&cmd->tlv_header, 3823 WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, 3824 WMITLV_GET_STRUCT_TLVLEN 3825 (wmi_peer_assoc_complete_cmd_fixed_param)); 3826 3827 cmd->vdev_id = param->vdev_id; 3828 3829 cmd->peer_new_assoc = param->peer_new_assoc; 3830 cmd->peer_associd = param->peer_associd; 3831 3832 copy_peer_flags_tlv(cmd, param); 3833 copy_peer_mac_addr_tlv(cmd, param); 3834 3835 cmd->peer_rate_caps = param->peer_rate_caps; 3836 cmd->peer_caps = param->peer_caps; 3837 cmd->peer_listen_intval = param->peer_listen_intval; 3838 cmd->peer_ht_caps = param->peer_ht_caps; 3839 cmd->peer_max_mpdu = param->peer_max_mpdu; 3840 cmd->peer_mpdu_density = param->peer_mpdu_density; 3841 cmd->peer_vht_caps = param->peer_vht_caps; 3842 cmd->peer_phymode = param->peer_phymode; 3843 cmd->bss_max_idle_option = param->peer_bss_max_idle_option; 3844 3845 /* Update 11ax capabilities */ 3846 cmd->peer_he_cap_info = 3847 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD1]; 3848 cmd->peer_he_cap_info_ext = 3849 param->peer_he_cap_macinfo[WMI_HOST_HECAP_MAC_WORD2]; 3850 cmd->peer_he_cap_info_internal = param->peer_he_cap_info_internal; 3851 cmd->peer_he_ops = param->peer_he_ops; 3852 qdf_mem_copy(&cmd->peer_he_cap_phy, ¶m->peer_he_cap_phyinfo, 3853 sizeof(param->peer_he_cap_phyinfo)); 3854 qdf_mem_copy(&cmd->peer_ppet, ¶m->peer_ppet, 3855 sizeof(param->peer_ppet)); 3856 cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz; 3857 3858 /* Update peer legacy rate information */ 3859 buf_ptr += sizeof(*cmd); 3860 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3861 peer_legacy_rates_align); 3862 buf_ptr += WMI_TLV_HDR_SIZE; 3863 cmd->num_peer_legacy_rates = param->peer_legacy_rates.num_rates; 3864 qdf_mem_copy(buf_ptr, param->peer_legacy_rates.rates, 3865 param->peer_legacy_rates.num_rates); 3866 3867 /* Update peer HT rate information */ 3868 buf_ptr += peer_legacy_rates_align; 3869 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 3870 peer_ht_rates_align); 3871 buf_ptr += WMI_TLV_HDR_SIZE; 3872 cmd->num_peer_ht_rates = param->peer_ht_rates.num_rates; 3873 qdf_mem_copy(buf_ptr, param->peer_ht_rates.rates, 3874 param->peer_ht_rates.num_rates); 3875 3876 /* VHT Rates */ 3877 buf_ptr += peer_ht_rates_align; 3878 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, 3879 WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); 3880 3881 cmd->auth_mode = param->akm; 3882 cmd->peer_nss = param->peer_nss; 3883 3884 /* Update bandwidth-NSS mapping */ 3885 cmd->peer_bw_rxnss_override = 0; 3886 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 3887 3888 mcs = (wmi_vht_rate_set *) buf_ptr; 3889 if (param->vht_capable) { 3890 mcs->rx_max_rate = param->rx_max_rate; 3891 mcs->rx_mcs_set = param->rx_mcs_set; 3892 mcs->tx_max_rate = param->tx_max_rate; 3893 mcs->tx_mcs_set = param->tx_mcs_set; 3894 mcs->tx_max_mcs_nss = param->tx_max_mcs_nss; 3895 } 3896 3897 /* HE Rates */ 3898 cmd->min_data_rate = param->min_data_rate; 3899 cmd->peer_he_mcs = param->peer_he_mcs_count; 3900 buf_ptr += sizeof(wmi_vht_rate_set); 3901 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 3902 (param->peer_he_mcs_count * sizeof(wmi_he_rate_set))); 3903 buf_ptr += WMI_TLV_HDR_SIZE; 3904 3905 WMI_PEER_STA_TYPE_SET(cmd->sta_type, param->peer_bsscolor_rept_info); 3906 /* Loop through the HE rate set */ 3907 for (i = 0; i < param->peer_he_mcs_count; i++) { 3908 he_mcs = (wmi_he_rate_set *) buf_ptr; 3909 WMITLV_SET_HDR(he_mcs, WMITLV_TAG_STRUC_wmi_he_rate_set, 3910 WMITLV_GET_STRUCT_TLVLEN(wmi_he_rate_set)); 3911 3912 he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 3913 he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 3914 wmi_debug("HE idx %d RxMCSmap %x TxMCSmap %x ", 3915 i, he_mcs->rx_mcs_set, he_mcs->tx_mcs_set); 3916 buf_ptr += sizeof(wmi_he_rate_set); 3917 } 3918 3919 if ((param->he_flag) && (param->peer_he_mcs_count > 1) && 3920 (param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3921 == WMI_HOST_HE_INVALID_MCSNSSMAP || 3922 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160] 3923 == WMI_HOST_HE_INVALID_MCSNSSMAP)) { 3924 wmi_debug("param->peer_he_tx_mcs_set[160MHz]=%x", 3925 param->peer_he_tx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3926 wmi_debug("param->peer_he_rx_mcs_set[160MHz]=%x", 3927 param->peer_he_rx_mcs_set[WMI_HOST_HE_TXRX_MCS_NSS_IDX_160]); 3928 wmi_debug("peer_mac="QDF_MAC_ADDR_FMT, 3929 QDF_MAC_ADDR_REF(param->peer_mac)); 3930 } 3931 3932 wmi_debug("vdev_id %d associd %d peer_flags %x rate_caps %x " 3933 "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " 3934 "nss %d phymode %d peer_mpdu_density %d " 3935 "cmd->peer_vht_caps %x " 3936 "HE cap_info %x ops %x " 3937 "HE cap_info_ext %x " 3938 "HE phy %x %x %x " 3939 "peer_bw_rxnss_override %x", 3940 cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, 3941 cmd->peer_rate_caps, cmd->peer_caps, 3942 cmd->peer_listen_intval, cmd->peer_ht_caps, 3943 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, 3944 cmd->peer_mpdu_density, 3945 cmd->peer_vht_caps, cmd->peer_he_cap_info, 3946 cmd->peer_he_ops, cmd->peer_he_cap_info_ext, 3947 cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1], 3948 cmd->peer_he_cap_phy[2], 3949 cmd->peer_bw_rxnss_override); 3950 3951 buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); 3952 3953 buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); 3954 3955 buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); 3956 3957 buf_ptr = peer_assoc_add_tid_to_link_map(buf_ptr, param); 3958 3959 wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); 3960 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 3961 WMI_PEER_ASSOC_CMDID); 3962 if (QDF_IS_STATUS_ERROR(ret)) { 3963 wmi_err("Failed to send peer assoc command ret = %d", ret); 3964 wmi_buf_free(buf); 3965 } 3966 3967 return ret; 3968 } 3969 3970 /* copy_scan_notify_events() - Helper routine to copy scan notify events 3971 */ 3972 static inline void copy_scan_event_cntrl_flags( 3973 wmi_start_scan_cmd_fixed_param * cmd, 3974 struct scan_req_params *param) 3975 { 3976 3977 /* Scan events subscription */ 3978 if (param->scan_ev_started) 3979 cmd->notify_scan_events |= WMI_SCAN_EVENT_STARTED; 3980 if (param->scan_ev_completed) 3981 cmd->notify_scan_events |= WMI_SCAN_EVENT_COMPLETED; 3982 if (param->scan_ev_bss_chan) 3983 cmd->notify_scan_events |= WMI_SCAN_EVENT_BSS_CHANNEL; 3984 if (param->scan_ev_foreign_chan) 3985 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL; 3986 if (param->scan_ev_dequeued) 3987 cmd->notify_scan_events |= WMI_SCAN_EVENT_DEQUEUED; 3988 if (param->scan_ev_preempted) 3989 cmd->notify_scan_events |= WMI_SCAN_EVENT_PREEMPTED; 3990 if (param->scan_ev_start_failed) 3991 cmd->notify_scan_events |= WMI_SCAN_EVENT_START_FAILED; 3992 if (param->scan_ev_restarted) 3993 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESTARTED; 3994 if (param->scan_ev_foreign_chn_exit) 3995 cmd->notify_scan_events |= WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT; 3996 if (param->scan_ev_suspended) 3997 cmd->notify_scan_events |= WMI_SCAN_EVENT_SUSPENDED; 3998 if (param->scan_ev_resumed) 3999 cmd->notify_scan_events |= WMI_SCAN_EVENT_RESUMED; 4000 4001 /** Set scan control flags */ 4002 cmd->scan_ctrl_flags = 0; 4003 if (param->scan_f_passive) 4004 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; 4005 if (param->scan_f_strict_passive_pch) 4006 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN; 4007 if (param->scan_f_promisc_mode) 4008 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROMISCOUS; 4009 if (param->scan_f_capture_phy_err) 4010 cmd->scan_ctrl_flags |= WMI_SCAN_CAPTURE_PHY_ERROR; 4011 if (param->scan_f_half_rate) 4012 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_HALF_RATE_SUPPORT; 4013 if (param->scan_f_quarter_rate) 4014 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT; 4015 if (param->scan_f_cck_rates) 4016 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; 4017 if (param->scan_f_ofdm_rates) 4018 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; 4019 if (param->scan_f_chan_stat_evnt) 4020 cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; 4021 if (param->scan_f_filter_prb_req) 4022 cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; 4023 if (param->scan_f_bcast_probe) 4024 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; 4025 if (param->scan_f_offchan_mgmt_tx) 4026 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_MGMT_TX; 4027 if (param->scan_f_offchan_data_tx) 4028 cmd->scan_ctrl_flags |= WMI_SCAN_OFFCHAN_DATA_TX; 4029 if (param->scan_f_force_active_dfs_chn) 4030 cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; 4031 if (param->scan_f_add_tpc_ie_in_probe) 4032 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; 4033 if (param->scan_f_add_ds_ie_in_probe) 4034 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; 4035 if (param->scan_f_add_spoofed_mac_in_probe) 4036 cmd->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; 4037 if (param->scan_f_add_rand_seq_in_probe) 4038 cmd->scan_ctrl_flags |= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ; 4039 if (param->scan_f_en_ie_allowlist_in_probe) 4040 cmd->scan_ctrl_flags |= 4041 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ; 4042 if (param->scan_f_pause_home_channel) 4043 cmd->scan_ctrl_flags |= 4044 WMI_SCAN_FLAG_PAUSE_HOME_CHANNEL; 4045 if (param->scan_f_report_cca_busy_for_each_20mhz) 4046 cmd->scan_ctrl_flags |= 4047 WMI_SCAN_FLAG_REPORT_CCA_BUSY_FOREACH_20MHZ; 4048 4049 /* for adaptive scan mode using 3 bits (21 - 23 bits) */ 4050 WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, 4051 param->adaptive_dwell_time_mode); 4052 } 4053 4054 /* scan_copy_ie_buffer() - Copy scan ie_data */ 4055 static inline void scan_copy_ie_buffer(uint8_t *buf_ptr, 4056 struct scan_req_params *params) 4057 { 4058 qdf_mem_copy(buf_ptr, params->extraie.ptr, params->extraie.len); 4059 } 4060 4061 /** 4062 * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer 4063 * @mac: random mac addr 4064 * @mask: random mac mask 4065 * @mac_addr: wmi random mac 4066 * @mac_mask: wmi random mac mask 4067 * 4068 * Return None. 4069 */ 4070 static inline 4071 void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, 4072 wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) 4073 { 4074 WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); 4075 WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); 4076 } 4077 4078 /* 4079 * wmi_fill_vendor_oui() - fill vendor OUIs 4080 * @buf_ptr: pointer to wmi tlv buffer 4081 * @num_vendor_oui: number of vendor OUIs to be filled 4082 * @param_voui: pointer to OUI buffer 4083 * 4084 * This function populates the wmi tlv buffer when vendor specific OUIs are 4085 * present. 4086 * 4087 * Return: None 4088 */ 4089 static inline 4090 void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui, 4091 uint32_t *pvoui) 4092 { 4093 wmi_vendor_oui *voui = NULL; 4094 uint32_t i; 4095 4096 voui = (wmi_vendor_oui *)buf_ptr; 4097 4098 for (i = 0; i < num_vendor_oui; i++) { 4099 WMITLV_SET_HDR(&voui[i].tlv_header, 4100 WMITLV_TAG_STRUC_wmi_vendor_oui, 4101 WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui)); 4102 voui[i].oui_type_subtype = pvoui[i]; 4103 } 4104 } 4105 4106 /* 4107 * wmi_fill_ie_allowlist_attrs() - fill IE allowlist attrs 4108 * @ie_bitmap: output pointer to ie bit map in cmd 4109 * @num_vendor_oui: output pointer to num vendor OUIs 4110 * @ie_allowlist: input parameter 4111 * 4112 * This function populates the IE allowlist attrs of scan, pno and 4113 * scan oui commands for ie_allowlist parameter. 4114 * 4115 * Return: None 4116 */ 4117 static inline 4118 void wmi_fill_ie_allowlist_attrs(uint32_t *ie_bitmap, 4119 uint32_t *num_vendor_oui, 4120 struct probe_req_allowlist_attr *ie_allowlist) 4121 { 4122 uint32_t i = 0; 4123 4124 for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++) 4125 ie_bitmap[i] = ie_allowlist->ie_bitmap[i]; 4126 4127 *num_vendor_oui = ie_allowlist->num_vendor_oui; 4128 } 4129 4130 /** 4131 * send_scan_start_cmd_tlv() - WMI scan start function 4132 * @wmi_handle: handle to WMI. 4133 * @params: pointer to hold scan start cmd parameter 4134 * 4135 * Return: QDF_STATUS_SUCCESS for success or error code 4136 */ 4137 static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, 4138 struct scan_req_params *params) 4139 { 4140 int32_t ret = 0; 4141 int32_t i; 4142 wmi_buf_t wmi_buf; 4143 wmi_start_scan_cmd_fixed_param *cmd; 4144 uint8_t *buf_ptr; 4145 uint32_t *tmp_ptr; 4146 wmi_ssid *ssid = NULL; 4147 wmi_mac_addr *bssid; 4148 size_t len = sizeof(*cmd); 4149 uint16_t extraie_len_with_pad = 0; 4150 uint8_t phymode_roundup = 0; 4151 struct probe_req_allowlist_attr *ie_allowlist = ¶ms->ie_allowlist; 4152 wmi_hint_freq_short_ssid *s_ssid = NULL; 4153 wmi_hint_freq_bssid *hint_bssid = NULL; 4154 4155 /* Length TLV placeholder for array of uint32_t */ 4156 len += WMI_TLV_HDR_SIZE; 4157 /* calculate the length of buffer required */ 4158 if (params->chan_list.num_chan) 4159 len += params->chan_list.num_chan * sizeof(uint32_t); 4160 4161 /* Length TLV placeholder for array of wmi_ssid structures */ 4162 len += WMI_TLV_HDR_SIZE; 4163 if (params->num_ssids) 4164 len += params->num_ssids * sizeof(wmi_ssid); 4165 4166 /* Length TLV placeholder for array of wmi_mac_addr structures */ 4167 len += WMI_TLV_HDR_SIZE; 4168 if (params->num_bssid) 4169 len += sizeof(wmi_mac_addr) * params->num_bssid; 4170 4171 /* Length TLV placeholder for array of bytes */ 4172 len += WMI_TLV_HDR_SIZE; 4173 if (params->extraie.len) 4174 extraie_len_with_pad = 4175 roundup(params->extraie.len, sizeof(uint32_t)); 4176 len += extraie_len_with_pad; 4177 4178 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */ 4179 if (ie_allowlist->num_vendor_oui) 4180 len += ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 4181 4182 len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ 4183 if (params->scan_f_wide_band) 4184 phymode_roundup = 4185 qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), 4186 sizeof(uint32_t)); 4187 len += phymode_roundup; 4188 4189 len += WMI_TLV_HDR_SIZE; 4190 if (params->num_hint_bssid) 4191 len += params->num_hint_bssid * sizeof(wmi_hint_freq_bssid); 4192 4193 len += WMI_TLV_HDR_SIZE; 4194 if (params->num_hint_s_ssid) 4195 len += params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid); 4196 4197 /* Allocate the memory */ 4198 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4199 if (!wmi_buf) 4200 return QDF_STATUS_E_FAILURE; 4201 4202 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 4203 cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; 4204 WMITLV_SET_HDR(&cmd->tlv_header, 4205 WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, 4206 WMITLV_GET_STRUCT_TLVLEN 4207 (wmi_start_scan_cmd_fixed_param)); 4208 4209 cmd->scan_id = params->scan_id; 4210 cmd->scan_req_id = params->scan_req_id; 4211 cmd->vdev_id = params->vdev_id; 4212 cmd->scan_priority = params->scan_priority; 4213 4214 copy_scan_event_cntrl_flags(cmd, params); 4215 4216 cmd->dwell_time_active = params->dwell_time_active; 4217 cmd->dwell_time_active_2g = params->dwell_time_active_2g; 4218 cmd->dwell_time_passive = params->dwell_time_passive; 4219 cmd->min_dwell_time_6ghz = params->min_dwell_time_6g; 4220 cmd->dwell_time_active_6ghz = params->dwell_time_active_6g; 4221 cmd->dwell_time_passive_6ghz = params->dwell_time_passive_6g; 4222 cmd->scan_start_offset = params->scan_offset_time; 4223 cmd->min_rest_time = params->min_rest_time; 4224 cmd->max_rest_time = params->max_rest_time; 4225 cmd->repeat_probe_time = params->repeat_probe_time; 4226 cmd->probe_spacing_time = params->probe_spacing_time; 4227 cmd->idle_time = params->idle_time; 4228 cmd->max_scan_time = params->max_scan_time; 4229 cmd->probe_delay = params->probe_delay; 4230 cmd->burst_duration = params->burst_duration; 4231 cmd->num_chan = params->chan_list.num_chan; 4232 cmd->num_bssid = params->num_bssid; 4233 cmd->num_ssids = params->num_ssids; 4234 cmd->ie_len = params->extraie.len; 4235 cmd->n_probes = params->n_probes; 4236 cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext; 4237 WMI_SCAN_MLD_PARAM_MLD_ID_SET(cmd->mld_parameter, params->mld_id); 4238 wmi_debug("MLD ID: %u", cmd->mld_parameter); 4239 4240 if (params->scan_random.randomize) 4241 wmi_copy_scan_random_mac(params->scan_random.mac_addr, 4242 params->scan_random.mac_mask, 4243 &cmd->mac_addr, 4244 &cmd->mac_mask); 4245 4246 if (ie_allowlist->allow_list) 4247 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 4248 &cmd->num_vendor_oui, 4249 ie_allowlist); 4250 4251 buf_ptr += sizeof(*cmd); 4252 tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4253 for (i = 0; i < params->chan_list.num_chan; ++i) { 4254 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(tmp_ptr[i], 4255 params->chan_list.chan[i].freq); 4256 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(tmp_ptr[i], 4257 params->chan_list.chan[i].flags); 4258 } 4259 4260 WMITLV_SET_HDR(buf_ptr, 4261 WMITLV_TAG_ARRAY_UINT32, 4262 (params->chan_list.num_chan * sizeof(uint32_t))); 4263 buf_ptr += WMI_TLV_HDR_SIZE + 4264 (params->chan_list.num_chan * sizeof(uint32_t)); 4265 4266 if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { 4267 wmi_err("Invalid value for num_ssids %d", params->num_ssids); 4268 goto error; 4269 } 4270 4271 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4272 (params->num_ssids * sizeof(wmi_ssid))); 4273 4274 if (params->num_ssids) { 4275 ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); 4276 for (i = 0; i < params->num_ssids; ++i) { 4277 ssid->ssid_len = params->ssid[i].length; 4278 qdf_mem_copy(ssid->ssid, params->ssid[i].ssid, 4279 params->ssid[i].length); 4280 ssid++; 4281 } 4282 } 4283 buf_ptr += WMI_TLV_HDR_SIZE + (params->num_ssids * sizeof(wmi_ssid)); 4284 4285 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4286 (params->num_bssid * sizeof(wmi_mac_addr))); 4287 bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); 4288 4289 if (params->num_bssid) { 4290 for (i = 0; i < params->num_bssid; ++i) { 4291 WMI_CHAR_ARRAY_TO_MAC_ADDR( 4292 ¶ms->bssid_list[i].bytes[0], bssid); 4293 bssid++; 4294 } 4295 } 4296 4297 buf_ptr += WMI_TLV_HDR_SIZE + 4298 (params->num_bssid * sizeof(wmi_mac_addr)); 4299 4300 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, extraie_len_with_pad); 4301 if (params->extraie.len) 4302 scan_copy_ie_buffer(buf_ptr + WMI_TLV_HDR_SIZE, 4303 params); 4304 4305 buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad; 4306 4307 /* probe req ie allowlisting */ 4308 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 4309 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 4310 4311 buf_ptr += WMI_TLV_HDR_SIZE; 4312 4313 if (cmd->num_vendor_oui) { 4314 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 4315 ie_allowlist->voui); 4316 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 4317 } 4318 4319 /* Add phy mode TLV if it's a wide band scan */ 4320 if (params->scan_f_wide_band) { 4321 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); 4322 buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 4323 for (i = 0; i < params->chan_list.num_chan; ++i) 4324 buf_ptr[i] = 4325 WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); 4326 buf_ptr += phymode_roundup; 4327 } else { 4328 /* Add ZERO length phy mode TLV */ 4329 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 4330 buf_ptr += WMI_TLV_HDR_SIZE; 4331 } 4332 4333 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4334 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid))); 4335 if (params->num_hint_s_ssid) { 4336 s_ssid = (wmi_hint_freq_short_ssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4337 for (i = 0; i < params->num_hint_s_ssid; ++i) { 4338 s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags; 4339 s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid; 4340 s_ssid++; 4341 } 4342 } 4343 buf_ptr += WMI_TLV_HDR_SIZE + 4344 (params->num_hint_s_ssid * sizeof(wmi_hint_freq_short_ssid)); 4345 4346 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 4347 (params->num_hint_bssid * sizeof(wmi_hint_freq_bssid))); 4348 if (params->num_hint_bssid) { 4349 hint_bssid = (wmi_hint_freq_bssid *)(buf_ptr + WMI_TLV_HDR_SIZE); 4350 for (i = 0; i < params->num_hint_bssid; ++i) { 4351 hint_bssid->freq_flags = 4352 params->hint_bssid[i].freq_flags; 4353 WMI_CHAR_ARRAY_TO_MAC_ADDR(¶ms->hint_bssid[i].bssid.bytes[0], 4354 &hint_bssid->bssid); 4355 hint_bssid++; 4356 } 4357 } 4358 4359 wmi_mtrace(WMI_START_SCAN_CMDID, cmd->vdev_id, 0); 4360 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4361 len, WMI_START_SCAN_CMDID); 4362 if (ret) { 4363 wmi_err("Failed to start scan: %d", ret); 4364 wmi_buf_free(wmi_buf); 4365 } 4366 return ret; 4367 error: 4368 wmi_buf_free(wmi_buf); 4369 return QDF_STATUS_E_FAILURE; 4370 } 4371 4372 /** 4373 * send_scan_stop_cmd_tlv() - WMI scan start function 4374 * @wmi_handle: handle to WMI. 4375 * @param: pointer to hold scan cancel cmd parameter 4376 * 4377 * Return: QDF_STATUS_SUCCESS for success or error code 4378 */ 4379 static QDF_STATUS send_scan_stop_cmd_tlv(wmi_unified_t wmi_handle, 4380 struct scan_cancel_param *param) 4381 { 4382 wmi_stop_scan_cmd_fixed_param *cmd; 4383 int ret; 4384 int len = sizeof(*cmd); 4385 wmi_buf_t wmi_buf; 4386 4387 /* Allocate the memory */ 4388 wmi_buf = wmi_buf_alloc(wmi_handle, len); 4389 if (!wmi_buf) { 4390 ret = QDF_STATUS_E_NOMEM; 4391 goto error; 4392 } 4393 4394 cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(wmi_buf); 4395 WMITLV_SET_HDR(&cmd->tlv_header, 4396 WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, 4397 WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); 4398 cmd->vdev_id = param->vdev_id; 4399 cmd->requestor = param->requester; 4400 cmd->scan_id = param->scan_id; 4401 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4402 wmi_handle, 4403 param->pdev_id); 4404 /* stop the scan with the corresponding scan_id */ 4405 if (param->req_type == WLAN_SCAN_CANCEL_PDEV_ALL) { 4406 /* Cancelling all scans */ 4407 cmd->req_type = WMI_SCAN_STOP_ALL; 4408 } else if (param->req_type == WLAN_SCAN_CANCEL_VDEV_ALL) { 4409 /* Cancelling VAP scans */ 4410 cmd->req_type = WMI_SCN_STOP_VAP_ALL; 4411 } else if (param->req_type == WLAN_SCAN_CANCEL_SINGLE) { 4412 /* Cancelling specific scan */ 4413 cmd->req_type = WMI_SCAN_STOP_ONE; 4414 } else if (param->req_type == WLAN_SCAN_CANCEL_HOST_VDEV_ALL) { 4415 cmd->req_type = WMI_SCN_STOP_HOST_VAP_ALL; 4416 } else { 4417 wmi_err("Invalid Scan cancel req type: %d", param->req_type); 4418 wmi_buf_free(wmi_buf); 4419 return QDF_STATUS_E_INVAL; 4420 } 4421 4422 wmi_mtrace(WMI_STOP_SCAN_CMDID, cmd->vdev_id, 0); 4423 ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, 4424 len, WMI_STOP_SCAN_CMDID); 4425 if (ret) { 4426 wmi_err("Failed to send stop scan: %d", ret); 4427 wmi_buf_free(wmi_buf); 4428 } 4429 4430 error: 4431 return ret; 4432 } 4433 4434 #define WMI_MAX_CHAN_INFO_LOG 192 4435 4436 /** 4437 * wmi_scan_chanlist_dump() - Dump scan channel list info 4438 * @scan_chan_list: scan channel list 4439 * 4440 * Return: void 4441 */ 4442 static void wmi_scan_chanlist_dump(struct scan_chan_list_params *scan_chan_list) 4443 { 4444 uint32_t i; 4445 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 4446 uint32_t len = 0; 4447 struct channel_param *chan; 4448 int ret; 4449 4450 wmi_debug("Total chan %d", scan_chan_list->nallchans); 4451 for (i = 0; i < scan_chan_list->nallchans; i++) { 4452 chan = &scan_chan_list->ch_param[i]; 4453 ret = qdf_scnprintf(info + len, sizeof(info) - len, 4454 " %d[%d][%d][%d]", chan->mhz, 4455 chan->maxregpower, 4456 chan->dfs_set, chan->nan_disabled); 4457 if (ret <= 0) 4458 break; 4459 len += ret; 4460 if (len >= (sizeof(info) - 20)) { 4461 wmi_nofl_debug("Chan[TXPwr][DFS][nan_disabled]:%s", 4462 info); 4463 len = 0; 4464 } 4465 } 4466 if (len) 4467 wmi_nofl_debug("Chan[TXPwr][DFS]:%s", info); 4468 } 4469 4470 static QDF_STATUS send_scan_chan_list_cmd_tlv(wmi_unified_t wmi_handle, 4471 struct scan_chan_list_params *chan_list) 4472 { 4473 wmi_buf_t buf; 4474 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 4475 wmi_scan_chan_list_cmd_fixed_param *cmd; 4476 int i; 4477 uint8_t *buf_ptr; 4478 wmi_channel *chan_info; 4479 struct channel_param *tchan_info; 4480 uint16_t len; 4481 uint16_t num_send_chans, num_sends = 0; 4482 4483 wmi_scan_chanlist_dump(chan_list); 4484 tchan_info = &chan_list->ch_param[0]; 4485 while (chan_list->nallchans) { 4486 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 4487 if (chan_list->nallchans > MAX_NUM_CHAN_PER_WMI_CMD) 4488 num_send_chans = MAX_NUM_CHAN_PER_WMI_CMD; 4489 else 4490 num_send_chans = chan_list->nallchans; 4491 4492 chan_list->nallchans -= num_send_chans; 4493 len += sizeof(wmi_channel) * num_send_chans; 4494 buf = wmi_buf_alloc(wmi_handle, len); 4495 if (!buf) { 4496 qdf_status = QDF_STATUS_E_NOMEM; 4497 goto end; 4498 } 4499 4500 buf_ptr = (uint8_t *)wmi_buf_data(buf); 4501 cmd = (wmi_scan_chan_list_cmd_fixed_param *)buf_ptr; 4502 WMITLV_SET_HDR(&cmd->tlv_header, 4503 WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, 4504 WMITLV_GET_STRUCT_TLVLEN 4505 (wmi_scan_chan_list_cmd_fixed_param)); 4506 4507 wmi_debug("no of channels = %d, len = %d", num_send_chans, len); 4508 4509 if (num_sends) 4510 cmd->flags |= APPEND_TO_EXISTING_CHAN_LIST; 4511 4512 if (chan_list->max_bw_support_present) 4513 cmd->flags |= CHANNEL_MAX_BANDWIDTH_VALID; 4514 4515 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 4516 wmi_handle, 4517 chan_list->pdev_id); 4518 4519 wmi_mtrace(WMI_SCAN_CHAN_LIST_CMDID, cmd->pdev_id, 0); 4520 4521 cmd->num_scan_chans = num_send_chans; 4522 WMITLV_SET_HDR((buf_ptr + 4523 sizeof(wmi_scan_chan_list_cmd_fixed_param)), 4524 WMITLV_TAG_ARRAY_STRUC, 4525 sizeof(wmi_channel) * num_send_chans); 4526 chan_info = (wmi_channel *)(buf_ptr + sizeof(*cmd) + 4527 WMI_TLV_HDR_SIZE); 4528 4529 for (i = 0; i < num_send_chans; ++i) { 4530 WMITLV_SET_HDR(&chan_info->tlv_header, 4531 WMITLV_TAG_STRUC_wmi_channel, 4532 WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); 4533 chan_info->mhz = tchan_info->mhz; 4534 chan_info->band_center_freq1 = 4535 tchan_info->cfreq1; 4536 chan_info->band_center_freq2 = 4537 tchan_info->cfreq2; 4538 4539 if (tchan_info->is_chan_passive) 4540 WMI_SET_CHANNEL_FLAG(chan_info, 4541 WMI_CHAN_FLAG_PASSIVE); 4542 if (tchan_info->dfs_set) 4543 WMI_SET_CHANNEL_FLAG(chan_info, 4544 WMI_CHAN_FLAG_DFS); 4545 4546 if (tchan_info->dfs_set_cfreq2) 4547 WMI_SET_CHANNEL_FLAG(chan_info, 4548 WMI_CHAN_FLAG_DFS_CFREQ2); 4549 4550 if (tchan_info->allow_he) 4551 WMI_SET_CHANNEL_FLAG(chan_info, 4552 WMI_CHAN_FLAG_ALLOW_HE); 4553 4554 if (tchan_info->allow_eht) 4555 WMI_SET_CHANNEL_FLAG(chan_info, 4556 WMI_CHAN_FLAG_ALLOW_EHT); 4557 4558 if (tchan_info->allow_vht) 4559 WMI_SET_CHANNEL_FLAG(chan_info, 4560 WMI_CHAN_FLAG_ALLOW_VHT); 4561 4562 if (tchan_info->allow_ht) 4563 WMI_SET_CHANNEL_FLAG(chan_info, 4564 WMI_CHAN_FLAG_ALLOW_HT); 4565 WMI_SET_CHANNEL_MODE(chan_info, 4566 tchan_info->phy_mode); 4567 4568 if (tchan_info->half_rate) 4569 WMI_SET_CHANNEL_FLAG(chan_info, 4570 WMI_CHAN_FLAG_HALF_RATE); 4571 4572 if (tchan_info->quarter_rate) 4573 WMI_SET_CHANNEL_FLAG(chan_info, 4574 WMI_CHAN_FLAG_QUARTER_RATE); 4575 4576 if (tchan_info->psc_channel) 4577 WMI_SET_CHANNEL_FLAG(chan_info, 4578 WMI_CHAN_FLAG_PSC); 4579 4580 if (tchan_info->nan_disabled) 4581 WMI_SET_CHANNEL_FLAG(chan_info, 4582 WMI_CHAN_FLAG_NAN_DISABLED); 4583 4584 /* also fill in power information */ 4585 WMI_SET_CHANNEL_MIN_POWER(chan_info, 4586 tchan_info->minpower); 4587 WMI_SET_CHANNEL_MAX_POWER(chan_info, 4588 tchan_info->maxpower); 4589 WMI_SET_CHANNEL_REG_POWER(chan_info, 4590 tchan_info->maxregpower); 4591 WMI_SET_CHANNEL_ANTENNA_MAX(chan_info, 4592 tchan_info->antennamax); 4593 WMI_SET_CHANNEL_REG_CLASSID(chan_info, 4594 tchan_info->reg_class_id); 4595 WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, 4596 tchan_info->maxregpower); 4597 WMI_SET_CHANNEL_MAX_BANDWIDTH(chan_info, 4598 tchan_info->max_bw_supported); 4599 4600 tchan_info++; 4601 chan_info++; 4602 } 4603 4604 qdf_status = wmi_unified_cmd_send( 4605 wmi_handle, 4606 buf, len, WMI_SCAN_CHAN_LIST_CMDID); 4607 4608 if (QDF_IS_STATUS_ERROR(qdf_status)) { 4609 wmi_err("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); 4610 wmi_buf_free(buf); 4611 goto end; 4612 } 4613 num_sends++; 4614 } 4615 4616 end: 4617 return qdf_status; 4618 } 4619 4620 /** 4621 * populate_tx_send_params - Populate TX param TLV for mgmt and offchan tx 4622 * 4623 * @bufp: Pointer to buffer 4624 * @param: Pointer to tx param 4625 * 4626 * Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure 4627 */ 4628 static inline QDF_STATUS populate_tx_send_params(uint8_t *bufp, 4629 struct tx_send_params param) 4630 { 4631 wmi_tx_send_params *tx_param; 4632 QDF_STATUS status = QDF_STATUS_SUCCESS; 4633 4634 if (!bufp) { 4635 status = QDF_STATUS_E_FAILURE; 4636 return status; 4637 } 4638 tx_param = (wmi_tx_send_params *)bufp; 4639 WMITLV_SET_HDR(&tx_param->tlv_header, 4640 WMITLV_TAG_STRUC_wmi_tx_send_params, 4641 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4642 WMI_TX_SEND_PARAM_PWR_SET(tx_param->tx_param_dword0, param.pwr); 4643 WMI_TX_SEND_PARAM_MCS_MASK_SET(tx_param->tx_param_dword0, 4644 param.mcs_mask); 4645 WMI_TX_SEND_PARAM_NSS_MASK_SET(tx_param->tx_param_dword0, 4646 param.nss_mask); 4647 WMI_TX_SEND_PARAM_RETRY_LIMIT_SET(tx_param->tx_param_dword0, 4648 param.retry_limit); 4649 WMI_TX_SEND_PARAM_CHAIN_MASK_SET(tx_param->tx_param_dword1, 4650 param.chain_mask); 4651 WMI_TX_SEND_PARAM_BW_MASK_SET(tx_param->tx_param_dword1, 4652 param.bw_mask); 4653 WMI_TX_SEND_PARAM_PREAMBLE_SET(tx_param->tx_param_dword1, 4654 param.preamble_type); 4655 WMI_TX_SEND_PARAM_FRAME_TYPE_SET(tx_param->tx_param_dword1, 4656 param.frame_type); 4657 WMI_TX_SEND_PARAM_CFR_CAPTURE_SET(tx_param->tx_param_dword1, 4658 param.cfr_enable); 4659 WMI_TX_SEND_PARAM_BEAMFORM_SET(tx_param->tx_param_dword1, 4660 param.en_beamforming); 4661 WMI_TX_SEND_PARAM_RETRY_LIMIT_EXT_SET(tx_param->tx_param_dword1, 4662 param.retry_limit_ext); 4663 4664 return status; 4665 } 4666 4667 #ifdef CONFIG_HL_SUPPORT 4668 /** 4669 * send_mgmt_cmd_tlv() - WMI scan start function 4670 * @wmi_handle: handle to WMI. 4671 * @param: pointer to hold mgmt cmd parameter 4672 * 4673 * Return: QDF_STATUS_SUCCESS for success or error code 4674 */ 4675 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4676 struct wmi_mgmt_params *param) 4677 { 4678 wmi_buf_t buf; 4679 uint8_t *bufp; 4680 int32_t cmd_len; 4681 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4682 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4683 mgmt_tx_dl_frm_len; 4684 4685 if (param->frm_len > mgmt_tx_dl_frm_len) { 4686 wmi_err("mgmt frame len %u exceeds %u", 4687 param->frm_len, mgmt_tx_dl_frm_len); 4688 return QDF_STATUS_E_INVAL; 4689 } 4690 4691 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4692 WMI_TLV_HDR_SIZE + 4693 roundup(bufp_len, sizeof(uint32_t)); 4694 4695 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4696 if (!buf) 4697 return QDF_STATUS_E_NOMEM; 4698 4699 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4700 bufp = (uint8_t *) cmd; 4701 WMITLV_SET_HDR(&cmd->tlv_header, 4702 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4703 WMITLV_GET_STRUCT_TLVLEN 4704 (wmi_mgmt_tx_send_cmd_fixed_param)); 4705 4706 cmd->vdev_id = param->vdev_id; 4707 4708 cmd->desc_id = param->desc_id; 4709 cmd->chanfreq = param->chanfreq; 4710 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4711 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4712 sizeof(uint32_t))); 4713 bufp += WMI_TLV_HDR_SIZE; 4714 qdf_mem_copy(bufp, param->pdata, bufp_len); 4715 4716 cmd->frame_len = param->frm_len; 4717 cmd->buf_len = bufp_len; 4718 cmd->tx_params_valid = param->tx_params_valid; 4719 cmd->tx_flags = param->tx_flags; 4720 cmd->peer_rssi = param->peer_rssi; 4721 4722 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4723 bufp, cmd->vdev_id, cmd->chanfreq); 4724 4725 bufp += roundup(bufp_len, sizeof(uint32_t)); 4726 if (param->tx_params_valid) { 4727 if (populate_tx_send_params(bufp, param->tx_param) != 4728 QDF_STATUS_SUCCESS) { 4729 wmi_err("Populate TX send params failed"); 4730 goto free_buf; 4731 } 4732 cmd_len += sizeof(wmi_tx_send_params); 4733 } 4734 4735 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4736 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4737 WMI_MGMT_TX_SEND_CMDID)) { 4738 wmi_err("Failed to send mgmt Tx"); 4739 goto free_buf; 4740 } 4741 return QDF_STATUS_SUCCESS; 4742 4743 free_buf: 4744 wmi_buf_free(buf); 4745 return QDF_STATUS_E_FAILURE; 4746 } 4747 #else 4748 /** 4749 * send_mgmt_cmd_tlv() - WMI scan start function 4750 * @wmi_handle: handle to WMI. 4751 * @param: pointer to hold mgmt cmd parameter 4752 * 4753 * Return: QDF_STATUS_SUCCESS for success or error code 4754 */ 4755 static QDF_STATUS send_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 4756 struct wmi_mgmt_params *param) 4757 { 4758 wmi_buf_t buf; 4759 wmi_mgmt_tx_send_cmd_fixed_param *cmd; 4760 int32_t cmd_len; 4761 uint64_t dma_addr; 4762 void *qdf_ctx = param->qdf_ctx; 4763 uint8_t *bufp; 4764 QDF_STATUS status = QDF_STATUS_SUCCESS; 4765 wmi_mlo_tx_send_params *mlo_params; 4766 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? param->frm_len : 4767 mgmt_tx_dl_frm_len; 4768 4769 cmd_len = sizeof(wmi_mgmt_tx_send_cmd_fixed_param) + 4770 WMI_TLV_HDR_SIZE + 4771 roundup(bufp_len, sizeof(uint32_t)); 4772 4773 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len + 4774 WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params)); 4775 if (!buf) 4776 return QDF_STATUS_E_NOMEM; 4777 4778 cmd = (wmi_mgmt_tx_send_cmd_fixed_param *)wmi_buf_data(buf); 4779 bufp = (uint8_t *) cmd; 4780 WMITLV_SET_HDR(&cmd->tlv_header, 4781 WMITLV_TAG_STRUC_wmi_mgmt_tx_send_cmd_fixed_param, 4782 WMITLV_GET_STRUCT_TLVLEN 4783 (wmi_mgmt_tx_send_cmd_fixed_param)); 4784 4785 cmd->vdev_id = param->vdev_id; 4786 4787 cmd->desc_id = param->desc_id; 4788 cmd->chanfreq = param->chanfreq; 4789 cmd->peer_rssi = param->peer_rssi; 4790 bufp += sizeof(wmi_mgmt_tx_send_cmd_fixed_param); 4791 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4792 sizeof(uint32_t))); 4793 bufp += WMI_TLV_HDR_SIZE; 4794 4795 /* for big endian host, copy engine byte_swap is enabled 4796 * But the frame content is in network byte order 4797 * Need to byte swap the frame content - so when copy engine 4798 * does byte_swap - target gets frame content in the correct order 4799 */ 4800 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY(bufp, param->pdata, bufp_len); 4801 4802 status = qdf_nbuf_map_single(qdf_ctx, param->tx_frame, 4803 QDF_DMA_TO_DEVICE); 4804 if (status != QDF_STATUS_SUCCESS) { 4805 wmi_err("wmi buf map failed"); 4806 goto free_buf; 4807 } 4808 4809 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4810 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4811 #if defined(HTT_PADDR64) 4812 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4813 #endif 4814 cmd->frame_len = param->frm_len; 4815 cmd->buf_len = bufp_len; 4816 cmd->tx_params_valid = param->tx_params_valid; 4817 cmd->tx_flags = param->tx_flags; 4818 4819 wmi_mgmt_cmd_record(wmi_handle, WMI_MGMT_TX_SEND_CMDID, 4820 bufp, cmd->vdev_id, cmd->chanfreq); 4821 4822 bufp += roundup(bufp_len, sizeof(uint32_t)); 4823 if (param->tx_params_valid) { 4824 status = populate_tx_send_params(bufp, param->tx_param); 4825 if (status != QDF_STATUS_SUCCESS) { 4826 wmi_err("Populate TX send params failed"); 4827 goto unmap_tx_frame; 4828 } 4829 } else { 4830 WMITLV_SET_HDR(&((wmi_tx_send_params *)bufp)->tlv_header, 4831 WMITLV_TAG_STRUC_wmi_tx_send_params, 4832 WMITLV_GET_STRUCT_TLVLEN(wmi_tx_send_params)); 4833 } 4834 4835 /* Even tx_params_valid is false, still need reserve space to pass wmi 4836 * tag check */ 4837 cmd_len += sizeof(wmi_tx_send_params); 4838 bufp += sizeof(wmi_tx_send_params); 4839 /* wmi_mlo_tx_send_params */ 4840 if (param->mlo_link_agnostic) { 4841 wmi_debug("Set mlo mgmt tid"); 4842 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_STRUC, 4843 sizeof(wmi_mlo_tx_send_params)); 4844 bufp += WMI_TLV_HDR_SIZE; 4845 mlo_params = (wmi_mlo_tx_send_params *)bufp; 4846 WMITLV_SET_HDR(&mlo_params->tlv_header, 4847 WMITLV_TAG_STRUC_wmi_mlo_tx_send_params, 4848 WMITLV_GET_STRUCT_TLVLEN(wmi_mlo_tx_send_params)); 4849 mlo_params->hw_link_id = WMI_MLO_MGMT_TID; 4850 cmd_len += WMI_TLV_HDR_SIZE + sizeof(wmi_mlo_tx_send_params); 4851 } 4852 4853 wmi_mtrace(WMI_MGMT_TX_SEND_CMDID, cmd->vdev_id, 0); 4854 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4855 WMI_MGMT_TX_SEND_CMDID)) { 4856 wmi_err("Failed to send mgmt Tx"); 4857 goto unmap_tx_frame; 4858 } 4859 return QDF_STATUS_SUCCESS; 4860 4861 unmap_tx_frame: 4862 qdf_nbuf_unmap_single(qdf_ctx, param->tx_frame, 4863 QDF_DMA_TO_DEVICE); 4864 free_buf: 4865 wmi_buf_free(buf); 4866 return QDF_STATUS_E_FAILURE; 4867 } 4868 #endif /* CONFIG_HL_SUPPORT */ 4869 4870 /** 4871 * send_offchan_data_tx_cmd_tlv() - Send off-chan tx data 4872 * @wmi_handle: handle to WMI. 4873 * @param: pointer to offchan data tx cmd parameter 4874 * 4875 * Return: QDF_STATUS_SUCCESS on success and error on failure. 4876 */ 4877 static QDF_STATUS send_offchan_data_tx_cmd_tlv(wmi_unified_t wmi_handle, 4878 struct wmi_offchan_data_tx_params *param) 4879 { 4880 wmi_buf_t buf; 4881 wmi_offchan_data_tx_send_cmd_fixed_param *cmd; 4882 int32_t cmd_len; 4883 uint64_t dma_addr; 4884 void *qdf_ctx = param->qdf_ctx; 4885 uint8_t *bufp; 4886 int32_t bufp_len = (param->frm_len < mgmt_tx_dl_frm_len) ? 4887 param->frm_len : mgmt_tx_dl_frm_len; 4888 QDF_STATUS status = QDF_STATUS_SUCCESS; 4889 4890 cmd_len = sizeof(wmi_offchan_data_tx_send_cmd_fixed_param) + 4891 WMI_TLV_HDR_SIZE + 4892 roundup(bufp_len, sizeof(uint32_t)); 4893 4894 buf = wmi_buf_alloc(wmi_handle, sizeof(wmi_tx_send_params) + cmd_len); 4895 if (!buf) 4896 return QDF_STATUS_E_NOMEM; 4897 4898 cmd = (wmi_offchan_data_tx_send_cmd_fixed_param *) wmi_buf_data(buf); 4899 bufp = (uint8_t *) cmd; 4900 WMITLV_SET_HDR(&cmd->tlv_header, 4901 WMITLV_TAG_STRUC_wmi_offchan_data_tx_send_cmd_fixed_param, 4902 WMITLV_GET_STRUCT_TLVLEN 4903 (wmi_offchan_data_tx_send_cmd_fixed_param)); 4904 4905 cmd->vdev_id = param->vdev_id; 4906 4907 cmd->desc_id = param->desc_id; 4908 cmd->chanfreq = param->chanfreq; 4909 bufp += sizeof(wmi_offchan_data_tx_send_cmd_fixed_param); 4910 WMITLV_SET_HDR(bufp, WMITLV_TAG_ARRAY_BYTE, roundup(bufp_len, 4911 sizeof(uint32_t))); 4912 bufp += WMI_TLV_HDR_SIZE; 4913 qdf_mem_copy(bufp, param->pdata, bufp_len); 4914 qdf_nbuf_map_single(qdf_ctx, param->tx_frame, QDF_DMA_TO_DEVICE); 4915 dma_addr = qdf_nbuf_get_frag_paddr(param->tx_frame, 0); 4916 cmd->paddr_lo = (uint32_t)(dma_addr & 0xffffffff); 4917 #if defined(HTT_PADDR64) 4918 cmd->paddr_hi = (uint32_t)((dma_addr >> 32) & 0x1F); 4919 #endif 4920 cmd->frame_len = param->frm_len; 4921 cmd->buf_len = bufp_len; 4922 cmd->tx_params_valid = param->tx_params_valid; 4923 4924 wmi_mgmt_cmd_record(wmi_handle, WMI_OFFCHAN_DATA_TX_SEND_CMDID, 4925 bufp, cmd->vdev_id, cmd->chanfreq); 4926 4927 bufp += roundup(bufp_len, sizeof(uint32_t)); 4928 if (param->tx_params_valid) { 4929 status = populate_tx_send_params(bufp, param->tx_param); 4930 if (status != QDF_STATUS_SUCCESS) { 4931 wmi_err("Populate TX send params failed"); 4932 goto err1; 4933 } 4934 cmd_len += sizeof(wmi_tx_send_params); 4935 } 4936 4937 wmi_mtrace(WMI_OFFCHAN_DATA_TX_SEND_CMDID, cmd->vdev_id, 0); 4938 if (wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 4939 WMI_OFFCHAN_DATA_TX_SEND_CMDID)) { 4940 wmi_err("Failed to offchan data Tx"); 4941 goto err1; 4942 } 4943 4944 return QDF_STATUS_SUCCESS; 4945 4946 err1: 4947 wmi_buf_free(buf); 4948 return QDF_STATUS_E_FAILURE; 4949 } 4950 4951 /** 4952 * send_modem_power_state_cmd_tlv() - set modem power state to fw 4953 * @wmi_handle: wmi handle 4954 * @param_value: parameter value 4955 * 4956 * Return: QDF_STATUS_SUCCESS for success or error code 4957 */ 4958 static QDF_STATUS send_modem_power_state_cmd_tlv(wmi_unified_t wmi_handle, 4959 uint32_t param_value) 4960 { 4961 QDF_STATUS ret; 4962 wmi_modem_power_state_cmd_param *cmd; 4963 wmi_buf_t buf; 4964 uint16_t len = sizeof(*cmd); 4965 4966 buf = wmi_buf_alloc(wmi_handle, len); 4967 if (!buf) 4968 return QDF_STATUS_E_NOMEM; 4969 4970 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf); 4971 WMITLV_SET_HDR(&cmd->tlv_header, 4972 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, 4973 WMITLV_GET_STRUCT_TLVLEN 4974 (wmi_modem_power_state_cmd_param)); 4975 cmd->modem_power_state = param_value; 4976 wmi_debug("Setting cmd->modem_power_state = %u", param_value); 4977 wmi_mtrace(WMI_MODEM_POWER_STATE_CMDID, NO_SESSION, 0); 4978 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 4979 WMI_MODEM_POWER_STATE_CMDID); 4980 if (QDF_IS_STATUS_ERROR(ret)) { 4981 wmi_err("Failed to send notify cmd ret = %d", ret); 4982 wmi_buf_free(buf); 4983 } 4984 4985 return ret; 4986 } 4987 4988 /** 4989 * send_set_sta_ps_mode_cmd_tlv() - set sta powersave mode in fw 4990 * @wmi_handle: wmi handle 4991 * @vdev_id: vdev id 4992 * @val: value 4993 * 4994 * Return: QDF_STATUS_SUCCESS for success or error code. 4995 */ 4996 static QDF_STATUS send_set_sta_ps_mode_cmd_tlv(wmi_unified_t wmi_handle, 4997 uint32_t vdev_id, uint8_t val) 4998 { 4999 wmi_sta_powersave_mode_cmd_fixed_param *cmd; 5000 wmi_buf_t buf; 5001 int32_t len = sizeof(*cmd); 5002 5003 wmi_debug("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); 5004 5005 buf = wmi_buf_alloc(wmi_handle, len); 5006 if (!buf) 5007 return QDF_STATUS_E_NOMEM; 5008 5009 cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); 5010 WMITLV_SET_HDR(&cmd->tlv_header, 5011 WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, 5012 WMITLV_GET_STRUCT_TLVLEN 5013 (wmi_sta_powersave_mode_cmd_fixed_param)); 5014 cmd->vdev_id = vdev_id; 5015 if (val) 5016 cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; 5017 else 5018 cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; 5019 5020 wmi_mtrace(WMI_STA_POWERSAVE_MODE_CMDID, cmd->vdev_id, 0); 5021 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5022 WMI_STA_POWERSAVE_MODE_CMDID)) { 5023 wmi_err("Set Sta Mode Ps Failed vdevId %d val %d", 5024 vdev_id, val); 5025 wmi_buf_free(buf); 5026 return QDF_STATUS_E_FAILURE; 5027 } 5028 return QDF_STATUS_SUCCESS; 5029 } 5030 5031 /** 5032 * send_idle_roam_monitor_cmd_tlv() - send idle monitor command to fw 5033 * @wmi_handle: wmi handle 5034 * @val: non-zero to turn monitor on 5035 * 5036 * Return: QDF_STATUS_SUCCESS for success or error code. 5037 */ 5038 static QDF_STATUS send_idle_roam_monitor_cmd_tlv(wmi_unified_t wmi_handle, 5039 uint8_t val) 5040 { 5041 wmi_idle_trigger_monitor_cmd_fixed_param *cmd; 5042 wmi_buf_t buf; 5043 size_t len = sizeof(*cmd); 5044 5045 buf = wmi_buf_alloc(wmi_handle, len); 5046 if (!buf) 5047 return QDF_STATUS_E_NOMEM; 5048 5049 cmd = (wmi_idle_trigger_monitor_cmd_fixed_param *)wmi_buf_data(buf); 5050 WMITLV_SET_HDR(&cmd->tlv_header, 5051 WMITLV_TAG_STRUC_wmi_idle_trigger_monitor_cmd_fixed_param, 5052 WMITLV_GET_STRUCT_TLVLEN(wmi_idle_trigger_monitor_cmd_fixed_param)); 5053 5054 cmd->idle_trigger_monitor = (val ? WMI_IDLE_TRIGGER_MONITOR_ON : 5055 WMI_IDLE_TRIGGER_MONITOR_OFF); 5056 5057 wmi_debug("val: %d", cmd->idle_trigger_monitor); 5058 5059 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5060 WMI_IDLE_TRIGGER_MONITOR_CMDID)) { 5061 wmi_buf_free(buf); 5062 return QDF_STATUS_E_FAILURE; 5063 } 5064 return QDF_STATUS_SUCCESS; 5065 } 5066 5067 /** 5068 * send_set_mimops_cmd_tlv() - set MIMO powersave 5069 * @wmi_handle: wmi handle 5070 * @vdev_id: vdev id 5071 * @value: value 5072 * 5073 * Return: QDF_STATUS_SUCCESS for success or error code. 5074 */ 5075 static QDF_STATUS send_set_mimops_cmd_tlv(wmi_unified_t wmi_handle, 5076 uint8_t vdev_id, int value) 5077 { 5078 QDF_STATUS ret; 5079 wmi_sta_smps_force_mode_cmd_fixed_param *cmd; 5080 wmi_buf_t buf; 5081 uint16_t len = sizeof(*cmd); 5082 5083 buf = wmi_buf_alloc(wmi_handle, len); 5084 if (!buf) 5085 return QDF_STATUS_E_NOMEM; 5086 5087 cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); 5088 WMITLV_SET_HDR(&cmd->tlv_header, 5089 WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, 5090 WMITLV_GET_STRUCT_TLVLEN 5091 (wmi_sta_smps_force_mode_cmd_fixed_param)); 5092 5093 cmd->vdev_id = vdev_id; 5094 5095 /* WMI_SMPS_FORCED_MODE values do not directly map 5096 * to SM power save values defined in the specification. 5097 * Make sure to send the right mapping. 5098 */ 5099 switch (value) { 5100 case 0: 5101 cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; 5102 break; 5103 case 1: 5104 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; 5105 break; 5106 case 2: 5107 cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; 5108 break; 5109 case 3: 5110 cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; 5111 break; 5112 default: 5113 wmi_err("INVALID MIMO PS CONFIG: %d", value); 5114 wmi_buf_free(buf); 5115 return QDF_STATUS_E_FAILURE; 5116 } 5117 5118 wmi_debug("Setting vdev %d value = %u", vdev_id, value); 5119 5120 wmi_mtrace(WMI_STA_SMPS_FORCE_MODE_CMDID, cmd->vdev_id, 0); 5121 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5122 WMI_STA_SMPS_FORCE_MODE_CMDID); 5123 if (QDF_IS_STATUS_ERROR(ret)) { 5124 wmi_err("Failed to send set Mimo PS ret = %d", ret); 5125 wmi_buf_free(buf); 5126 } 5127 5128 return ret; 5129 } 5130 5131 /** 5132 * send_set_smps_params_cmd_tlv() - set smps params 5133 * @wmi_handle: wmi handle 5134 * @vdev_id: vdev id 5135 * @value: value 5136 * 5137 * Return: QDF_STATUS_SUCCESS for success or error code. 5138 */ 5139 static QDF_STATUS send_set_smps_params_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id, 5140 int value) 5141 { 5142 QDF_STATUS ret; 5143 wmi_sta_smps_param_cmd_fixed_param *cmd; 5144 wmi_buf_t buf; 5145 uint16_t len = sizeof(*cmd); 5146 5147 buf = wmi_buf_alloc(wmi_handle, len); 5148 if (!buf) 5149 return QDF_STATUS_E_NOMEM; 5150 5151 cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); 5152 WMITLV_SET_HDR(&cmd->tlv_header, 5153 WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, 5154 WMITLV_GET_STRUCT_TLVLEN 5155 (wmi_sta_smps_param_cmd_fixed_param)); 5156 5157 cmd->vdev_id = vdev_id; 5158 cmd->value = value & WMI_SMPS_MASK_LOWER_16BITS; 5159 cmd->param = 5160 (value >> WMI_SMPS_PARAM_VALUE_S) & WMI_SMPS_MASK_UPPER_3BITS; 5161 5162 wmi_debug("Setting vdev %d value = %x param %x", vdev_id, cmd->value, 5163 cmd->param); 5164 5165 wmi_mtrace(WMI_STA_SMPS_PARAM_CMDID, cmd->vdev_id, 0); 5166 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 5167 WMI_STA_SMPS_PARAM_CMDID); 5168 if (QDF_IS_STATUS_ERROR(ret)) { 5169 wmi_err("Failed to send set Mimo PS ret = %d", ret); 5170 wmi_buf_free(buf); 5171 } 5172 5173 return ret; 5174 } 5175 5176 /** 5177 * send_get_temperature_cmd_tlv() - get pdev temperature req 5178 * @wmi_handle: wmi handle 5179 * 5180 * Return: QDF_STATUS_SUCCESS for success or error code. 5181 */ 5182 static QDF_STATUS send_get_temperature_cmd_tlv(wmi_unified_t wmi_handle) 5183 { 5184 wmi_pdev_get_temperature_cmd_fixed_param *cmd; 5185 wmi_buf_t wmi_buf; 5186 uint32_t len = sizeof(wmi_pdev_get_temperature_cmd_fixed_param); 5187 uint8_t *buf_ptr; 5188 5189 if (!wmi_handle) { 5190 wmi_err("WMI is closed, can not issue cmd"); 5191 return QDF_STATUS_E_INVAL; 5192 } 5193 5194 wmi_buf = wmi_buf_alloc(wmi_handle, len); 5195 if (!wmi_buf) 5196 return QDF_STATUS_E_NOMEM; 5197 5198 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5199 5200 cmd = (wmi_pdev_get_temperature_cmd_fixed_param *) buf_ptr; 5201 WMITLV_SET_HDR(&cmd->tlv_header, 5202 WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, 5203 WMITLV_GET_STRUCT_TLVLEN 5204 (wmi_pdev_get_temperature_cmd_fixed_param)); 5205 5206 wmi_mtrace(WMI_PDEV_GET_TEMPERATURE_CMDID, NO_SESSION, 0); 5207 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 5208 WMI_PDEV_GET_TEMPERATURE_CMDID)) { 5209 wmi_err("Failed to send get temperature command"); 5210 wmi_buf_free(wmi_buf); 5211 return QDF_STATUS_E_FAILURE; 5212 } 5213 5214 return QDF_STATUS_SUCCESS; 5215 } 5216 5217 /** 5218 * send_set_sta_uapsd_auto_trig_cmd_tlv() - set uapsd auto trigger command 5219 * @wmi_handle: wmi handle 5220 * @param: UAPSD trigger parameters 5221 * 5222 * This function sets the trigger 5223 * uapsd params such as service interval, delay interval 5224 * and suspend interval which will be used by the firmware 5225 * to send trigger frames periodically when there is no 5226 * traffic on the transmit side. 5227 * 5228 * Return: QDF_STATUS_SUCCESS for success or error code. 5229 */ 5230 static QDF_STATUS send_set_sta_uapsd_auto_trig_cmd_tlv(wmi_unified_t wmi_handle, 5231 struct sta_uapsd_trig_params *param) 5232 { 5233 wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; 5234 QDF_STATUS ret; 5235 uint32_t param_len = param->num_ac * sizeof(wmi_sta_uapsd_auto_trig_param); 5236 uint32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; 5237 uint32_t i; 5238 wmi_buf_t buf; 5239 uint8_t *buf_ptr; 5240 struct sta_uapsd_params *uapsd_param; 5241 wmi_sta_uapsd_auto_trig_param *trig_param; 5242 5243 buf = wmi_buf_alloc(wmi_handle, cmd_len); 5244 if (!buf) 5245 return QDF_STATUS_E_NOMEM; 5246 5247 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5248 cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; 5249 WMITLV_SET_HDR(&cmd->tlv_header, 5250 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, 5251 WMITLV_GET_STRUCT_TLVLEN 5252 (wmi_sta_uapsd_auto_trig_cmd_fixed_param)); 5253 cmd->vdev_id = param->vdevid; 5254 cmd->num_ac = param->num_ac; 5255 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 5256 5257 /* TLV indicating array of structures to follow */ 5258 buf_ptr += sizeof(*cmd); 5259 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); 5260 5261 buf_ptr += WMI_TLV_HDR_SIZE; 5262 5263 /* 5264 * Update tag and length for uapsd auto trigger params (this will take 5265 * care of updating tag and length if it is not pre-filled by caller). 5266 */ 5267 uapsd_param = (struct sta_uapsd_params *)param->auto_triggerparam; 5268 trig_param = (wmi_sta_uapsd_auto_trig_param *)buf_ptr; 5269 for (i = 0; i < param->num_ac; i++) { 5270 WMITLV_SET_HDR((buf_ptr + 5271 (i * sizeof(wmi_sta_uapsd_auto_trig_param))), 5272 WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, 5273 WMITLV_GET_STRUCT_TLVLEN 5274 (wmi_sta_uapsd_auto_trig_param)); 5275 trig_param->wmm_ac = uapsd_param->wmm_ac; 5276 trig_param->user_priority = uapsd_param->user_priority; 5277 trig_param->service_interval = uapsd_param->service_interval; 5278 trig_param->suspend_interval = uapsd_param->suspend_interval; 5279 trig_param->delay_interval = uapsd_param->delay_interval; 5280 trig_param++; 5281 uapsd_param++; 5282 } 5283 5284 wmi_mtrace(WMI_STA_UAPSD_AUTO_TRIG_CMDID, cmd->vdev_id, 0); 5285 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 5286 WMI_STA_UAPSD_AUTO_TRIG_CMDID); 5287 if (QDF_IS_STATUS_ERROR(ret)) { 5288 wmi_err("Failed to send set uapsd param ret = %d", ret); 5289 wmi_buf_free(buf); 5290 } 5291 5292 return ret; 5293 } 5294 5295 /** 5296 * send_set_thermal_mgmt_cmd_tlv() - set thermal mgmt command to fw 5297 * @wmi_handle: Pointer to wmi handle 5298 * @thermal_info: Thermal command information 5299 * 5300 * This function sends the thermal management command 5301 * to the firmware 5302 * 5303 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5304 */ 5305 static QDF_STATUS send_set_thermal_mgmt_cmd_tlv(wmi_unified_t wmi_handle, 5306 struct thermal_cmd_params *thermal_info) 5307 { 5308 wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; 5309 wmi_buf_t buf = NULL; 5310 QDF_STATUS status; 5311 uint32_t len = 0; 5312 uint8_t action; 5313 5314 switch (thermal_info->thermal_action) { 5315 case THERMAL_MGMT_ACTION_DEFAULT: 5316 action = WMI_THERMAL_MGMT_ACTION_DEFAULT; 5317 break; 5318 5319 case THERMAL_MGMT_ACTION_HALT_TRAFFIC: 5320 action = WMI_THERMAL_MGMT_ACTION_HALT_TRAFFIC; 5321 break; 5322 5323 case THERMAL_MGMT_ACTION_NOTIFY_HOST: 5324 action = WMI_THERMAL_MGMT_ACTION_NOTIFY_HOST; 5325 break; 5326 5327 case THERMAL_MGMT_ACTION_CHAINSCALING: 5328 action = WMI_THERMAL_MGMT_ACTION_CHAINSCALING; 5329 break; 5330 5331 default: 5332 wmi_err("Invalid thermal_action code %d", 5333 thermal_info->thermal_action); 5334 return QDF_STATUS_E_FAILURE; 5335 } 5336 5337 len = sizeof(*cmd); 5338 5339 buf = wmi_buf_alloc(wmi_handle, len); 5340 if (!buf) 5341 return QDF_STATUS_E_FAILURE; 5342 5343 cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data(buf); 5344 5345 WMITLV_SET_HDR(&cmd->tlv_header, 5346 WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, 5347 WMITLV_GET_STRUCT_TLVLEN 5348 (wmi_thermal_mgmt_cmd_fixed_param)); 5349 5350 cmd->lower_thresh_degreeC = thermal_info->min_temp; 5351 cmd->upper_thresh_degreeC = thermal_info->max_temp; 5352 cmd->enable = thermal_info->thermal_enable; 5353 cmd->action = action; 5354 5355 wmi_debug("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d action %d", 5356 cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, 5357 cmd->enable, cmd->action); 5358 5359 wmi_mtrace(WMI_THERMAL_MGMT_CMDID, NO_SESSION, 0); 5360 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5361 WMI_THERMAL_MGMT_CMDID); 5362 if (QDF_IS_STATUS_ERROR(status)) { 5363 wmi_buf_free(buf); 5364 wmi_err("Failed to send thermal mgmt command"); 5365 } 5366 5367 return status; 5368 } 5369 5370 /** 5371 * send_lro_config_cmd_tlv() - process the LRO config command 5372 * @wmi_handle: Pointer to WMI handle 5373 * @wmi_lro_cmd: Pointer to LRO configuration parameters 5374 * 5375 * This function sends down the LRO configuration parameters to 5376 * the firmware to enable LRO, sets the TCP flags and sets the 5377 * seed values for the toeplitz hash generation 5378 * 5379 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5380 */ 5381 static QDF_STATUS send_lro_config_cmd_tlv(wmi_unified_t wmi_handle, 5382 struct wmi_lro_config_cmd_t *wmi_lro_cmd) 5383 { 5384 wmi_lro_info_cmd_fixed_param *cmd; 5385 wmi_buf_t buf; 5386 QDF_STATUS status; 5387 uint8_t pdev_id = wmi_lro_cmd->pdev_id; 5388 5389 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 5390 if (!buf) 5391 return QDF_STATUS_E_FAILURE; 5392 5393 cmd = (wmi_lro_info_cmd_fixed_param *) wmi_buf_data(buf); 5394 5395 WMITLV_SET_HDR(&cmd->tlv_header, 5396 WMITLV_TAG_STRUC_wmi_lro_info_cmd_fixed_param, 5397 WMITLV_GET_STRUCT_TLVLEN(wmi_lro_info_cmd_fixed_param)); 5398 5399 cmd->lro_enable = wmi_lro_cmd->lro_enable; 5400 WMI_LRO_INFO_TCP_FLAG_VALS_SET(cmd->tcp_flag_u32, 5401 wmi_lro_cmd->tcp_flag); 5402 WMI_LRO_INFO_TCP_FLAGS_MASK_SET(cmd->tcp_flag_u32, 5403 wmi_lro_cmd->tcp_flag_mask); 5404 cmd->toeplitz_hash_ipv4_0_3 = 5405 wmi_lro_cmd->toeplitz_hash_ipv4[0]; 5406 cmd->toeplitz_hash_ipv4_4_7 = 5407 wmi_lro_cmd->toeplitz_hash_ipv4[1]; 5408 cmd->toeplitz_hash_ipv4_8_11 = 5409 wmi_lro_cmd->toeplitz_hash_ipv4[2]; 5410 cmd->toeplitz_hash_ipv4_12_15 = 5411 wmi_lro_cmd->toeplitz_hash_ipv4[3]; 5412 cmd->toeplitz_hash_ipv4_16 = 5413 wmi_lro_cmd->toeplitz_hash_ipv4[4]; 5414 5415 cmd->toeplitz_hash_ipv6_0_3 = 5416 wmi_lro_cmd->toeplitz_hash_ipv6[0]; 5417 cmd->toeplitz_hash_ipv6_4_7 = 5418 wmi_lro_cmd->toeplitz_hash_ipv6[1]; 5419 cmd->toeplitz_hash_ipv6_8_11 = 5420 wmi_lro_cmd->toeplitz_hash_ipv6[2]; 5421 cmd->toeplitz_hash_ipv6_12_15 = 5422 wmi_lro_cmd->toeplitz_hash_ipv6[3]; 5423 cmd->toeplitz_hash_ipv6_16_19 = 5424 wmi_lro_cmd->toeplitz_hash_ipv6[4]; 5425 cmd->toeplitz_hash_ipv6_20_23 = 5426 wmi_lro_cmd->toeplitz_hash_ipv6[5]; 5427 cmd->toeplitz_hash_ipv6_24_27 = 5428 wmi_lro_cmd->toeplitz_hash_ipv6[6]; 5429 cmd->toeplitz_hash_ipv6_28_31 = 5430 wmi_lro_cmd->toeplitz_hash_ipv6[7]; 5431 cmd->toeplitz_hash_ipv6_32_35 = 5432 wmi_lro_cmd->toeplitz_hash_ipv6[8]; 5433 cmd->toeplitz_hash_ipv6_36_39 = 5434 wmi_lro_cmd->toeplitz_hash_ipv6[9]; 5435 cmd->toeplitz_hash_ipv6_40 = 5436 wmi_lro_cmd->toeplitz_hash_ipv6[10]; 5437 5438 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 5439 wmi_handle, 5440 pdev_id); 5441 wmi_debug("WMI_LRO_CONFIG: lro_enable %d, tcp_flag 0x%x, pdev_id: %d", 5442 cmd->lro_enable, cmd->tcp_flag_u32, cmd->pdev_id); 5443 5444 wmi_mtrace(WMI_LRO_CONFIG_CMDID, NO_SESSION, 0); 5445 status = wmi_unified_cmd_send(wmi_handle, buf, 5446 sizeof(*cmd), WMI_LRO_CONFIG_CMDID); 5447 if (QDF_IS_STATUS_ERROR(status)) { 5448 wmi_buf_free(buf); 5449 wmi_err("Failed to send WMI_LRO_CONFIG_CMDID"); 5450 } 5451 5452 return status; 5453 } 5454 5455 /** 5456 * send_peer_rate_report_cmd_tlv() - process the peer rate report command 5457 * @wmi_handle: Pointer to wmi handle 5458 * @rate_report_params: Pointer to peer rate report parameters 5459 * 5460 * 5461 * Return: QDF_STATUS_SUCCESS for success otherwise failure 5462 */ 5463 static QDF_STATUS send_peer_rate_report_cmd_tlv(wmi_unified_t wmi_handle, 5464 struct wmi_peer_rate_report_params *rate_report_params) 5465 { 5466 wmi_peer_set_rate_report_condition_fixed_param *cmd = NULL; 5467 wmi_buf_t buf = NULL; 5468 QDF_STATUS status = 0; 5469 uint32_t len = 0; 5470 uint32_t i, j; 5471 5472 len = sizeof(*cmd); 5473 5474 buf = wmi_buf_alloc(wmi_handle, len); 5475 if (!buf) 5476 return QDF_STATUS_E_FAILURE; 5477 5478 cmd = (wmi_peer_set_rate_report_condition_fixed_param *) 5479 wmi_buf_data(buf); 5480 5481 WMITLV_SET_HDR( 5482 &cmd->tlv_header, 5483 WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, 5484 WMITLV_GET_STRUCT_TLVLEN( 5485 wmi_peer_set_rate_report_condition_fixed_param)); 5486 5487 cmd->enable_rate_report = rate_report_params->rate_report_enable; 5488 cmd->report_backoff_time = rate_report_params->backoff_time; 5489 cmd->report_timer_period = rate_report_params->timer_period; 5490 for (i = 0; i < PEER_RATE_REPORT_COND_MAX_NUM; i++) { 5491 cmd->cond_per_phy[i].val_cond_flags = 5492 rate_report_params->report_per_phy[i].cond_flags; 5493 cmd->cond_per_phy[i].rate_delta.min_delta = 5494 rate_report_params->report_per_phy[i].delta.delta_min; 5495 cmd->cond_per_phy[i].rate_delta.percentage = 5496 rate_report_params->report_per_phy[i].delta.percent; 5497 for (j = 0; j < MAX_NUM_OF_RATE_THRESH; j++) { 5498 cmd->cond_per_phy[i].rate_threshold[j] = 5499 rate_report_params->report_per_phy[i]. 5500 report_rate_threshold[j]; 5501 } 5502 } 5503 5504 wmi_debug("enable %d backoff_time %d period %d", 5505 cmd->enable_rate_report, 5506 cmd->report_backoff_time, cmd->report_timer_period); 5507 5508 wmi_mtrace(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, NO_SESSION, 0); 5509 status = wmi_unified_cmd_send(wmi_handle, buf, len, 5510 WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); 5511 if (QDF_IS_STATUS_ERROR(status)) { 5512 wmi_buf_free(buf); 5513 wmi_err("Failed to send peer_set_report_cond command"); 5514 } 5515 return status; 5516 } 5517 5518 /** 5519 * send_process_update_edca_param_cmd_tlv() - update EDCA params 5520 * @wmi_handle: wmi handle 5521 * @vdev_id: vdev id. 5522 * @mu_edca_param: true if these are MU EDCA params 5523 * @wmm_vparams: edca parameters 5524 * 5525 * This function updates EDCA parameters to the target 5526 * 5527 * Return: CDF Status 5528 */ 5529 static QDF_STATUS send_process_update_edca_param_cmd_tlv(wmi_unified_t wmi_handle, 5530 uint8_t vdev_id, bool mu_edca_param, 5531 struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]) 5532 { 5533 uint8_t *buf_ptr; 5534 wmi_buf_t buf; 5535 wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; 5536 wmi_wmm_vparams *wmm_param; 5537 struct wmi_host_wme_vparams *twmm_param; 5538 int len = sizeof(*cmd); 5539 int ac; 5540 5541 buf = wmi_buf_alloc(wmi_handle, len); 5542 5543 if (!buf) 5544 return QDF_STATUS_E_NOMEM; 5545 5546 buf_ptr = (uint8_t *) wmi_buf_data(buf); 5547 cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; 5548 WMITLV_SET_HDR(&cmd->tlv_header, 5549 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5550 WMITLV_GET_STRUCT_TLVLEN 5551 (wmi_vdev_set_wmm_params_cmd_fixed_param)); 5552 cmd->vdev_id = vdev_id; 5553 cmd->wmm_param_type = mu_edca_param; 5554 5555 for (ac = 0; ac < WMI_MAX_NUM_AC; ac++) { 5556 wmm_param = (wmi_wmm_vparams *) (&cmd->wmm_params[ac]); 5557 twmm_param = (struct wmi_host_wme_vparams *) (&wmm_vparams[ac]); 5558 WMITLV_SET_HDR(&wmm_param->tlv_header, 5559 WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, 5560 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); 5561 wmm_param->cwmin = twmm_param->cwmin; 5562 wmm_param->cwmax = twmm_param->cwmax; 5563 wmm_param->aifs = twmm_param->aifs; 5564 if (mu_edca_param) 5565 wmm_param->mu_edca_timer = twmm_param->mu_edca_timer; 5566 else 5567 wmm_param->txoplimit = twmm_param->txoplimit; 5568 wmm_param->acm = twmm_param->acm; 5569 wmm_param->no_ack = twmm_param->noackpolicy; 5570 } 5571 5572 wmi_mtrace(WMI_VDEV_SET_WMM_PARAMS_CMDID, cmd->vdev_id, 0); 5573 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5574 WMI_VDEV_SET_WMM_PARAMS_CMDID)) 5575 goto fail; 5576 5577 return QDF_STATUS_SUCCESS; 5578 5579 fail: 5580 wmi_buf_free(buf); 5581 wmi_err("Failed to set WMM Parameters"); 5582 return QDF_STATUS_E_FAILURE; 5583 } 5584 5585 static WMI_EDCA_PARAM_TYPE 5586 wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) 5587 { 5588 switch (type) { 5589 case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: 5590 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5591 case HOST_EDCA_PARAM_TYPE_PIFS: 5592 return WMI_EDCA_PARAM_TYPE_PIFS; 5593 default: 5594 return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; 5595 } 5596 } 5597 5598 /** 5599 * send_update_edca_pifs_param_cmd_tlv() - update EDCA params 5600 * @wmi_handle: wmi handle 5601 * @edca_pifs: edca/pifs parameters 5602 * 5603 * This function updates EDCA/PIFS parameters to the target 5604 * 5605 * Return: QDF Status 5606 */ 5607 5608 static QDF_STATUS 5609 send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, 5610 struct edca_pifs_vparam *edca_pifs) 5611 { 5612 uint8_t *buf_ptr; 5613 wmi_buf_t buf = NULL; 5614 wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; 5615 wmi_wmm_params *wmm_params; 5616 wmi_pifs_params *pifs_params; 5617 uint16_t len; 5618 5619 if (!edca_pifs) { 5620 wmi_debug("edca_pifs is NULL"); 5621 return QDF_STATUS_E_FAILURE; 5622 } 5623 5624 len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5625 if (edca_pifs->param.edca_param_type == 5626 HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { 5627 len += WMI_TLV_HDR_SIZE; 5628 len += sizeof(wmi_wmm_params); 5629 } else { 5630 len += WMI_TLV_HDR_SIZE; 5631 } 5632 if (edca_pifs->param.edca_param_type == 5633 HOST_EDCA_PARAM_TYPE_PIFS) { 5634 len += WMI_TLV_HDR_SIZE; 5635 len += sizeof(wmi_pifs_params); 5636 } else { 5637 len += WMI_TLV_HDR_SIZE; 5638 } 5639 5640 buf = wmi_buf_alloc(wmi_handle, len); 5641 5642 if (!buf) 5643 return QDF_STATUS_E_NOMEM; 5644 5645 cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); 5646 buf_ptr = (uint8_t *)cmd; 5647 5648 WMITLV_SET_HDR(&cmd->tlv_header, 5649 WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, 5650 WMITLV_GET_STRUCT_TLVLEN 5651 (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); 5652 5653 cmd->vdev_id = edca_pifs->vdev_id; 5654 cmd->type = wmi_convert_edca_pifs_param_type( 5655 edca_pifs->param.edca_param_type); 5656 buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); 5657 5658 if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { 5659 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5660 sizeof(*wmm_params)); 5661 buf_ptr += WMI_TLV_HDR_SIZE; 5662 wmm_params = (wmi_wmm_params *)buf_ptr; 5663 WMITLV_SET_HDR(&wmm_params->tlv_header, 5664 WMITLV_TAG_STRUC_wmi_wmm_params, 5665 WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); 5666 5667 wmm_params->cwmin = 5668 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin) - 1; 5669 wmm_params->cwmax = 5670 BIT(edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax) - 1; 5671 wmm_params->aifs = 5672 edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn - 1; 5673 wmm_params->txoplimit = 5674 edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; 5675 wmm_params->acm = 5676 edca_pifs->param.edca_pifs_param.eparam.acvo_acm; 5677 wmm_params->no_ack = 0; 5678 wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", 5679 cmd->vdev_id, cmd->type, wmm_params->cwmin, 5680 wmm_params->cwmax, wmm_params->aifs, 5681 wmm_params->txoplimit, wmm_params->acm, 5682 wmm_params->no_ack); 5683 buf_ptr += sizeof(*wmm_params); 5684 } else { 5685 /* set zero TLV's for wmm_params */ 5686 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5687 WMITLV_GET_STRUCT_TLVLEN(0)); 5688 buf_ptr += WMI_TLV_HDR_SIZE; 5689 } 5690 if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { 5691 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5692 sizeof(*pifs_params)); 5693 buf_ptr += WMI_TLV_HDR_SIZE; 5694 pifs_params = (wmi_pifs_params *)buf_ptr; 5695 WMITLV_SET_HDR(&pifs_params->tlv_header, 5696 WMITLV_TAG_STRUC_wmi_pifs_params, 5697 WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); 5698 5699 pifs_params->sap_pifs_offset = 5700 edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; 5701 pifs_params->leb_pifs_offset = 5702 edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; 5703 pifs_params->reb_pifs_offset = 5704 edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; 5705 wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", 5706 cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, 5707 pifs_params->leb_pifs_offset, 5708 pifs_params->reb_pifs_offset); 5709 } else { 5710 /* set zero TLV's for pifs_params */ 5711 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 5712 WMITLV_GET_STRUCT_TLVLEN(0)); 5713 buf_ptr += WMI_TLV_HDR_SIZE; 5714 } 5715 5716 wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); 5717 if (wmi_unified_cmd_send(wmi_handle, buf, len, 5718 WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) 5719 goto fail; 5720 5721 return QDF_STATUS_SUCCESS; 5722 5723 fail: 5724 wmi_buf_free(buf); 5725 wmi_err("Failed to set EDCA/PIFS Parameters"); 5726 return QDF_STATUS_E_FAILURE; 5727 } 5728 5729 /** 5730 * extract_csa_ie_received_ev_params_tlv() - extract csa IE received event 5731 * @wmi_handle: wmi handle 5732 * @evt_buf: pointer to event buffer 5733 * @vdev_id: VDEV ID 5734 * @csa_event: csa event data 5735 * 5736 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5737 */ 5738 static QDF_STATUS 5739 extract_csa_ie_received_ev_params_tlv(wmi_unified_t wmi_handle, 5740 void *evt_buf, uint8_t *vdev_id, 5741 struct csa_offload_params *csa_event) 5742 { 5743 WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *param_buf; 5744 wmi_csa_event_fixed_param *csa_ev; 5745 struct xcsa_ie *xcsa_ie; 5746 struct csa_ie *csa_ie; 5747 uint8_t *bssid; 5748 bool ret; 5749 5750 param_buf = (WMI_CSA_IE_RECEIVED_EVENTID_param_tlvs *)evt_buf; 5751 if (!param_buf) { 5752 wmi_err("Invalid csa event buffer"); 5753 return QDF_STATUS_E_FAILURE; 5754 } 5755 csa_ev = param_buf->fixed_param; 5756 WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_ev->i_addr2, 5757 &csa_event->bssid.bytes[0]); 5758 5759 bssid = csa_event->bssid.bytes; 5760 ret = wlan_get_connected_vdev_from_psoc_by_bssid(wmi_handle->soc->wmi_psoc, 5761 bssid, vdev_id); 5762 if (!ret) { 5763 wmi_err("VDEV is not connected with BSSID"); 5764 return QDF_STATUS_E_FAILURE; 5765 } 5766 5767 if (csa_ev->ies_present_flag & WMI_CSA_IE_PRESENT) { 5768 csa_ie = (struct csa_ie *)(&csa_ev->csa_ie[0]); 5769 csa_event->channel = csa_ie->new_channel; 5770 csa_event->switch_mode = csa_ie->switch_mode; 5771 csa_event->ies_present_flag |= MLME_CSA_IE_PRESENT; 5772 } else if (csa_ev->ies_present_flag & WMI_XCSA_IE_PRESENT) { 5773 xcsa_ie = (struct xcsa_ie *)(&csa_ev->xcsa_ie[0]); 5774 csa_event->channel = xcsa_ie->new_channel; 5775 csa_event->switch_mode = xcsa_ie->switch_mode; 5776 csa_event->new_op_class = xcsa_ie->new_class; 5777 csa_event->ies_present_flag |= MLME_XCSA_IE_PRESENT; 5778 } else { 5779 wmi_err("CSA Event error: No CSA IE present"); 5780 return QDF_STATUS_E_INVAL; 5781 } 5782 5783 wmi_debug("CSA IE Received: BSSID " QDF_MAC_ADDR_FMT " chan %d freq %d flag 0x%x width = %d freq1 = %d freq2 = %d op class = %d", 5784 QDF_MAC_ADDR_REF(csa_event->bssid.bytes), 5785 csa_event->channel, 5786 csa_event->csa_chan_freq, 5787 csa_event->ies_present_flag, 5788 csa_event->new_ch_width, 5789 csa_event->new_ch_freq_seg1, 5790 csa_event->new_ch_freq_seg2, 5791 csa_event->new_op_class); 5792 5793 if (!csa_event->channel) { 5794 wmi_err("CSA Event with channel %d. Ignore !!", 5795 csa_event->channel); 5796 return QDF_STATUS_E_FAILURE; 5797 } 5798 5799 return QDF_STATUS_SUCCESS; 5800 } 5801 5802 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 5803 static void 5804 populate_per_band_aoa_caps(struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5805 wmi_enhanced_aoa_per_band_caps_param per_band_cap) 5806 { 5807 uint8_t tbl_idx; 5808 uint16_t *gain_array = NULL; 5809 5810 if (per_band_cap.band_info == WMI_AOA_2G) 5811 gain_array = aoa_cap->max_agc_gain_per_tbl_2g; 5812 else if (per_band_cap.band_info == WMI_AOA_5G) 5813 gain_array = aoa_cap->max_agc_gain_per_tbl_5g; 5814 else if (per_band_cap.band_info == WMI_AOA_6G) 5815 gain_array = aoa_cap->max_agc_gain_per_tbl_6g; 5816 5817 if (!gain_array) { 5818 wmi_debug("unhandled AOA BAND TYPE!! fix it"); 5819 return; 5820 } 5821 5822 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) 5823 WMI_AOA_MAX_AGC_GAIN_GET(per_band_cap.max_agc_gain, 5824 tbl_idx, 5825 gain_array[tbl_idx]); 5826 } 5827 5828 static void 5829 populate_aoa_caps(struct wmi_unified *wmi_handle, 5830 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap, 5831 wmi_enhanced_aoa_caps_param *aoa_caps_param) 5832 { 5833 uint8_t tbl_idx; 5834 5835 aoa_cap->max_agc_gain_tbls = aoa_caps_param->max_agc_gain_tbls; 5836 if (aoa_cap->max_agc_gain_tbls > PSOC_MAX_NUM_AGC_GAIN_TBLS) { 5837 wmi_err("Num gain table > PSOC_MAX_NUM_AGC_GAIN_TBLS cap"); 5838 aoa_cap->max_agc_gain_tbls = PSOC_MAX_NUM_AGC_GAIN_TBLS; 5839 } 5840 5841 if (aoa_cap->max_agc_gain_tbls > WMI_AGC_MAX_GAIN_TABLE_IDX) { 5842 wmi_err("num gain table > WMI_AGC_MAX_GAIN_TABLE_IDX cap"); 5843 aoa_cap->max_agc_gain_tbls = WMI_AGC_MAX_GAIN_TABLE_IDX; 5844 } 5845 5846 for (tbl_idx = 0; tbl_idx < aoa_cap->max_agc_gain_tbls; tbl_idx++) { 5847 WMI_AOA_MAX_BDF_ENTRIES_GET 5848 (aoa_caps_param->max_bdf_gain_entries, 5849 tbl_idx, aoa_cap->max_bdf_entries_per_tbl[tbl_idx]); 5850 } 5851 } 5852 5853 /** 5854 * extract_aoa_caps_tlv() - extract aoa cap tlv 5855 * @wmi_handle: wmi handle 5856 * @event: pointer to event buffer 5857 * @aoa_cap: pointer to structure where capability needs to extracted 5858 * 5859 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 5860 */ 5861 static QDF_STATUS 5862 extract_aoa_caps_tlv(struct wmi_unified *wmi_handle, uint8_t *event, 5863 struct wlan_psoc_host_rcc_enh_aoa_caps_ext2 *aoa_cap) 5864 { 5865 int8_t band; 5866 5867 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 5868 5869 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 5870 if (!param_buf) { 5871 wmi_err("NULL param buf"); 5872 return QDF_STATUS_E_INVAL; 5873 } 5874 5875 if (!param_buf->aoa_caps_param) { 5876 wmi_debug("NULL aoa_caps_param"); 5877 return QDF_STATUS_E_INVAL; 5878 } 5879 5880 if (!param_buf->num_aoa_per_band_caps_param || 5881 !param_buf->aoa_per_band_caps_param) { 5882 wmi_debug("No aoa_per_band_caps_param"); 5883 return QDF_STATUS_E_INVAL; 5884 } 5885 populate_aoa_caps(wmi_handle, aoa_cap, param_buf->aoa_caps_param); 5886 5887 for (band = 0; band < param_buf->num_aoa_per_band_caps_param; band++) 5888 populate_per_band_aoa_caps 5889 (aoa_cap, param_buf->aoa_per_band_caps_param[band]); 5890 5891 return QDF_STATUS_SUCCESS; 5892 } 5893 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 5894 5895 /** 5896 * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw 5897 * @wmi_handle: wmi handle 5898 * @vdev_id: vdev id 5899 * @probe_rsp_info: probe response info 5900 * 5901 * Return: QDF_STATUS_SUCCESS for success or error code 5902 */ 5903 static QDF_STATUS send_probe_rsp_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle, 5904 uint8_t vdev_id, 5905 struct wmi_probe_resp_params *probe_rsp_info) 5906 { 5907 wmi_prb_tmpl_cmd_fixed_param *cmd; 5908 wmi_bcn_prb_info *bcn_prb_info; 5909 wmi_buf_t wmi_buf; 5910 uint32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; 5911 uint8_t *buf_ptr; 5912 QDF_STATUS ret; 5913 5914 wmi_debug("Send probe response template for vdev %d", vdev_id); 5915 5916 tmpl_len = probe_rsp_info->prb_rsp_template_len; 5917 tmpl_len_aligned = roundup(tmpl_len, sizeof(uint32_t)); 5918 5919 wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + 5920 sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + 5921 tmpl_len_aligned + 5922 prb_resp_tmpl_ml_info_size(probe_rsp_info); 5923 5924 if (wmi_buf_len > WMI_BEACON_TX_BUFFER_SIZE) { 5925 wmi_err("wmi_buf_len: %d > %d. Can't send wmi cmd", 5926 wmi_buf_len, WMI_BEACON_TX_BUFFER_SIZE); 5927 return QDF_STATUS_E_INVAL; 5928 } 5929 5930 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 5931 if (!wmi_buf) 5932 return QDF_STATUS_E_NOMEM; 5933 5934 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 5935 5936 cmd = (wmi_prb_tmpl_cmd_fixed_param *) buf_ptr; 5937 WMITLV_SET_HDR(&cmd->tlv_header, 5938 WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, 5939 WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); 5940 cmd->vdev_id = vdev_id; 5941 cmd->buf_len = tmpl_len; 5942 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5943 5944 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5945 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5946 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5947 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5948 bcn_prb_info->caps = 0; 5949 bcn_prb_info->erp = 0; 5950 buf_ptr += sizeof(wmi_bcn_prb_info); 5951 5952 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5953 buf_ptr += WMI_TLV_HDR_SIZE; 5954 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5955 buf_ptr += tmpl_len_aligned; 5956 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5957 5958 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5959 ret = wmi_unified_cmd_send(wmi_handle, 5960 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5961 if (QDF_IS_STATUS_ERROR(ret)) { 5962 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5963 wmi_buf_free(wmi_buf); 5964 } 5965 5966 return ret; 5967 } 5968 5969 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5970 #define WPI_IV_LEN 16 5971 5972 /** 5973 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5974 * 5975 * @dest_tx: destination address of tsc key counter 5976 * @src_tx: source address of tsc key counter 5977 * @dest_rx: destination address of rsc key counter 5978 * @src_rx: source address of rsc key counter 5979 * 5980 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5981 * 5982 * Return: None 5983 * 5984 */ 5985 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5986 uint8_t *dest_rx, uint8_t *src_rx) 5987 { 5988 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5989 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5990 } 5991 #else 5992 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5993 uint8_t *dest_rx, uint8_t *src_rx) 5994 { 5995 return; 5996 } 5997 #endif 5998 5999 /** 6000 * send_setup_install_key_cmd_tlv() - set key parameters 6001 * @wmi_handle: wmi handle 6002 * @key_params: key parameters 6003 * 6004 * This function fills structure from information 6005 * passed in key_params. 6006 * 6007 * Return: QDF_STATUS_SUCCESS - success 6008 * QDF_STATUS_E_FAILURE - failure 6009 * QDF_STATUS_E_NOMEM - not able to allocate buffer 6010 */ 6011 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 6012 struct set_key_params *key_params) 6013 { 6014 wmi_vdev_install_key_cmd_fixed_param *cmd; 6015 wmi_buf_t buf; 6016 uint8_t *buf_ptr; 6017 uint32_t len; 6018 uint8_t *key_data; 6019 QDF_STATUS status; 6020 6021 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 6022 WMI_TLV_HDR_SIZE; 6023 6024 buf = wmi_buf_alloc(wmi_handle, len); 6025 if (!buf) 6026 return QDF_STATUS_E_NOMEM; 6027 6028 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6029 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 6030 WMITLV_SET_HDR(&cmd->tlv_header, 6031 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 6032 WMITLV_GET_STRUCT_TLVLEN 6033 (wmi_vdev_install_key_cmd_fixed_param)); 6034 cmd->vdev_id = key_params->vdev_id; 6035 cmd->key_ix = key_params->key_idx; 6036 if (key_params->group_key_idx) { 6037 cmd->is_group_key_ix_valid = 1; 6038 cmd->group_key_ix = key_params->group_key_idx; 6039 } 6040 6041 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 6042 cmd->key_flags |= key_params->key_flags; 6043 cmd->key_cipher = key_params->key_cipher; 6044 if ((key_params->key_txmic_len) && 6045 (key_params->key_rxmic_len)) { 6046 cmd->key_txmic_len = key_params->key_txmic_len; 6047 cmd->key_rxmic_len = key_params->key_rxmic_len; 6048 } 6049 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 6050 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 6051 key_params->tx_iv, 6052 cmd->wpi_key_rsc_counter, 6053 key_params->rx_iv); 6054 #endif 6055 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 6056 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6057 roundup(key_params->key_len, sizeof(uint32_t))); 6058 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 6059 6060 /* for big endian host, copy engine byte_swap is enabled 6061 * But key_data is in network byte order 6062 * Need to byte swap the key_data - so when copy engine 6063 * does byte_swap - target gets key_data in the correct order 6064 */ 6065 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 6066 (const void *)key_params->key_data, 6067 key_params->key_len); 6068 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 6069 sizeof(wmi_key_seq_counter)); 6070 cmd->key_len = key_params->key_len; 6071 6072 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 6073 sizeof(wmi_key_seq_counter)); 6074 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 6075 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6076 WMI_VDEV_INSTALL_KEY_CMDID); 6077 if (QDF_IS_STATUS_ERROR(status)) { 6078 qdf_mem_zero(wmi_buf_data(buf), len); 6079 wmi_buf_free(buf); 6080 } 6081 return status; 6082 } 6083 6084 /** 6085 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 6086 * @wmi_handle: wmi handle 6087 * @vdev_id: vdev id 6088 * @p2p_ie: p2p IE 6089 * 6090 * Return: QDF_STATUS_SUCCESS for success or error code 6091 */ 6092 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 6093 uint32_t vdev_id, uint8_t *p2p_ie) 6094 { 6095 QDF_STATUS ret; 6096 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 6097 wmi_buf_t wmi_buf; 6098 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 6099 uint8_t *buf_ptr; 6100 6101 ie_len = (uint32_t) (p2p_ie[1] + 2); 6102 6103 /* More than one P2P IE may be included in a single frame. 6104 If multiple P2P IEs are present, the complete P2P attribute 6105 data consists of the concatenation of the P2P Attribute 6106 fields of the P2P IEs. The P2P Attributes field of each 6107 P2P IE may be any length up to the maximum (251 octets). 6108 In this case host sends one P2P IE to firmware so the length 6109 should not exceed more than 251 bytes 6110 */ 6111 if (ie_len > 251) { 6112 wmi_err("Invalid p2p ie length %u", ie_len); 6113 return QDF_STATUS_E_INVAL; 6114 } 6115 6116 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 6117 6118 wmi_buf_len = 6119 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 6120 WMI_TLV_HDR_SIZE; 6121 6122 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6123 if (!wmi_buf) 6124 return QDF_STATUS_E_NOMEM; 6125 6126 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6127 6128 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 6129 WMITLV_SET_HDR(&cmd->tlv_header, 6130 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 6131 WMITLV_GET_STRUCT_TLVLEN 6132 (wmi_p2p_go_set_beacon_ie_fixed_param)); 6133 cmd->vdev_id = vdev_id; 6134 cmd->ie_buf_len = ie_len; 6135 6136 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 6137 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 6138 buf_ptr += WMI_TLV_HDR_SIZE; 6139 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6140 6141 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 6142 6143 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 6144 ret = wmi_unified_cmd_send(wmi_handle, 6145 wmi_buf, wmi_buf_len, 6146 WMI_P2P_GO_SET_BEACON_IE); 6147 if (QDF_IS_STATUS_ERROR(ret)) { 6148 wmi_err("Failed to send bcn tmpl: %d", ret); 6149 wmi_buf_free(wmi_buf); 6150 } 6151 6152 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 6153 return ret; 6154 } 6155 6156 /** 6157 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6158 * @wmi_handle: wmi handle 6159 * @psetoui: OUI parameters 6160 * 6161 * set scan probe OUI parameters in firmware 6162 * 6163 * Return: QDF status 6164 */ 6165 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6166 struct scan_mac_oui *psetoui) 6167 { 6168 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6169 wmi_buf_t wmi_buf; 6170 uint32_t len; 6171 uint8_t *buf_ptr; 6172 uint32_t *oui_buf; 6173 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 6174 6175 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6176 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 6177 6178 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6179 if (!wmi_buf) 6180 return QDF_STATUS_E_NOMEM; 6181 6182 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6183 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6184 WMITLV_SET_HDR(&cmd->tlv_header, 6185 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6186 WMITLV_GET_STRUCT_TLVLEN 6187 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6188 6189 oui_buf = &cmd->prob_req_oui; 6190 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6191 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6192 | psetoui->oui[2]; 6193 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 6194 6195 cmd->vdev_id = psetoui->vdev_id; 6196 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6197 if (psetoui->enb_probe_req_sno_randomization) 6198 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6199 6200 if (ie_allowlist->allow_list) { 6201 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6202 &cmd->num_vendor_oui, 6203 ie_allowlist); 6204 cmd->flags |= 6205 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6206 } 6207 6208 buf_ptr += sizeof(*cmd); 6209 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6210 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6211 buf_ptr += WMI_TLV_HDR_SIZE; 6212 6213 if (cmd->num_vendor_oui != 0) { 6214 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6215 ie_allowlist->voui); 6216 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6217 } 6218 6219 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 6220 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6221 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6222 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 6223 wmi_buf_free(wmi_buf); 6224 return QDF_STATUS_E_FAILURE; 6225 } 6226 return QDF_STATUS_SUCCESS; 6227 } 6228 6229 #ifdef IPA_OFFLOAD 6230 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 6231 * @wmi_handle: wmi handle 6232 * @ipa_offload: ipa offload control parameter 6233 * 6234 * Returns: 0 on success, error number otherwise 6235 */ 6236 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 6237 struct ipa_uc_offload_control_params *ipa_offload) 6238 { 6239 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 6240 wmi_buf_t wmi_buf; 6241 uint32_t len; 6242 u_int8_t *buf_ptr; 6243 6244 len = sizeof(*cmd); 6245 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6246 if (!wmi_buf) 6247 return QDF_STATUS_E_NOMEM; 6248 6249 wmi_debug("offload_type=%d, enable=%d", 6250 ipa_offload->offload_type, ipa_offload->enable); 6251 6252 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 6253 6254 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 6255 WMITLV_SET_HDR(&cmd->tlv_header, 6256 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 6257 WMITLV_GET_STRUCT_TLVLEN( 6258 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 6259 6260 cmd->offload_type = ipa_offload->offload_type; 6261 cmd->vdev_id = ipa_offload->vdev_id; 6262 cmd->enable = ipa_offload->enable; 6263 6264 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 6265 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6266 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 6267 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 6268 wmi_buf_free(wmi_buf); 6269 return QDF_STATUS_E_FAILURE; 6270 } 6271 6272 return QDF_STATUS_SUCCESS; 6273 } 6274 #endif 6275 6276 /** 6277 * send_pno_stop_cmd_tlv() - PNO stop request 6278 * @wmi_handle: wmi handle 6279 * @vdev_id: vdev id 6280 * 6281 * This function request FW to stop ongoing PNO operation. 6282 * 6283 * Return: QDF status 6284 */ 6285 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6286 { 6287 wmi_nlo_config_cmd_fixed_param *cmd; 6288 int32_t len = sizeof(*cmd); 6289 wmi_buf_t buf; 6290 uint8_t *buf_ptr; 6291 int ret; 6292 6293 /* 6294 * TLV place holder for array of structures nlo_configured_parameters 6295 * TLV place holder for array of uint32_t channel_list 6296 * TLV place holder for chnl prediction cfg 6297 */ 6298 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6299 buf = wmi_buf_alloc(wmi_handle, len); 6300 if (!buf) 6301 return QDF_STATUS_E_NOMEM; 6302 6303 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6304 buf_ptr = (uint8_t *) cmd; 6305 6306 WMITLV_SET_HDR(&cmd->tlv_header, 6307 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6308 WMITLV_GET_STRUCT_TLVLEN 6309 (wmi_nlo_config_cmd_fixed_param)); 6310 6311 cmd->vdev_id = vdev_id; 6312 cmd->flags = WMI_NLO_CONFIG_STOP; 6313 buf_ptr += sizeof(*cmd); 6314 6315 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6316 buf_ptr += WMI_TLV_HDR_SIZE; 6317 6318 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 6319 buf_ptr += WMI_TLV_HDR_SIZE; 6320 6321 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6322 buf_ptr += WMI_TLV_HDR_SIZE; 6323 6324 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6325 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6326 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6327 if (ret) { 6328 wmi_err("Failed to send nlo wmi cmd"); 6329 wmi_buf_free(buf); 6330 return QDF_STATUS_E_FAILURE; 6331 } 6332 6333 return QDF_STATUS_SUCCESS; 6334 } 6335 6336 /** 6337 * send_obss_disable_cmd_tlv() - disable obss scan request 6338 * @wmi_handle: wmi handle 6339 * @vdev_id: vdev id 6340 * 6341 * This function request FW to disable ongoing obss scan operation. 6342 * 6343 * Return: QDF status 6344 */ 6345 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 6346 uint8_t vdev_id) 6347 { 6348 QDF_STATUS status; 6349 wmi_buf_t buf; 6350 wmi_obss_scan_disable_cmd_fixed_param *cmd; 6351 int len = sizeof(*cmd); 6352 6353 buf = wmi_buf_alloc(wmi_handle, len); 6354 if (!buf) 6355 return QDF_STATUS_E_NOMEM; 6356 6357 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 6358 6359 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 6360 WMITLV_SET_HDR(&cmd->tlv_header, 6361 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 6362 WMITLV_GET_STRUCT_TLVLEN( 6363 wmi_obss_scan_disable_cmd_fixed_param)); 6364 6365 cmd->vdev_id = vdev_id; 6366 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6367 WMI_OBSS_SCAN_DISABLE_CMDID); 6368 if (QDF_IS_STATUS_ERROR(status)) 6369 wmi_buf_free(buf); 6370 6371 return status; 6372 } 6373 6374 /** 6375 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 6376 * @buf_ptr: Buffer passed by upper layers 6377 * @pno: Buffer to be sent to the firmware 6378 * 6379 * Copy the PNO Channel prediction configuration parameters 6380 * passed by the upper layers to a WMI format TLV and send it 6381 * down to the firmware. 6382 * 6383 * Return: None 6384 */ 6385 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 6386 struct pno_scan_req_params *pno) 6387 { 6388 nlo_channel_prediction_cfg *channel_prediction_cfg = 6389 (nlo_channel_prediction_cfg *) buf_ptr; 6390 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 6391 WMITLV_TAG_ARRAY_BYTE, 6392 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 6393 #ifdef FEATURE_WLAN_SCAN_PNO 6394 channel_prediction_cfg->enable = pno->pno_channel_prediction; 6395 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 6396 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 6397 channel_prediction_cfg->full_scan_period_ms = 6398 pno->channel_prediction_full_scan; 6399 #endif 6400 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6401 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 6402 channel_prediction_cfg->enable, 6403 channel_prediction_cfg->top_k_num, 6404 channel_prediction_cfg->stationary_threshold, 6405 channel_prediction_cfg->full_scan_period_ms); 6406 } 6407 6408 /** 6409 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 6410 * @wmi_handle: wmi handle 6411 * @buf_ptr: Buffer passed by upper layers 6412 * @buf_len: Length of passed buffer by upper layer 6413 * 6414 * Copy the buffer passed by the upper layers and send it 6415 * down to the firmware. 6416 * 6417 * Return: None 6418 */ 6419 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6420 void *buf_ptr, uint32_t buf_len) 6421 { 6422 wmi_buf_t buf = NULL; 6423 QDF_STATUS status; 6424 int len; 6425 uint8_t *data_ptr; 6426 6427 len = buf_len; 6428 buf = wmi_buf_alloc(wmi_handle, len); 6429 if (!buf) 6430 return QDF_STATUS_E_NOMEM; 6431 6432 data_ptr = (uint8_t *)wmi_buf_data(buf); 6433 qdf_mem_copy(data_ptr, buf_ptr, len); 6434 6435 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6436 status = wmi_unified_cmd_send(wmi_handle, buf, 6437 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6438 6439 if (QDF_IS_STATUS_ERROR(status)) { 6440 wmi_buf_free(buf); 6441 return QDF_STATUS_E_FAILURE; 6442 } 6443 return QDF_STATUS_SUCCESS; 6444 } 6445 6446 /** 6447 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6448 * @wmi_handle: wmi handle 6449 * @buf_ptr: Buffer passed by upper layers 6450 * @buf_len: Length of passed buffer by upper layer 6451 * 6452 * Copy the buffer passed by the upper layers and send it 6453 * down to the firmware. 6454 * 6455 * Return: None 6456 */ 6457 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6458 void *buf_ptr, uint32_t buf_len) 6459 { 6460 wmi_buf_t buf = NULL; 6461 QDF_STATUS status; 6462 int len; 6463 uint8_t *data_ptr; 6464 6465 len = buf_len; 6466 buf = wmi_buf_alloc(wmi_handle, len); 6467 if (!buf) 6468 return QDF_STATUS_E_NOMEM; 6469 6470 data_ptr = (uint8_t *)wmi_buf_data(buf); 6471 qdf_mem_copy(data_ptr, buf_ptr, len); 6472 6473 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6474 status = wmi_unified_cmd_send(wmi_handle, buf, 6475 len, 6476 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6477 6478 if (QDF_IS_STATUS_ERROR(status)) { 6479 wmi_buf_free(buf); 6480 return QDF_STATUS_E_FAILURE; 6481 } 6482 return QDF_STATUS_SUCCESS; 6483 } 6484 6485 /** 6486 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6487 * @wmi_handle: wmi handle 6488 * @evt_buf: event buffer 6489 * @more_flag: buffer to populate more flag 6490 * 6491 * Return: status of operation 6492 */ 6493 static QDF_STATUS 6494 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6495 uint32_t *more_flag) 6496 { 6497 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6498 wmi_ctrl_path_stats_event_fixed_param *ev; 6499 6500 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6501 if (!param_buf) { 6502 wmi_err_rl("param_buf is NULL"); 6503 return QDF_STATUS_E_FAILURE; 6504 } 6505 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6506 6507 *more_flag = ev->more; 6508 return QDF_STATUS_SUCCESS; 6509 } 6510 6511 /** 6512 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6513 * from event data 6514 * @wmi_handle: wmi handle 6515 * @evt_buf: event buffer 6516 * @end_of_event_flag: buffer to populate end_of_event flag 6517 * 6518 * Return: status of operation 6519 */ 6520 static QDF_STATUS 6521 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6522 uint32_t *end_of_event_flag) 6523 { 6524 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6525 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6526 6527 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6528 if (!param_buf) { 6529 wmi_err_rl("param_buf is NULL"); 6530 return QDF_STATUS_E_FAILURE; 6531 } 6532 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6533 param_buf->fixed_param; 6534 6535 *end_of_event_flag = ev->end_of_event; 6536 return QDF_STATUS_SUCCESS; 6537 } 6538 6539 /** 6540 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6541 * from event data 6542 * @wmi_handle: wmi handle 6543 * @evt_buf: event buffer 6544 * @event_count_flag: buffer to populate event_count flag 6545 * 6546 * Return: status of operation 6547 */ 6548 static QDF_STATUS 6549 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6550 uint32_t *event_count_flag) 6551 { 6552 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6553 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6554 6555 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6556 if (!param_buf) { 6557 wmi_err_rl("param_buf is NULL"); 6558 return QDF_STATUS_E_FAILURE; 6559 } 6560 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6561 param_buf->fixed_param; 6562 6563 *event_count_flag = ev->event_count; 6564 return QDF_STATUS_SUCCESS; 6565 } 6566 6567 /** 6568 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6569 * @wmi_handle: wmi handle 6570 * @params: configuration parameters 6571 * 6572 * Return: QDF_STATUS 6573 */ 6574 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6575 struct nlo_mawc_params *params) 6576 { 6577 wmi_buf_t buf = NULL; 6578 QDF_STATUS status; 6579 int len; 6580 uint8_t *buf_ptr; 6581 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6582 6583 len = sizeof(*wmi_nlo_mawc_params); 6584 buf = wmi_buf_alloc(wmi_handle, len); 6585 if (!buf) 6586 return QDF_STATUS_E_NOMEM; 6587 6588 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6589 wmi_nlo_mawc_params = 6590 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6591 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6592 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6593 WMITLV_GET_STRUCT_TLVLEN 6594 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6595 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6596 if (params->enable) 6597 wmi_nlo_mawc_params->enable = 1; 6598 else 6599 wmi_nlo_mawc_params->enable = 0; 6600 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6601 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6602 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6603 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6604 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6605 wmi_nlo_mawc_params->exp_backoff_ratio, 6606 wmi_nlo_mawc_params->init_scan_interval, 6607 wmi_nlo_mawc_params->max_scan_interval); 6608 6609 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6610 status = wmi_unified_cmd_send(wmi_handle, buf, 6611 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6612 if (QDF_IS_STATUS_ERROR(status)) { 6613 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6614 status); 6615 wmi_buf_free(buf); 6616 return QDF_STATUS_E_FAILURE; 6617 } 6618 6619 return QDF_STATUS_SUCCESS; 6620 } 6621 6622 /** 6623 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6624 * scan 6625 * @scan_freq_list: frequency list for pno scan 6626 * 6627 * Return: void 6628 */ 6629 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6630 { 6631 uint32_t i; 6632 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6633 uint32_t len = 0; 6634 struct chan_info *chan_info; 6635 int ret; 6636 6637 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6638 for (i = 0; i < scan_freq_list->num_chan; i++) { 6639 chan_info = &scan_freq_list->chan[i]; 6640 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6641 " %d[%d]", chan_info->freq, 6642 chan_info->flags); 6643 if (ret <= 0) 6644 break; 6645 len += ret; 6646 if (len >= (sizeof(info) - 20)) { 6647 wmi_nofl_debug("Freq[flag]:%s", 6648 info); 6649 len = 0; 6650 } 6651 } 6652 if (len) 6653 wmi_nofl_debug("Freq[flag]:%s", info); 6654 } 6655 6656 /** 6657 * send_pno_start_cmd_tlv() - PNO start request 6658 * @wmi_handle: wmi handle 6659 * @pno: PNO request 6660 * 6661 * This function request FW to start PNO request. 6662 * Request: QDF status 6663 */ 6664 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6665 struct pno_scan_req_params *pno) 6666 { 6667 wmi_nlo_config_cmd_fixed_param *cmd; 6668 nlo_configured_parameters *nlo_list; 6669 uint32_t *channel_list; 6670 int32_t len; 6671 qdf_freq_t freq; 6672 wmi_buf_t buf; 6673 uint8_t *buf_ptr; 6674 uint8_t i; 6675 int ret; 6676 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6677 connected_nlo_rssi_params *nlo_relative_rssi; 6678 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6679 6680 /* 6681 * TLV place holder for array nlo_configured_parameters(nlo_list) 6682 * TLV place holder for array of uint32_t channel_list 6683 * TLV place holder for chnnl prediction cfg 6684 * TLV place holder for array of wmi_vendor_oui 6685 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6686 */ 6687 len = sizeof(*cmd) + 6688 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6689 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6690 6691 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6692 len += sizeof(nlo_configured_parameters) * 6693 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6694 len += sizeof(nlo_channel_prediction_cfg); 6695 len += sizeof(enlo_candidate_score_params); 6696 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6697 len += sizeof(connected_nlo_rssi_params); 6698 len += sizeof(connected_nlo_bss_band_rssi_pref); 6699 6700 buf = wmi_buf_alloc(wmi_handle, len); 6701 if (!buf) 6702 return QDF_STATUS_E_NOMEM; 6703 6704 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6705 6706 buf_ptr = (uint8_t *) cmd; 6707 WMITLV_SET_HDR(&cmd->tlv_header, 6708 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6709 WMITLV_GET_STRUCT_TLVLEN 6710 (wmi_nlo_config_cmd_fixed_param)); 6711 cmd->vdev_id = pno->vdev_id; 6712 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6713 6714 #ifdef FEATURE_WLAN_SCAN_PNO 6715 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6716 pno->adaptive_dwell_mode); 6717 #endif 6718 /* Current FW does not support min-max range for dwell time */ 6719 cmd->active_dwell_time = pno->active_dwell_time; 6720 cmd->passive_dwell_time = pno->passive_dwell_time; 6721 6722 if (pno->do_passive_scan) 6723 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6724 /* Copy scan interval */ 6725 cmd->fast_scan_period = pno->fast_scan_period; 6726 cmd->slow_scan_period = pno->slow_scan_period; 6727 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6728 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6729 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6730 6731 /* mac randomization attributes */ 6732 if (pno->scan_random.randomize) { 6733 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6734 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6735 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6736 pno->scan_random.mac_mask, 6737 &cmd->mac_addr, 6738 &cmd->mac_mask); 6739 } 6740 6741 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6742 6743 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6744 6745 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6746 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6747 buf_ptr += WMI_TLV_HDR_SIZE; 6748 6749 nlo_list = (nlo_configured_parameters *) buf_ptr; 6750 for (i = 0; i < cmd->no_of_ssids; i++) { 6751 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6752 WMITLV_TAG_ARRAY_BYTE, 6753 WMITLV_GET_STRUCT_TLVLEN 6754 (nlo_configured_parameters)); 6755 /* Copy ssid and it's length */ 6756 nlo_list[i].ssid.valid = true; 6757 nlo_list[i].ssid.ssid.ssid_len = 6758 pno->networks_list[i].ssid.length; 6759 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6760 pno->networks_list[i].ssid.ssid, 6761 nlo_list[i].ssid.ssid.ssid_len); 6762 6763 /* Copy rssi threshold */ 6764 if (pno->networks_list[i].rssi_thresh && 6765 pno->networks_list[i].rssi_thresh > 6766 WMI_RSSI_THOLD_DEFAULT) { 6767 nlo_list[i].rssi_cond.valid = true; 6768 nlo_list[i].rssi_cond.rssi = 6769 pno->networks_list[i].rssi_thresh; 6770 } 6771 nlo_list[i].bcast_nw_type.valid = true; 6772 nlo_list[i].bcast_nw_type.bcast_nw_type = 6773 pno->networks_list[i].bc_new_type; 6774 } 6775 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6776 6777 /* Copy channel info */ 6778 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6779 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6780 (cmd->num_of_channels * sizeof(uint32_t))); 6781 buf_ptr += WMI_TLV_HDR_SIZE; 6782 6783 channel_list = (uint32_t *) buf_ptr; 6784 for (i = 0; i < cmd->num_of_channels; i++) { 6785 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6786 pno->networks_list[0].pno_chan_list.chan[i].freq); 6787 6788 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6789 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6790 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6791 wlan_chan_to_freq(freq)); 6792 } 6793 6794 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6795 pno->networks_list[0].pno_chan_list.chan[i].flags); 6796 } 6797 6798 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6799 6800 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6801 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6802 sizeof(nlo_channel_prediction_cfg)); 6803 buf_ptr += WMI_TLV_HDR_SIZE; 6804 wmi_set_pno_channel_prediction(buf_ptr, pno); 6805 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6806 /** TODO: Discrete firmware doesn't have command/option to configure 6807 * App IE which comes from wpa_supplicant as of part PNO start request. 6808 */ 6809 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6810 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6811 buf_ptr += sizeof(enlo_candidate_score_params); 6812 6813 if (ie_allowlist->allow_list) { 6814 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6815 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6816 &cmd->num_vendor_oui, 6817 ie_allowlist); 6818 } 6819 6820 /* ie allow list */ 6821 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6822 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6823 buf_ptr += WMI_TLV_HDR_SIZE; 6824 if (cmd->num_vendor_oui != 0) { 6825 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6826 ie_allowlist->voui); 6827 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6828 } 6829 6830 if (pno->relative_rssi_set) 6831 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6832 6833 /* 6834 * Firmware calculation using connected PNO params: 6835 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6836 * deduction of rssi_pref for chosen band_pref and 6837 * addition of rssi_pref for remaining bands (other than chosen band). 6838 */ 6839 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6840 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6841 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6842 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6843 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6844 buf_ptr += sizeof(*nlo_relative_rssi); 6845 6846 /* 6847 * As of now Kernel and Host supports one band and rssi preference. 6848 * Firmware supports array of band and rssi preferences 6849 */ 6850 cmd->num_cnlo_band_pref = 1; 6851 WMITLV_SET_HDR(buf_ptr, 6852 WMITLV_TAG_ARRAY_STRUC, 6853 cmd->num_cnlo_band_pref * 6854 sizeof(connected_nlo_bss_band_rssi_pref)); 6855 buf_ptr += WMI_TLV_HDR_SIZE; 6856 6857 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6858 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6859 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6860 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6861 WMITLV_GET_STRUCT_TLVLEN( 6862 connected_nlo_bss_band_rssi_pref)); 6863 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6864 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6865 } 6866 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6867 6868 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6869 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6870 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6871 if (ret) { 6872 wmi_err("Failed to send nlo wmi cmd"); 6873 wmi_buf_free(buf); 6874 return QDF_STATUS_E_FAILURE; 6875 } 6876 6877 return QDF_STATUS_SUCCESS; 6878 } 6879 6880 /** 6881 * is_service_enabled_tlv() - Check if service enabled 6882 * @wmi_handle: wmi handle 6883 * @service_id: service identifier 6884 * 6885 * Return: 1 enabled, 0 disabled 6886 */ 6887 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6888 uint32_t service_id) 6889 { 6890 struct wmi_soc *soc = wmi_handle->soc; 6891 6892 if (!soc->wmi_service_bitmap) { 6893 wmi_err("WMI service bit map is not saved yet"); 6894 return false; 6895 } 6896 6897 /* if wmi_service_enabled was received with extended2 bitmap, 6898 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6899 */ 6900 if (soc->wmi_ext2_service_bitmap) { 6901 if (!soc->wmi_ext_service_bitmap) { 6902 wmi_err("WMI service ext bit map is not saved yet"); 6903 return false; 6904 } 6905 6906 if (service_id > WMI_MAX_EXT_SERVICE && 6907 (service_id - WMI_MAX_EXT_SERVICE) / 32 >= 6908 soc->wmi_ext2_service_bitmap_len) { 6909 wmi_err("WMI service ext2 bit = %d is not advertised by fw", 6910 service_id); 6911 return false; 6912 } 6913 6914 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6915 soc->wmi_ext_service_bitmap, 6916 soc->wmi_ext2_service_bitmap, 6917 service_id); 6918 } 6919 6920 if (service_id >= WMI_MAX_EXT_SERVICE) { 6921 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6922 service_id); 6923 return false; 6924 } 6925 /* if wmi_service_enabled was received with extended bitmap, 6926 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6927 */ 6928 if (soc->wmi_ext_service_bitmap) 6929 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6930 soc->wmi_ext_service_bitmap, 6931 service_id); 6932 6933 if (service_id >= WMI_MAX_SERVICE) { 6934 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6935 service_id); 6936 return false; 6937 } 6938 6939 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6940 service_id); 6941 } 6942 6943 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6944 /** 6945 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6946 * @wmi_handle: wmi handle 6947 * @clear_req: ll stats clear request command params 6948 * 6949 * Return: QDF_STATUS_SUCCESS for success or error code 6950 */ 6951 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6952 const struct ll_stats_clear_params *clear_req) 6953 { 6954 wmi_clear_link_stats_cmd_fixed_param *cmd; 6955 int32_t len; 6956 wmi_buf_t buf; 6957 uint8_t *buf_ptr; 6958 int ret; 6959 6960 len = sizeof(*cmd); 6961 buf = wmi_buf_alloc(wmi_handle, len); 6962 6963 if (!buf) 6964 return QDF_STATUS_E_NOMEM; 6965 6966 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6967 qdf_mem_zero(buf_ptr, len); 6968 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6969 6970 WMITLV_SET_HDR(&cmd->tlv_header, 6971 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6972 WMITLV_GET_STRUCT_TLVLEN 6973 (wmi_clear_link_stats_cmd_fixed_param)); 6974 6975 cmd->stop_stats_collection_req = clear_req->stop_req; 6976 cmd->vdev_id = clear_req->vdev_id; 6977 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6978 6979 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6980 &cmd->peer_macaddr); 6981 6982 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6983 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6984 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6985 cmd->stop_stats_collection_req, 6986 cmd->vdev_id, cmd->stats_clear_req_mask, 6987 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6988 6989 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6990 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6991 WMI_CLEAR_LINK_STATS_CMDID); 6992 if (ret) { 6993 wmi_err("Failed to send clear link stats req"); 6994 wmi_buf_free(buf); 6995 return QDF_STATUS_E_FAILURE; 6996 } 6997 6998 wmi_debug("Clear Link Layer Stats request sent successfully"); 6999 return QDF_STATUS_SUCCESS; 7000 } 7001 7002 /** 7003 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 7004 * @wmi_handle: wmi handle 7005 * @set_req: ll stats set request command params 7006 * 7007 * Return: QDF_STATUS_SUCCESS for success or error code 7008 */ 7009 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 7010 const struct ll_stats_set_params *set_req) 7011 { 7012 wmi_start_link_stats_cmd_fixed_param *cmd; 7013 int32_t len; 7014 wmi_buf_t buf; 7015 uint8_t *buf_ptr; 7016 int ret; 7017 7018 len = sizeof(*cmd); 7019 buf = wmi_buf_alloc(wmi_handle, len); 7020 7021 if (!buf) 7022 return QDF_STATUS_E_NOMEM; 7023 7024 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7025 qdf_mem_zero(buf_ptr, len); 7026 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 7027 7028 WMITLV_SET_HDR(&cmd->tlv_header, 7029 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 7030 WMITLV_GET_STRUCT_TLVLEN 7031 (wmi_start_link_stats_cmd_fixed_param)); 7032 7033 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 7034 cmd->aggressive_statistics_gathering = 7035 set_req->aggressive_statistics_gathering; 7036 7037 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 7038 cmd->mpdu_size_threshold, 7039 cmd->aggressive_statistics_gathering); 7040 7041 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 7042 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7043 WMI_START_LINK_STATS_CMDID); 7044 if (ret) { 7045 wmi_err("Failed to send set link stats request"); 7046 wmi_buf_free(buf); 7047 return QDF_STATUS_E_FAILURE; 7048 } 7049 7050 return QDF_STATUS_SUCCESS; 7051 } 7052 7053 /** 7054 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 7055 * @wmi_handle: wmi handle 7056 * @get_req: ll stats get request command params 7057 * 7058 * Return: QDF_STATUS_SUCCESS for success or error code 7059 */ 7060 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 7061 const struct ll_stats_get_params *get_req) 7062 { 7063 wmi_request_link_stats_cmd_fixed_param *cmd; 7064 int32_t len; 7065 wmi_buf_t buf; 7066 uint8_t *buf_ptr; 7067 int ret; 7068 bool is_link_stats_over_qmi; 7069 7070 len = sizeof(*cmd); 7071 buf = wmi_buf_alloc(wmi_handle, len); 7072 7073 if (!buf) 7074 return QDF_STATUS_E_NOMEM; 7075 7076 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7077 qdf_mem_zero(buf_ptr, len); 7078 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 7079 7080 WMITLV_SET_HDR(&cmd->tlv_header, 7081 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 7082 WMITLV_GET_STRUCT_TLVLEN 7083 (wmi_request_link_stats_cmd_fixed_param)); 7084 7085 cmd->request_id = get_req->req_id; 7086 cmd->stats_type = get_req->param_id_mask; 7087 cmd->vdev_id = get_req->vdev_id; 7088 7089 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7090 &cmd->peer_macaddr); 7091 7092 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 7093 cmd->request_id, cmd->stats_type, cmd->vdev_id, 7094 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7095 7096 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 7097 is_link_stats_over_qmi = is_service_enabled_tlv( 7098 wmi_handle, 7099 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7100 7101 if (is_link_stats_over_qmi) { 7102 ret = wmi_unified_cmd_send_over_qmi( 7103 wmi_handle, buf, len, 7104 WMI_REQUEST_LINK_STATS_CMDID); 7105 } else { 7106 ret = wmi_unified_cmd_send_pm_chk( 7107 wmi_handle, buf, len, 7108 WMI_REQUEST_LINK_STATS_CMDID, true); 7109 } 7110 7111 if (ret) { 7112 wmi_buf_free(buf); 7113 return QDF_STATUS_E_FAILURE; 7114 } 7115 7116 return QDF_STATUS_SUCCESS; 7117 } 7118 7119 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 7120 #ifdef WLAN_FEATURE_11BE_MLO 7121 static int 7122 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7123 { 7124 int32_t len = 0; 7125 7126 /* In case of MLO connection, update the length of the buffer. 7127 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 7128 * hence just update the TLV header, but allocate no memory for it. 7129 */ 7130 if (!get_req->is_mlo_req) 7131 return len; 7132 7133 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 7134 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 7135 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 7136 7137 return len; 7138 } 7139 7140 static void 7141 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7142 void *buf_ptr) 7143 { 7144 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7145 uint32_t *vdev_id_bitmap; 7146 wmi_mac_addr *mld_mac; 7147 7148 /* In case of MLO connection, update the TLV Headers */ 7149 if (!get_req->is_mlo_req) 7150 return; 7151 7152 buf_ptr += sizeof(*unified_cmd); 7153 7154 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 7155 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7156 buf_ptr += WMI_TLV_HDR_SIZE; 7157 7158 /* Adding vdev_bitmap_id array TLV */ 7159 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7160 sizeof(*vdev_id_bitmap)); 7161 buf_ptr += WMI_TLV_HDR_SIZE; 7162 vdev_id_bitmap = buf_ptr; 7163 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 7164 buf_ptr += sizeof(*vdev_id_bitmap); 7165 7166 /* Adding mld_macaddr array TLV */ 7167 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 7168 sizeof(*mld_mac)); 7169 buf_ptr += WMI_TLV_HDR_SIZE; 7170 mld_mac = buf_ptr; 7171 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 7172 7173 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 7174 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 7175 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 7176 } 7177 #else 7178 static inline int 7179 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7180 { 7181 return 0; 7182 } 7183 7184 static inline void 7185 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7186 void *buf_ptr) 7187 { 7188 } 7189 #endif 7190 7191 /** 7192 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 7193 * station request 7194 * @wmi_handle: wmi handle 7195 * @get_req: ll stats get request command params 7196 * 7197 * Return: QDF_STATUS_SUCCESS for success or error code 7198 */ 7199 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 7200 wmi_unified_t wmi_handle, 7201 const struct ll_stats_get_params *get_req) 7202 { 7203 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7204 int32_t len; 7205 wmi_buf_t buf; 7206 void *buf_ptr; 7207 QDF_STATUS ret; 7208 bool is_ll_get_sta_stats_over_qmi; 7209 7210 len = sizeof(*unified_cmd); 7211 len += wmi_get_tlv_length_for_mlo_stats(get_req); 7212 7213 buf = wmi_buf_alloc(wmi_handle, len); 7214 if (!buf) 7215 return QDF_STATUS_E_NOMEM; 7216 7217 buf_ptr = wmi_buf_data(buf); 7218 7219 unified_cmd = buf_ptr; 7220 WMITLV_SET_HDR( 7221 &unified_cmd->tlv_header, 7222 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 7223 WMITLV_GET_STRUCT_TLVLEN 7224 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 7225 7226 unified_cmd->link_stats_type = get_req->param_id_mask; 7227 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 7228 WMI_REQUEST_PEER_STAT | 7229 WMI_REQUEST_VDEV_STAT | 7230 WMI_REQUEST_PDEV_STAT | 7231 WMI_REQUEST_VDEV_EXTD_STAT | 7232 WMI_REQUEST_PEER_EXTD2_STAT | 7233 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 7234 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7235 wmi_handle, 7236 WMI_HOST_PDEV_ID_SOC); 7237 7238 unified_cmd->vdev_id = get_req->vdev_id; 7239 unified_cmd->request_id = get_req->req_id; 7240 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7241 &unified_cmd->peer_macaddr); 7242 7243 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 7244 QDF_MAC_ADDR_FMT, 7245 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 7246 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7247 7248 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 7249 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 7250 7251 /** 7252 * FW support for LL_get_sta command. True represents the unified 7253 * ll_get_sta command should be sent over QMI always irrespective of 7254 * WOW state. 7255 */ 7256 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 7257 wmi_handle, 7258 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7259 7260 if (is_ll_get_sta_stats_over_qmi) { 7261 ret = wmi_unified_cmd_send_over_qmi( 7262 wmi_handle, buf, len, 7263 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 7264 } else { 7265 ret = wmi_unified_cmd_send_pm_chk( 7266 wmi_handle, buf, len, 7267 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 7268 true); 7269 } 7270 7271 if (QDF_IS_STATUS_ERROR(ret)) { 7272 wmi_buf_free(buf); 7273 return QDF_STATUS_E_FAILURE; 7274 } 7275 7276 return ret; 7277 } 7278 #endif 7279 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 7280 7281 /** 7282 * send_congestion_cmd_tlv() - send request to fw to get CCA 7283 * @wmi_handle: wmi handle 7284 * @vdev_id: vdev id 7285 * 7286 * Return: QDF status 7287 */ 7288 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 7289 uint8_t vdev_id) 7290 { 7291 wmi_buf_t buf; 7292 wmi_request_stats_cmd_fixed_param *cmd; 7293 uint8_t len; 7294 uint8_t *buf_ptr; 7295 7296 len = sizeof(*cmd); 7297 buf = wmi_buf_alloc(wmi_handle, len); 7298 if (!buf) 7299 return QDF_STATUS_E_FAILURE; 7300 7301 buf_ptr = wmi_buf_data(buf); 7302 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 7303 WMITLV_SET_HDR(&cmd->tlv_header, 7304 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7305 WMITLV_GET_STRUCT_TLVLEN 7306 (wmi_request_stats_cmd_fixed_param)); 7307 7308 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 7309 cmd->vdev_id = vdev_id; 7310 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 7311 cmd->vdev_id, cmd->stats_id); 7312 7313 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7314 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7315 WMI_REQUEST_STATS_CMDID)) { 7316 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 7317 wmi_buf_free(buf); 7318 return QDF_STATUS_E_FAILURE; 7319 } 7320 7321 return QDF_STATUS_SUCCESS; 7322 } 7323 7324 /** 7325 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 7326 * @wmi_handle: wmi handle 7327 * 7328 * Return: QDF status 7329 */ 7330 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 7331 { 7332 wmi_buf_t buf; 7333 wmi_request_stats_cmd_fixed_param *cmd; 7334 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7335 7336 buf = wmi_buf_alloc(wmi_handle, len); 7337 if (!buf) 7338 return QDF_STATUS_E_FAILURE; 7339 7340 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7341 WMITLV_SET_HDR(&cmd->tlv_header, 7342 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7343 WMITLV_GET_STRUCT_TLVLEN 7344 (wmi_request_stats_cmd_fixed_param)); 7345 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7346 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7347 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7348 WMI_REQUEST_STATS_CMDID)) { 7349 wmi_err("Failed to send host stats request to fw"); 7350 wmi_buf_free(buf); 7351 return QDF_STATUS_E_FAILURE; 7352 } 7353 7354 return QDF_STATUS_SUCCESS; 7355 } 7356 7357 /** 7358 * send_snr_cmd_tlv() - get RSSI from fw 7359 * @wmi_handle: wmi handle 7360 * @vdev_id: vdev id 7361 * 7362 * Return: QDF status 7363 */ 7364 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7365 { 7366 wmi_buf_t buf; 7367 wmi_request_stats_cmd_fixed_param *cmd; 7368 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7369 7370 buf = wmi_buf_alloc(wmi_handle, len); 7371 if (!buf) 7372 return QDF_STATUS_E_FAILURE; 7373 7374 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7375 cmd->vdev_id = vdev_id; 7376 7377 WMITLV_SET_HDR(&cmd->tlv_header, 7378 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7379 WMITLV_GET_STRUCT_TLVLEN 7380 (wmi_request_stats_cmd_fixed_param)); 7381 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7382 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7383 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7384 WMI_REQUEST_STATS_CMDID)) { 7385 wmi_err("Failed to send host stats request to fw"); 7386 wmi_buf_free(buf); 7387 return QDF_STATUS_E_FAILURE; 7388 } 7389 7390 return QDF_STATUS_SUCCESS; 7391 } 7392 7393 /** 7394 * send_link_status_req_cmd_tlv() - process link status request from UMAC 7395 * @wmi_handle: wmi handle 7396 * @link_status: get link params 7397 * 7398 * Return: QDF status 7399 */ 7400 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 7401 struct link_status_params *link_status) 7402 { 7403 wmi_buf_t buf; 7404 wmi_request_stats_cmd_fixed_param *cmd; 7405 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7406 7407 buf = wmi_buf_alloc(wmi_handle, len); 7408 if (!buf) 7409 return QDF_STATUS_E_FAILURE; 7410 7411 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7412 WMITLV_SET_HDR(&cmd->tlv_header, 7413 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7414 WMITLV_GET_STRUCT_TLVLEN 7415 (wmi_request_stats_cmd_fixed_param)); 7416 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 7417 cmd->vdev_id = link_status->vdev_id; 7418 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7419 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7420 WMI_REQUEST_STATS_CMDID)) { 7421 wmi_err("Failed to send WMI link status request to fw"); 7422 wmi_buf_free(buf); 7423 return QDF_STATUS_E_FAILURE; 7424 } 7425 7426 return QDF_STATUS_SUCCESS; 7427 } 7428 7429 #ifdef WLAN_SUPPORT_GREEN_AP 7430 /** 7431 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 7432 * @wmi_handle: wmi handler 7433 * @egap_params: pointer to egap_params 7434 * 7435 * Return: 0 for success, otherwise appropriate error code 7436 */ 7437 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7438 struct wlan_green_ap_egap_params *egap_params) 7439 { 7440 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7441 wmi_buf_t buf; 7442 int32_t err; 7443 7444 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7445 if (!buf) 7446 return QDF_STATUS_E_NOMEM; 7447 7448 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7449 WMITLV_SET_HDR(&cmd->tlv_header, 7450 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7451 WMITLV_GET_STRUCT_TLVLEN( 7452 wmi_ap_ps_egap_param_cmd_fixed_param)); 7453 7454 cmd->enable = egap_params->host_enable_egap; 7455 cmd->inactivity_time = egap_params->egap_inactivity_time; 7456 cmd->wait_time = egap_params->egap_wait_time; 7457 cmd->flags = egap_params->egap_feature_flags; 7458 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7459 err = wmi_unified_cmd_send(wmi_handle, buf, 7460 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7461 if (err) { 7462 wmi_err("Failed to send ap_ps_egap cmd"); 7463 wmi_buf_free(buf); 7464 return QDF_STATUS_E_FAILURE; 7465 } 7466 7467 return QDF_STATUS_SUCCESS; 7468 } 7469 #endif 7470 7471 /** 7472 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7473 * @wmi_handle: wmi handle 7474 * @vdev_id: vdev id 7475 * 7476 * Return: QDF_STATUS_SUCCESS for success or error code 7477 */ 7478 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7479 uint8_t vdev_id) 7480 { 7481 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7482 wmi_buf_t buf; 7483 int32_t len = sizeof(*cmd); 7484 7485 wmi_debug("vdev_id %d", vdev_id); 7486 buf = wmi_buf_alloc(wmi_handle, len); 7487 if (!buf) 7488 return QDF_STATUS_E_NOMEM; 7489 7490 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7491 WMITLV_SET_HDR(&cmd->tlv_header, 7492 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7493 WMITLV_GET_STRUCT_TLVLEN 7494 (wmi_csa_offload_enable_cmd_fixed_param)); 7495 cmd->vdev_id = vdev_id; 7496 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7497 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7498 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7499 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7500 wmi_err("Failed to send CSA offload enable command"); 7501 wmi_buf_free(buf); 7502 return QDF_STATUS_E_FAILURE; 7503 } 7504 7505 return 0; 7506 } 7507 7508 #ifdef WLAN_FEATURE_CIF_CFR 7509 /** 7510 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7511 * @wmi_handle: wmi handle 7512 * @cfg: dma cfg req 7513 * 7514 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7515 */ 7516 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7517 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7518 { 7519 wmi_buf_t buf; 7520 uint8_t *cmd; 7521 QDF_STATUS ret; 7522 7523 WMITLV_SET_HDR(cfg, 7524 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7525 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7526 7527 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7528 if (!buf) 7529 return QDF_STATUS_E_FAILURE; 7530 7531 cmd = (uint8_t *) wmi_buf_data(buf); 7532 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7533 wmi_debug("Sending OEM Data Request to target, data len %lu", 7534 sizeof(*cfg)); 7535 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7536 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7537 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7538 if (QDF_IS_STATUS_ERROR(ret)) { 7539 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7540 wmi_buf_free(buf); 7541 } 7542 7543 return ret; 7544 } 7545 #endif 7546 7547 /** 7548 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7549 * @wmi_handle: wmi handle 7550 * @start_11d_scan: 11d scan start request parameters 7551 * 7552 * This function request FW to start 11d scan. 7553 * 7554 * Return: QDF status 7555 */ 7556 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7557 struct reg_start_11d_scan_req *start_11d_scan) 7558 { 7559 wmi_11d_scan_start_cmd_fixed_param *cmd; 7560 int32_t len; 7561 wmi_buf_t buf; 7562 int ret; 7563 7564 len = sizeof(*cmd); 7565 buf = wmi_buf_alloc(wmi_handle, len); 7566 if (!buf) 7567 return QDF_STATUS_E_NOMEM; 7568 7569 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7570 7571 WMITLV_SET_HDR(&cmd->tlv_header, 7572 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7573 WMITLV_GET_STRUCT_TLVLEN 7574 (wmi_11d_scan_start_cmd_fixed_param)); 7575 7576 cmd->vdev_id = start_11d_scan->vdev_id; 7577 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7578 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7579 7580 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7581 7582 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7583 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7584 WMI_11D_SCAN_START_CMDID); 7585 if (ret) { 7586 wmi_err("Failed to send start 11d scan wmi cmd"); 7587 wmi_buf_free(buf); 7588 return QDF_STATUS_E_FAILURE; 7589 } 7590 7591 return QDF_STATUS_SUCCESS; 7592 } 7593 7594 /** 7595 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7596 * @wmi_handle: wmi handle 7597 * @stop_11d_scan: 11d scan stop request parameters 7598 * 7599 * This function request FW to stop 11d scan. 7600 * 7601 * Return: QDF status 7602 */ 7603 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7604 struct reg_stop_11d_scan_req *stop_11d_scan) 7605 { 7606 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7607 int32_t len; 7608 wmi_buf_t buf; 7609 int ret; 7610 7611 len = sizeof(*cmd); 7612 buf = wmi_buf_alloc(wmi_handle, len); 7613 if (!buf) 7614 return QDF_STATUS_E_NOMEM; 7615 7616 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7617 7618 WMITLV_SET_HDR(&cmd->tlv_header, 7619 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7620 WMITLV_GET_STRUCT_TLVLEN 7621 (wmi_11d_scan_stop_cmd_fixed_param)); 7622 7623 cmd->vdev_id = stop_11d_scan->vdev_id; 7624 7625 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7626 7627 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7628 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7629 WMI_11D_SCAN_STOP_CMDID); 7630 if (ret) { 7631 wmi_err("Failed to send stop 11d scan wmi cmd"); 7632 wmi_buf_free(buf); 7633 return QDF_STATUS_E_FAILURE; 7634 } 7635 7636 return QDF_STATUS_SUCCESS; 7637 } 7638 7639 /** 7640 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7641 * @wmi_handle: wmi handle 7642 * @data_len: the length of @data 7643 * @data: the pointer to data buf 7644 * 7645 * Return: QDF status 7646 */ 7647 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7648 uint32_t data_len, 7649 uint8_t *data) 7650 { 7651 wmi_buf_t buf; 7652 uint8_t *cmd; 7653 QDF_STATUS ret; 7654 7655 buf = wmi_buf_alloc(wmi_handle, 7656 (data_len + WMI_TLV_HDR_SIZE)); 7657 if (!buf) 7658 return QDF_STATUS_E_FAILURE; 7659 7660 cmd = (uint8_t *) wmi_buf_data(buf); 7661 7662 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7663 cmd += WMI_TLV_HDR_SIZE; 7664 qdf_mem_copy(cmd, data, 7665 data_len); 7666 7667 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7668 7669 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7670 ret = wmi_unified_cmd_send(wmi_handle, buf, 7671 (data_len + 7672 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7673 7674 if (QDF_IS_STATUS_ERROR(ret)) { 7675 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7676 wmi_buf_free(buf); 7677 } 7678 7679 return ret; 7680 } 7681 7682 #ifdef FEATURE_OEM_DATA 7683 /** 7684 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7685 * @wmi_handle: wmi handle 7686 * @oem_data: the pointer to oem data 7687 * 7688 * Return: QDF status 7689 */ 7690 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7691 struct oem_data *oem_data) 7692 { 7693 QDF_STATUS ret; 7694 wmi_oem_data_cmd_fixed_param *cmd; 7695 struct wmi_ops *ops; 7696 wmi_buf_t buf; 7697 uint16_t len = sizeof(*cmd); 7698 uint16_t oem_data_len_aligned; 7699 uint8_t *buf_ptr; 7700 uint32_t pdev_id; 7701 7702 if (!oem_data || !oem_data->data) { 7703 wmi_err_rl("oem data is not valid"); 7704 return QDF_STATUS_E_FAILURE; 7705 } 7706 7707 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7708 if (oem_data_len_aligned < oem_data->data_len) { 7709 wmi_err_rl("integer overflow while rounding up data_len"); 7710 return QDF_STATUS_E_FAILURE; 7711 } 7712 7713 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7714 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7715 return QDF_STATUS_E_FAILURE; 7716 } 7717 7718 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7719 buf = wmi_buf_alloc(wmi_handle, len); 7720 if (!buf) 7721 return QDF_STATUS_E_NOMEM; 7722 7723 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7724 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7725 WMITLV_SET_HDR(&cmd->tlv_header, 7726 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7727 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7728 7729 pdev_id = oem_data->pdev_id; 7730 if (oem_data->pdev_vdev_flag) { 7731 ops = wmi_handle->ops; 7732 if (oem_data->is_host_pdev_id) 7733 pdev_id = 7734 ops->convert_host_pdev_id_to_target(wmi_handle, 7735 pdev_id); 7736 else 7737 pdev_id = 7738 ops->convert_pdev_id_host_to_target(wmi_handle, 7739 pdev_id); 7740 } 7741 7742 cmd->vdev_id = oem_data->vdev_id; 7743 cmd->data_len = oem_data->data_len; 7744 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7745 cmd->pdev_id = pdev_id; 7746 7747 buf_ptr += sizeof(*cmd); 7748 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7749 buf_ptr += WMI_TLV_HDR_SIZE; 7750 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7751 7752 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7753 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7754 if (QDF_IS_STATUS_ERROR(ret)) { 7755 wmi_err_rl("Failed with ret = %d", ret); 7756 wmi_buf_free(buf); 7757 } 7758 7759 return ret; 7760 } 7761 #endif 7762 7763 /** 7764 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7765 * @wmi_handle: wmi handle 7766 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7767 * 7768 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7769 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7770 * to firmware based on phyerr filtering 7771 * offload status. 7772 * 7773 * Return: 1 success, 0 failure 7774 */ 7775 static QDF_STATUS 7776 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7777 bool dfs_phyerr_filter_offload) 7778 { 7779 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7780 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7781 wmi_buf_t buf; 7782 uint16_t len; 7783 QDF_STATUS ret; 7784 7785 7786 if (false == dfs_phyerr_filter_offload) { 7787 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7788 len = sizeof(*disable_phyerr_offload_cmd); 7789 buf = wmi_buf_alloc(wmi_handle, len); 7790 if (!buf) 7791 return 0; 7792 7793 disable_phyerr_offload_cmd = 7794 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7795 wmi_buf_data(buf); 7796 7797 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7798 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7799 WMITLV_GET_STRUCT_TLVLEN 7800 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7801 7802 /* 7803 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7804 * to the firmware to disable the phyerror 7805 * filtering offload. 7806 */ 7807 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7808 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7809 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7810 if (QDF_IS_STATUS_ERROR(ret)) { 7811 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7812 ret); 7813 wmi_buf_free(buf); 7814 return QDF_STATUS_E_FAILURE; 7815 } 7816 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7817 } else { 7818 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7819 7820 len = sizeof(*enable_phyerr_offload_cmd); 7821 buf = wmi_buf_alloc(wmi_handle, len); 7822 if (!buf) 7823 return QDF_STATUS_E_FAILURE; 7824 7825 enable_phyerr_offload_cmd = 7826 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7827 wmi_buf_data(buf); 7828 7829 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7830 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7831 WMITLV_GET_STRUCT_TLVLEN 7832 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7833 7834 /* 7835 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7836 * to the firmware to enable the phyerror 7837 * filtering offload. 7838 */ 7839 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7840 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7841 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7842 7843 if (QDF_IS_STATUS_ERROR(ret)) { 7844 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7845 wmi_buf_free(buf); 7846 return QDF_STATUS_E_FAILURE; 7847 } 7848 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7849 } 7850 7851 return QDF_STATUS_SUCCESS; 7852 } 7853 7854 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7855 /** 7856 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7857 * @wmi_handle: wmi handle 7858 * @pktlog_event: pktlog event 7859 * @cmd_id: pktlog cmd id 7860 * @user_triggered: user triggered input for PKTLOG enable mode 7861 * 7862 * Return: QDF status 7863 */ 7864 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7865 WMI_PKTLOG_EVENT pktlog_event, 7866 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7867 { 7868 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7869 WMI_CMD_ID CMD_ID; 7870 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7871 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7872 int len = 0; 7873 wmi_buf_t buf; 7874 int32_t idx, max_idx; 7875 7876 PKTLOG_EVENT = pktlog_event; 7877 CMD_ID = cmd_id; 7878 7879 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7880 switch (CMD_ID) { 7881 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7882 len = sizeof(*cmd); 7883 buf = wmi_buf_alloc(wmi_handle, len); 7884 if (!buf) 7885 return QDF_STATUS_E_NOMEM; 7886 7887 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7888 wmi_buf_data(buf); 7889 WMITLV_SET_HDR(&cmd->tlv_header, 7890 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7891 WMITLV_GET_STRUCT_TLVLEN 7892 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7893 cmd->evlist = 0; 7894 for (idx = 0; idx < max_idx; idx++) { 7895 if (PKTLOG_EVENT & (1 << idx)) 7896 cmd->evlist |= pktlog_event_tlv[idx]; 7897 } 7898 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7899 : WMI_PKTLOG_ENABLE_AUTO; 7900 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7901 wmi_handle, 7902 WMI_HOST_PDEV_ID_SOC); 7903 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7904 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7905 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7906 wmi_err("Failed to send pktlog enable cmdid"); 7907 goto wmi_send_failed; 7908 } 7909 break; 7910 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7911 len = sizeof(*disable_cmd); 7912 buf = wmi_buf_alloc(wmi_handle, len); 7913 if (!buf) 7914 return QDF_STATUS_E_NOMEM; 7915 7916 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7917 wmi_buf_data(buf); 7918 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7919 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7920 WMITLV_GET_STRUCT_TLVLEN 7921 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7922 disable_cmd->pdev_id = 7923 wmi_handle->ops->convert_pdev_id_host_to_target( 7924 wmi_handle, 7925 WMI_HOST_PDEV_ID_SOC); 7926 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7927 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7928 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7929 wmi_err("failed to send pktlog disable cmdid"); 7930 goto wmi_send_failed; 7931 } 7932 break; 7933 default: 7934 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7935 break; 7936 } 7937 7938 return QDF_STATUS_SUCCESS; 7939 7940 wmi_send_failed: 7941 wmi_buf_free(buf); 7942 return QDF_STATUS_E_FAILURE; 7943 } 7944 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7945 7946 /** 7947 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7948 * @wmi_handle: wmi handle 7949 * @preq: stats ext params 7950 * 7951 * Return: QDF status 7952 */ 7953 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7954 struct stats_ext_params *preq) 7955 { 7956 QDF_STATUS ret; 7957 wmi_req_stats_ext_cmd_fixed_param *cmd; 7958 wmi_buf_t buf; 7959 size_t len; 7960 uint8_t *buf_ptr; 7961 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7962 uint32_t *vdev_bitmap; 7963 7964 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7965 sizeof(*cmd))) { 7966 wmi_err("Data length=%d is greater than max wmi msg size", 7967 preq->request_data_len); 7968 return QDF_STATUS_E_FAILURE; 7969 } 7970 7971 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7972 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7973 7974 buf = wmi_buf_alloc(wmi_handle, len); 7975 if (!buf) 7976 return QDF_STATUS_E_NOMEM; 7977 7978 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7979 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7980 7981 WMITLV_SET_HDR(&cmd->tlv_header, 7982 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7983 WMITLV_GET_STRUCT_TLVLEN 7984 (wmi_req_stats_ext_cmd_fixed_param)); 7985 cmd->vdev_id = preq->vdev_id; 7986 cmd->data_len = preq->request_data_len; 7987 7988 wmi_debug("The data len value is %u and vdev id set is %u", 7989 preq->request_data_len, preq->vdev_id); 7990 7991 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7992 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7993 7994 buf_ptr += WMI_TLV_HDR_SIZE; 7995 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7996 7997 buf_ptr += cmd->data_len; 7998 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 7999 8000 buf_ptr += WMI_TLV_HDR_SIZE; 8001 8002 vdev_bitmap = (A_UINT32 *)buf_ptr; 8003 8004 vdev_bitmap[0] = preq->vdev_id_bitmap; 8005 8006 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 8007 8008 buf_ptr += sizeof(uint32_t); 8009 8010 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 8011 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8012 WMI_REQUEST_STATS_EXT_CMDID); 8013 if (QDF_IS_STATUS_ERROR(ret)) { 8014 wmi_err("Failed to send notify cmd ret = %d", ret); 8015 wmi_buf_free(buf); 8016 } 8017 8018 return ret; 8019 } 8020 8021 /** 8022 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 8023 * @wmi_handle: wmi handle 8024 * @params: DHCP server offload info 8025 * 8026 * Return: QDF_STATUS_SUCCESS for success or error code 8027 */ 8028 static QDF_STATUS 8029 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 8030 struct dhcp_offload_info_params *params) 8031 { 8032 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 8033 wmi_buf_t buf; 8034 QDF_STATUS status; 8035 8036 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8037 if (!buf) 8038 return QDF_STATUS_E_NOMEM; 8039 8040 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 8041 8042 WMITLV_SET_HDR(&cmd->tlv_header, 8043 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 8044 WMITLV_GET_STRUCT_TLVLEN 8045 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 8046 cmd->vdev_id = params->vdev_id; 8047 cmd->enable = params->dhcp_offload_enabled; 8048 cmd->num_client = params->dhcp_client_num; 8049 cmd->srv_ipv4 = params->dhcp_srv_addr; 8050 cmd->start_lsb = 0; 8051 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 8052 status = wmi_unified_cmd_send(wmi_handle, buf, 8053 sizeof(*cmd), 8054 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 8055 if (QDF_IS_STATUS_ERROR(status)) { 8056 wmi_err("Failed to send set_dhcp_server_offload cmd"); 8057 wmi_buf_free(buf); 8058 return QDF_STATUS_E_FAILURE; 8059 } 8060 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 8061 8062 return status; 8063 } 8064 8065 /** 8066 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 8067 * @wmi_handle: wmi handle 8068 * @param: pointer to pdev regdomain params 8069 * 8070 * Return: QDF_STATUS_SUCCESS for success or error code 8071 */ 8072 static QDF_STATUS 8073 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 8074 struct pdev_set_regdomain_params *param) 8075 { 8076 wmi_buf_t buf; 8077 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 8078 int32_t len = sizeof(*cmd); 8079 8080 buf = wmi_buf_alloc(wmi_handle, len); 8081 if (!buf) 8082 return QDF_STATUS_E_NOMEM; 8083 8084 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8085 WMITLV_SET_HDR(&cmd->tlv_header, 8086 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8087 WMITLV_GET_STRUCT_TLVLEN 8088 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8089 8090 cmd->reg_domain = param->currentRDinuse; 8091 cmd->reg_domain_2G = param->currentRD2G; 8092 cmd->reg_domain_5G = param->currentRD5G; 8093 cmd->conformance_test_limit_2G = param->ctl_2G; 8094 cmd->conformance_test_limit_5G = param->ctl_5G; 8095 cmd->dfs_domain = param->dfsDomain; 8096 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8097 wmi_handle, 8098 param->pdev_id); 8099 8100 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8101 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8102 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8103 wmi_err("Failed to send pdev set regdomain command"); 8104 wmi_buf_free(buf); 8105 return QDF_STATUS_E_FAILURE; 8106 } 8107 8108 return QDF_STATUS_SUCCESS; 8109 } 8110 8111 /** 8112 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 8113 * @wmi_handle: wmi handle 8114 * @reg_dmn: reg domain 8115 * @regdmn2G: 2G reg domain 8116 * @regdmn5G: 5G reg domain 8117 * @ctl2G: 2G test limit 8118 * @ctl5G: 5G test limit 8119 * 8120 * Return: none 8121 */ 8122 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 8123 uint32_t reg_dmn, uint16_t regdmn2G, 8124 uint16_t regdmn5G, uint8_t ctl2G, 8125 uint8_t ctl5G) 8126 { 8127 wmi_buf_t buf; 8128 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 8129 int32_t len = sizeof(*cmd); 8130 8131 8132 buf = wmi_buf_alloc(wmi_handle, len); 8133 if (!buf) 8134 return QDF_STATUS_E_NOMEM; 8135 8136 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8137 WMITLV_SET_HDR(&cmd->tlv_header, 8138 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8139 WMITLV_GET_STRUCT_TLVLEN 8140 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8141 cmd->reg_domain = reg_dmn; 8142 cmd->reg_domain_2G = regdmn2G; 8143 cmd->reg_domain_5G = regdmn5G; 8144 cmd->conformance_test_limit_2G = ctl2G; 8145 cmd->conformance_test_limit_5G = ctl5G; 8146 8147 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 8148 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 8149 cmd->conformance_test_limit_2G, 8150 cmd->conformance_test_limit_5G); 8151 8152 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8153 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8154 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8155 wmi_err("Failed to send pdev set regdomain command"); 8156 wmi_buf_free(buf); 8157 return QDF_STATUS_E_FAILURE; 8158 } 8159 8160 return QDF_STATUS_SUCCESS; 8161 } 8162 8163 /** 8164 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 8165 * @param: param sent from the host side 8166 * @cmd: param to be sent to the fw side 8167 */ 8168 static inline void copy_custom_aggr_bitmap( 8169 struct set_custom_aggr_size_params *param, 8170 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 8171 { 8172 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 8173 param->ac); 8174 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 8175 param->aggr_type); 8176 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8177 param->tx_aggr_size_disable); 8178 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8179 param->rx_aggr_size_disable); 8180 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 8181 param->tx_ac_enable); 8182 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 8183 param->aggr_ba_enable); 8184 } 8185 8186 /** 8187 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 8188 * @wmi_handle: wmi handle 8189 * @param: pointer to hold custom aggr size params 8190 * 8191 * Return: QDF_STATUS_SUCCESS for success or error code 8192 */ 8193 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 8194 wmi_unified_t wmi_handle, 8195 struct set_custom_aggr_size_params *param) 8196 { 8197 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 8198 wmi_buf_t buf; 8199 int32_t len = sizeof(*cmd); 8200 8201 buf = wmi_buf_alloc(wmi_handle, len); 8202 if (!buf) 8203 return QDF_STATUS_E_FAILURE; 8204 8205 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 8206 wmi_buf_data(buf); 8207 WMITLV_SET_HDR(&cmd->tlv_header, 8208 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 8209 WMITLV_GET_STRUCT_TLVLEN( 8210 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 8211 cmd->vdev_id = param->vdev_id; 8212 cmd->tx_aggr_size = param->tx_aggr_size; 8213 cmd->rx_aggr_size = param->rx_aggr_size; 8214 copy_custom_aggr_bitmap(param, cmd); 8215 8216 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 8217 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 8218 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 8219 "tx_ac_enable=0x%X", 8220 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 8221 param->ac, param->aggr_type, param->tx_aggr_size_disable, 8222 param->rx_aggr_size_disable, param->tx_ac_enable); 8223 8224 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 8225 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8226 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 8227 wmi_err("Setting custom aggregation size failed"); 8228 wmi_buf_free(buf); 8229 return QDF_STATUS_E_FAILURE; 8230 } 8231 8232 return QDF_STATUS_SUCCESS; 8233 } 8234 8235 /** 8236 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 8237 * @wmi_handle: handle to WMI. 8238 * @param: pointer to tx antenna param 8239 * 8240 * Return: QDF_STATUS_SUCCESS for success or error code 8241 */ 8242 8243 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 8244 struct set_qdepth_thresh_params *param) 8245 { 8246 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 8247 wmi_msduq_qdepth_thresh_update *cmd_update; 8248 wmi_buf_t buf; 8249 int32_t len = 0; 8250 int i; 8251 uint8_t *buf_ptr; 8252 QDF_STATUS ret; 8253 8254 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 8255 wmi_err("Invalid Update Count!"); 8256 return QDF_STATUS_E_INVAL; 8257 } 8258 8259 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8260 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 8261 param->num_of_msduq_updates); 8262 buf = wmi_buf_alloc(wmi_handle, len); 8263 8264 if (!buf) 8265 return QDF_STATUS_E_NOMEM; 8266 8267 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8268 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 8269 buf_ptr; 8270 8271 WMITLV_SET_HDR(&cmd->tlv_header, 8272 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 8273 , WMITLV_GET_STRUCT_TLVLEN( 8274 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 8275 8276 cmd->pdev_id = 8277 wmi_handle->ops->convert_pdev_id_host_to_target( 8278 wmi_handle, 8279 param->pdev_id); 8280 cmd->vdev_id = param->vdev_id; 8281 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 8282 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 8283 8284 buf_ptr += sizeof( 8285 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 8286 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8287 param->num_of_msduq_updates * 8288 sizeof(wmi_msduq_qdepth_thresh_update)); 8289 buf_ptr += WMI_TLV_HDR_SIZE; 8290 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 8291 8292 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 8293 WMITLV_SET_HDR(&cmd_update->tlv_header, 8294 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 8295 WMITLV_GET_STRUCT_TLVLEN( 8296 wmi_msduq_qdepth_thresh_update)); 8297 cmd_update->tid_num = param->update_params[i].tid_num; 8298 cmd_update->msduq_update_mask = 8299 param->update_params[i].msduq_update_mask; 8300 cmd_update->qdepth_thresh_value = 8301 param->update_params[i].qdepth_thresh_value; 8302 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 8303 "mac_addr_upper4=%X, mac_addr_lower2:%X," 8304 " update mask=0x%X thresh val=0x%X", 8305 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 8306 cmd->peer_mac_address.mac_addr31to0, 8307 cmd->peer_mac_address.mac_addr47to32, 8308 cmd_update->msduq_update_mask, 8309 cmd_update->qdepth_thresh_value); 8310 cmd_update++; 8311 } 8312 8313 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 8314 cmd->vdev_id, 0); 8315 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8316 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 8317 8318 if (ret != 0) { 8319 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 8320 wmi_buf_free(buf); 8321 } 8322 8323 return ret; 8324 } 8325 8326 /** 8327 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 8328 * @wmi_handle: wmi handle 8329 * @param: pointer to hold vap dscp tid map param 8330 * 8331 * Return: QDF_STATUS_SUCCESS for success or error code 8332 */ 8333 static QDF_STATUS 8334 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 8335 struct vap_dscp_tid_map_params *param) 8336 { 8337 wmi_buf_t buf; 8338 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 8339 int32_t len = sizeof(*cmd); 8340 8341 buf = wmi_buf_alloc(wmi_handle, len); 8342 if (!buf) 8343 return QDF_STATUS_E_FAILURE; 8344 8345 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 8346 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 8347 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 8348 8349 cmd->vdev_id = param->vdev_id; 8350 cmd->enable_override = 0; 8351 8352 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 8353 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 8354 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8355 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 8356 wmi_err("Failed to set dscp cmd"); 8357 wmi_buf_free(buf); 8358 return QDF_STATUS_E_FAILURE; 8359 } 8360 8361 return QDF_STATUS_SUCCESS; 8362 } 8363 8364 /** 8365 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 8366 * @wmi_handle: wmi handle 8367 * @param: pointer to hold fwtest param 8368 * 8369 * Return: QDF_STATUS_SUCCESS for success or error code 8370 */ 8371 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 8372 struct set_fwtest_params *param) 8373 { 8374 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8375 wmi_buf_t buf; 8376 int32_t len = sizeof(*cmd); 8377 8378 buf = wmi_buf_alloc(wmi_handle, len); 8379 8380 if (!buf) 8381 return QDF_STATUS_E_FAILURE; 8382 8383 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 8384 WMITLV_SET_HDR(&cmd->tlv_header, 8385 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8386 WMITLV_GET_STRUCT_TLVLEN( 8387 wmi_fwtest_set_param_cmd_fixed_param)); 8388 cmd->param_id = param->arg; 8389 cmd->param_value = param->value; 8390 8391 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8392 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 8393 wmi_err("Setting FW test param failed"); 8394 wmi_buf_free(buf); 8395 return QDF_STATUS_E_FAILURE; 8396 } 8397 8398 return QDF_STATUS_SUCCESS; 8399 } 8400 8401 /** 8402 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 8403 * @wmi_handle: handle to WMI. 8404 * 8405 * Return: QDF_STATUS_SUCCESS for success or error code 8406 */ 8407 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 8408 { 8409 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 8410 wmi_buf_t buf; 8411 QDF_STATUS ret; 8412 int32_t len; 8413 8414 len = sizeof(*cmd); 8415 8416 buf = wmi_buf_alloc(wmi_handle, len); 8417 if (!buf) 8418 return QDF_STATUS_E_FAILURE; 8419 8420 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 8421 WMITLV_SET_HDR(&cmd->tlv_header, 8422 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 8423 WMITLV_GET_STRUCT_TLVLEN( 8424 wmi_pdev_dfs_disable_cmd_fixed_param)); 8425 /* Filling it with WMI_PDEV_ID_SOC for now */ 8426 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8427 wmi_handle, 8428 WMI_HOST_PDEV_ID_SOC); 8429 8430 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 8431 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8432 WMI_PDEV_DFS_DISABLE_CMDID); 8433 8434 if (ret != 0) { 8435 wmi_err("Sending PDEV DFS disable cmd failed"); 8436 wmi_buf_free(buf); 8437 } 8438 8439 return ret; 8440 } 8441 8442 /** 8443 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8444 * @wmi_handle: handle to WMI. 8445 * 8446 * Return: QDF_STATUS_SUCCESS for success or error code 8447 */ 8448 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8449 { 8450 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8451 wmi_buf_t buf; 8452 QDF_STATUS ret; 8453 int32_t len; 8454 8455 len = sizeof(*cmd); 8456 8457 buf = wmi_buf_alloc(wmi_handle, len); 8458 if (!buf) 8459 return QDF_STATUS_E_FAILURE; 8460 8461 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8462 WMITLV_SET_HDR(&cmd->tlv_header, 8463 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8464 WMITLV_GET_STRUCT_TLVLEN( 8465 wmi_pdev_dfs_enable_cmd_fixed_param)); 8466 /* Reserved for future use */ 8467 cmd->reserved0 = 0; 8468 8469 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8470 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8471 WMI_PDEV_DFS_ENABLE_CMDID); 8472 8473 if (ret != 0) { 8474 wmi_err("Sending PDEV DFS enable cmd failed"); 8475 wmi_buf_free(buf); 8476 } 8477 8478 return ret; 8479 } 8480 8481 /** 8482 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8483 * to fw 8484 * @wmi_handle: wmi handle 8485 * @param: pointer to hold periodic chan stats param 8486 * 8487 * Return: QDF_STATUS_SUCCESS for success or error code 8488 */ 8489 static QDF_STATUS 8490 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8491 struct periodic_chan_stats_params *param) 8492 { 8493 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8494 wmi_buf_t buf; 8495 QDF_STATUS ret; 8496 int32_t len; 8497 8498 len = sizeof(*cmd); 8499 8500 buf = wmi_buf_alloc(wmi_handle, len); 8501 if (!buf) 8502 return QDF_STATUS_E_FAILURE; 8503 8504 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8505 wmi_buf_data(buf); 8506 WMITLV_SET_HDR(&cmd->tlv_header, 8507 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8508 WMITLV_GET_STRUCT_TLVLEN( 8509 wmi_set_periodic_channel_stats_config_fixed_param)); 8510 cmd->enable = param->enable; 8511 cmd->stats_period = param->stats_period; 8512 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8513 wmi_handle, 8514 param->pdev_id); 8515 8516 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8517 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8518 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8519 8520 if (ret != 0) { 8521 wmi_err("Sending periodic chan stats config failed"); 8522 wmi_buf_free(buf); 8523 } 8524 8525 return ret; 8526 } 8527 8528 #ifdef WLAN_IOT_SIM_SUPPORT 8529 /** 8530 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8531 * 8532 * @wmi_handle: wmi handle 8533 * @param: pointer to hold simulation test parameter 8534 * 8535 * Return: QDF_STATUS_SUCCESS for success or error code 8536 */ 8537 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8538 struct simulation_test_params 8539 *param) 8540 { 8541 wmi_simulation_test_cmd_fixed_param *cmd; 8542 u32 wmi_buf_len; 8543 wmi_buf_t buf; 8544 u8 *buf_ptr; 8545 u32 aligned_len = 0; 8546 8547 wmi_buf_len = sizeof(*cmd); 8548 if (param->buf_len) { 8549 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8550 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8551 } 8552 8553 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8554 if (!buf) { 8555 wmi_err("wmi_buf_alloc failed"); 8556 return QDF_STATUS_E_NOMEM; 8557 } 8558 8559 buf_ptr = wmi_buf_data(buf); 8560 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8561 WMITLV_SET_HDR(&cmd->tlv_header, 8562 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8563 WMITLV_GET_STRUCT_TLVLEN( 8564 wmi_simulation_test_cmd_fixed_param)); 8565 cmd->pdev_id = param->pdev_id; 8566 cmd->vdev_id = param->vdev_id; 8567 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8568 cmd->test_cmd_type = param->test_cmd_type; 8569 cmd->test_subcmd_type = param->test_subcmd_type; 8570 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8571 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8572 param->frame_subtype); 8573 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8574 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8575 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8576 cmd->buf_len = param->buf_len; 8577 8578 if (param->buf_len) { 8579 buf_ptr += sizeof(*cmd); 8580 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8581 buf_ptr += WMI_TLV_HDR_SIZE; 8582 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8583 } 8584 8585 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8586 WMI_SIMULATION_TEST_CMDID)) { 8587 wmi_err("Failed to send test simulation cmd"); 8588 wmi_buf_free(buf); 8589 return QDF_STATUS_E_FAILURE; 8590 } 8591 8592 return QDF_STATUS_SUCCESS; 8593 } 8594 #endif 8595 8596 #ifdef WLAN_FEATURE_11BE 8597 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8598 #else 8599 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8600 #endif 8601 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8602 { 8603 switch (wmi_width) { 8604 case WMI_CHAN_WIDTH_20: 8605 return CH_WIDTH_20MHZ; 8606 case WMI_CHAN_WIDTH_40: 8607 return CH_WIDTH_40MHZ; 8608 case WMI_CHAN_WIDTH_80: 8609 return CH_WIDTH_80MHZ; 8610 case WMI_CHAN_WIDTH_160: 8611 return CH_WIDTH_160MHZ; 8612 case WMI_CHAN_WIDTH_80P80: 8613 return CH_WIDTH_80P80MHZ; 8614 case WMI_CHAN_WIDTH_5: 8615 return CH_WIDTH_5MHZ; 8616 case WMI_CHAN_WIDTH_10: 8617 return CH_WIDTH_10MHZ; 8618 case WMI_CHAN_WIDTH_320: 8619 return WLAN_PHY_CH_WIDTH_320MHZ; 8620 default: 8621 return CH_WIDTH_INVALID; 8622 } 8623 } 8624 8625 #ifdef WLAN_FEATURE_11BE 8626 /** 8627 * wmi_host_to_fw_phymode_11be() - convert host to fw phymode for 11be phymode 8628 * @host_phymode: phymode to convert 8629 * 8630 * Return: one of the 11be values defined in enum WMI_HOST_WLAN_PHY_MODE; 8631 * or WMI_HOST_MODE_UNKNOWN if the input is not an 11be phymode 8632 */ 8633 static WMI_HOST_WLAN_PHY_MODE 8634 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8635 { 8636 switch (host_phymode) { 8637 case WLAN_PHYMODE_11BEA_EHT20: 8638 return WMI_HOST_MODE_11BE_EHT20; 8639 case WLAN_PHYMODE_11BEA_EHT40: 8640 return WMI_HOST_MODE_11BE_EHT40; 8641 case WLAN_PHYMODE_11BEA_EHT80: 8642 return WMI_HOST_MODE_11BE_EHT80; 8643 case WLAN_PHYMODE_11BEA_EHT160: 8644 return WMI_HOST_MODE_11BE_EHT160; 8645 case WLAN_PHYMODE_11BEA_EHT320: 8646 return WMI_HOST_MODE_11BE_EHT320; 8647 case WLAN_PHYMODE_11BEG_EHT20: 8648 return WMI_HOST_MODE_11BE_EHT20_2G; 8649 case WLAN_PHYMODE_11BEG_EHT40: 8650 case WLAN_PHYMODE_11BEG_EHT40PLUS: 8651 case WLAN_PHYMODE_11BEG_EHT40MINUS: 8652 return WMI_HOST_MODE_11BE_EHT40_2G; 8653 default: 8654 return WMI_HOST_MODE_UNKNOWN; 8655 } 8656 } 8657 #else 8658 static WMI_HOST_WLAN_PHY_MODE 8659 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8660 { 8661 return WMI_HOST_MODE_UNKNOWN; 8662 } 8663 #endif 8664 8665 WMI_HOST_WLAN_PHY_MODE wmi_host_to_fw_phymode(enum wlan_phymode host_phymode) 8666 { 8667 switch (host_phymode) { 8668 case WLAN_PHYMODE_11A: 8669 return WMI_HOST_MODE_11A; 8670 case WLAN_PHYMODE_11G: 8671 return WMI_HOST_MODE_11G; 8672 case WLAN_PHYMODE_11B: 8673 return WMI_HOST_MODE_11B; 8674 case WLAN_PHYMODE_11G_ONLY: 8675 return WMI_HOST_MODE_11GONLY; 8676 case WLAN_PHYMODE_11NA_HT20: 8677 return WMI_HOST_MODE_11NA_HT20; 8678 case WLAN_PHYMODE_11NG_HT20: 8679 return WMI_HOST_MODE_11NG_HT20; 8680 case WLAN_PHYMODE_11NA_HT40: 8681 return WMI_HOST_MODE_11NA_HT40; 8682 case WLAN_PHYMODE_11NG_HT40: 8683 case WLAN_PHYMODE_11NG_HT40PLUS: 8684 case WLAN_PHYMODE_11NG_HT40MINUS: 8685 return WMI_HOST_MODE_11NG_HT40; 8686 case WLAN_PHYMODE_11AC_VHT20: 8687 return WMI_HOST_MODE_11AC_VHT20; 8688 case WLAN_PHYMODE_11AC_VHT40: 8689 return WMI_HOST_MODE_11AC_VHT40; 8690 case WLAN_PHYMODE_11AC_VHT80: 8691 return WMI_HOST_MODE_11AC_VHT80; 8692 case WLAN_PHYMODE_11AC_VHT20_2G: 8693 return WMI_HOST_MODE_11AC_VHT20_2G; 8694 case WLAN_PHYMODE_11AC_VHT40PLUS_2G: 8695 case WLAN_PHYMODE_11AC_VHT40MINUS_2G: 8696 case WLAN_PHYMODE_11AC_VHT40_2G: 8697 return WMI_HOST_MODE_11AC_VHT40_2G; 8698 case WLAN_PHYMODE_11AC_VHT80_2G: 8699 return WMI_HOST_MODE_11AC_VHT80_2G; 8700 case WLAN_PHYMODE_11AC_VHT80_80: 8701 return WMI_HOST_MODE_11AC_VHT80_80; 8702 case WLAN_PHYMODE_11AC_VHT160: 8703 return WMI_HOST_MODE_11AC_VHT160; 8704 case WLAN_PHYMODE_11AXA_HE20: 8705 return WMI_HOST_MODE_11AX_HE20; 8706 case WLAN_PHYMODE_11AXA_HE40: 8707 return WMI_HOST_MODE_11AX_HE40; 8708 case WLAN_PHYMODE_11AXA_HE80: 8709 return WMI_HOST_MODE_11AX_HE80; 8710 case WLAN_PHYMODE_11AXA_HE80_80: 8711 return WMI_HOST_MODE_11AX_HE80_80; 8712 case WLAN_PHYMODE_11AXA_HE160: 8713 return WMI_HOST_MODE_11AX_HE160; 8714 case WLAN_PHYMODE_11AXG_HE20: 8715 return WMI_HOST_MODE_11AX_HE20_2G; 8716 case WLAN_PHYMODE_11AXG_HE40: 8717 case WLAN_PHYMODE_11AXG_HE40PLUS: 8718 case WLAN_PHYMODE_11AXG_HE40MINUS: 8719 return WMI_HOST_MODE_11AX_HE40_2G; 8720 case WLAN_PHYMODE_11AXG_HE80: 8721 return WMI_HOST_MODE_11AX_HE80_2G; 8722 default: 8723 return wmi_host_to_fw_phymode_11be(host_phymode); 8724 } 8725 } 8726 8727 /* 8728 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8729 * to wmi channel width 8730 * @chan_width: Host channel width 8731 * 8732 * Return: wmi channel width 8733 */ 8734 static 8735 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8736 { 8737 switch (chan_width) { 8738 case CH_WIDTH_20MHZ: 8739 return WMI_CHAN_WIDTH_20; 8740 case CH_WIDTH_40MHZ: 8741 return WMI_CHAN_WIDTH_40; 8742 case CH_WIDTH_80MHZ: 8743 return WMI_CHAN_WIDTH_80; 8744 case CH_WIDTH_160MHZ: 8745 return WMI_CHAN_WIDTH_160; 8746 case CH_WIDTH_80P80MHZ: 8747 return WMI_CHAN_WIDTH_80P80; 8748 case CH_WIDTH_5MHZ: 8749 return WMI_CHAN_WIDTH_5; 8750 case CH_WIDTH_10MHZ: 8751 return WMI_CHAN_WIDTH_10; 8752 #ifdef WLAN_FEATURE_11BE 8753 case CH_WIDTH_320MHZ: 8754 return WMI_CHAN_WIDTH_320; 8755 #endif 8756 default: 8757 return WMI_CHAN_WIDTH_MAX; 8758 } 8759 } 8760 8761 /** 8762 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8763 * command to fw 8764 * @wmi_handle: wmi handle 8765 * @param: pointer to hold spectral config parameter 8766 * 8767 * Return: QDF_STATUS_SUCCESS for success or error code 8768 */ 8769 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8770 struct vdev_spectral_configure_params *param) 8771 { 8772 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8773 wmi_buf_t buf; 8774 QDF_STATUS ret; 8775 int32_t len; 8776 8777 len = sizeof(*cmd); 8778 buf = wmi_buf_alloc(wmi_handle, len); 8779 if (!buf) 8780 return QDF_STATUS_E_FAILURE; 8781 8782 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8783 WMITLV_SET_HDR(&cmd->tlv_header, 8784 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8785 WMITLV_GET_STRUCT_TLVLEN( 8786 wmi_vdev_spectral_configure_cmd_fixed_param)); 8787 8788 cmd->vdev_id = param->vdev_id; 8789 cmd->spectral_scan_count = param->count; 8790 cmd->spectral_scan_period = param->period; 8791 cmd->spectral_scan_priority = param->spectral_pri; 8792 cmd->spectral_scan_fft_size = param->fft_size; 8793 cmd->spectral_scan_gc_ena = param->gc_enable; 8794 cmd->spectral_scan_restart_ena = param->restart_enable; 8795 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8796 cmd->spectral_scan_init_delay = param->init_delay; 8797 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8798 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8799 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8800 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8801 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8802 cmd->spectral_scan_pwr_format = param->pwr_format; 8803 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8804 cmd->spectral_scan_bin_scale = param->bin_scale; 8805 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8806 cmd->spectral_scan_chn_mask = param->chn_mask; 8807 cmd->spectral_scan_mode = param->mode; 8808 cmd->spectral_scan_center_freq1 = param->center_freq1; 8809 cmd->spectral_scan_center_freq2 = param->center_freq2; 8810 cmd->spectral_scan_chan_width = 8811 convert_host_to_target_ch_width(param->chan_width); 8812 cmd->recapture_sample_on_gain_change = param->fft_recap; 8813 /* Not used, fill with zeros */ 8814 cmd->spectral_scan_chan_freq = 0; 8815 8816 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8817 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8818 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8819 8820 if (ret != 0) { 8821 wmi_err("Sending set quiet cmd failed"); 8822 wmi_buf_free(buf); 8823 } 8824 8825 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8826 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8827 param->vdev_id, param->count); 8828 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8829 param->period, param->spectral_pri); 8830 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8831 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8832 param->fft_size, param->gc_enable); 8833 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8834 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8835 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8836 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8837 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8838 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8839 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8840 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8841 param->rssi_thr, param->pwr_format); 8842 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8843 param->rpt_mode, param->bin_scale); 8844 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8845 param->dbm_adj, param->chn_mask); 8846 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8847 param->mode, param->center_freq1); 8848 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8849 param->center_freq2, param->chan_freq); 8850 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8851 param->chan_width, ret); 8852 8853 return ret; 8854 } 8855 8856 /** 8857 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8858 * command to fw 8859 * @wmi_handle: wmi handle 8860 * @param: pointer to hold spectral enable parameter 8861 * 8862 * Return: QDF_STATUS_SUCCESS for success or error code 8863 */ 8864 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8865 struct vdev_spectral_enable_params *param) 8866 { 8867 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8868 wmi_buf_t buf; 8869 QDF_STATUS ret; 8870 int32_t len; 8871 8872 len = sizeof(*cmd); 8873 buf = wmi_buf_alloc(wmi_handle, len); 8874 if (!buf) 8875 return QDF_STATUS_E_FAILURE; 8876 8877 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8878 WMITLV_SET_HDR(&cmd->tlv_header, 8879 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8880 WMITLV_GET_STRUCT_TLVLEN( 8881 wmi_vdev_spectral_enable_cmd_fixed_param)); 8882 8883 cmd->vdev_id = param->vdev_id; 8884 8885 if (param->active_valid) { 8886 cmd->trigger_cmd = param->active ? 1 : 2; 8887 /* 1: Trigger, 2: Clear Trigger */ 8888 } else { 8889 cmd->trigger_cmd = 0; /* 0: Ignore */ 8890 } 8891 8892 if (param->enabled_valid) { 8893 cmd->enable_cmd = param->enabled ? 1 : 2; 8894 /* 1: Enable 2: Disable */ 8895 } else { 8896 cmd->enable_cmd = 0; /* 0: Ignore */ 8897 } 8898 cmd->spectral_scan_mode = param->mode; 8899 8900 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8901 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8902 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8903 8904 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8905 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8906 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8907 8908 if (ret != 0) { 8909 wmi_err("Sending scan enable CMD failed"); 8910 wmi_buf_free(buf); 8911 } 8912 8913 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8914 ret); 8915 8916 return ret; 8917 } 8918 8919 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8920 static QDF_STATUS 8921 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8922 wmi_unified_t wmi_handle, 8923 uint8_t *event, struct spectral_startscan_resp_params *param) 8924 { 8925 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8926 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8927 8928 if (!wmi_handle) { 8929 wmi_err("WMI handle is null"); 8930 return QDF_STATUS_E_INVAL; 8931 } 8932 8933 if (!event) { 8934 wmi_err("WMI event is null"); 8935 return QDF_STATUS_E_INVAL; 8936 } 8937 8938 if (!param) { 8939 wmi_err("Spectral startscan response params is null"); 8940 return QDF_STATUS_E_INVAL; 8941 } 8942 8943 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8944 if (!param_buf) 8945 return QDF_STATUS_E_INVAL; 8946 8947 ev = param_buf->fixed_param; 8948 if (!ev) 8949 return QDF_STATUS_E_INVAL; 8950 8951 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8952 wmi_handle, 8953 ev->pdev_id); 8954 param->smode = ev->spectral_scan_mode; 8955 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8956 param->num_det_info = param_buf->num_det_info; 8957 8958 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8959 ev->pdev_id, ev->spectral_scan_mode, 8960 param_buf->num_fft_bin_index, param_buf->num_det_info); 8961 8962 return QDF_STATUS_SUCCESS; 8963 } 8964 8965 static QDF_STATUS 8966 extract_pdev_sscan_fft_bin_index_tlv( 8967 wmi_unified_t wmi_handle, uint8_t *event, 8968 struct spectral_fft_bin_markers_160_165mhz *param) 8969 { 8970 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8971 wmi_pdev_sscan_fft_bin_index *ev; 8972 8973 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8974 if (!param_buf) 8975 return QDF_STATUS_E_INVAL; 8976 8977 ev = param_buf->fft_bin_index; 8978 if (!ev) 8979 return QDF_STATUS_E_INVAL; 8980 8981 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8982 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8983 param->start_pri80 + 1; 8984 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8985 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8986 param->start_sec80 + 1; 8987 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8988 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8989 param->start_5mhz + 1; 8990 param->is_valid = true; 8991 8992 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8993 param->start_pri80, param->num_pri80, 8994 param->start_sec80, param->num_sec80, 8995 param->start_5mhz, param->num_5mhz); 8996 8997 return QDF_STATUS_SUCCESS; 8998 } 8999 9000 /** 9001 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 9002 * for a spectral scan session 9003 * @wmi_handle: handle to WMI. 9004 * @event: Event buffer 9005 * @chan_info: Spectral session channel information data structure to be filled 9006 * by this API 9007 * 9008 * Return: QDF_STATUS of operation 9009 */ 9010 static QDF_STATUS 9011 extract_pdev_spectral_session_chan_info_tlv( 9012 wmi_unified_t wmi_handle, void *event, 9013 struct spectral_session_chan_info *chan_info) 9014 { 9015 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 9016 wmi_pdev_sscan_chan_info *chan_info_tlv; 9017 9018 if (!param_buf) { 9019 wmi_err("param_buf is NULL"); 9020 return QDF_STATUS_E_NULL_VALUE; 9021 } 9022 9023 if (!chan_info) { 9024 wmi_err("chan_info is NULL"); 9025 return QDF_STATUS_E_NULL_VALUE; 9026 } 9027 9028 chan_info_tlv = param_buf->chan_info; 9029 if (!chan_info_tlv) { 9030 wmi_err("chan_info tlv is not present in the event"); 9031 return QDF_STATUS_E_NULL_VALUE; 9032 } 9033 9034 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 9035 "operating_cfreq2:%u operating_bw:%u" 9036 "operating_puncture_20mhz_bitmap:%u" 9037 "sscan_cfreq1:%u sscan_cfreq2:%u" 9038 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 9039 chan_info_tlv->operating_pri20_freq, 9040 chan_info_tlv->operating_cfreq1, 9041 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 9042 chan_info_tlv->operating_puncture_20mhz_bitmap, 9043 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 9044 chan_info_tlv->sscan_bw, 9045 chan_info_tlv->sscan_puncture_20mhz_bitmap); 9046 9047 chan_info->operating_pri20_freq = 9048 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 9049 chan_info->operating_cfreq1 = 9050 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 9051 chan_info->operating_cfreq2 = 9052 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 9053 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 9054 chan_info->operating_puncture_20mhz_bitmap = 9055 chan_info_tlv->operating_puncture_20mhz_bitmap; 9056 9057 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 9058 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 9059 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 9060 chan_info->sscan_puncture_20mhz_bitmap = 9061 chan_info_tlv->sscan_puncture_20mhz_bitmap; 9062 9063 return QDF_STATUS_SUCCESS; 9064 } 9065 9066 static QDF_STATUS 9067 extract_pdev_spectral_session_detector_info_tlv( 9068 wmi_unified_t wmi_handle, void *event, 9069 struct spectral_session_det_info *det_info, uint8_t idx) 9070 { 9071 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 9072 wmi_pdev_sscan_per_detector_info *det_info_tlv; 9073 9074 if (!param_buf) { 9075 wmi_err("param_buf is NULL"); 9076 return QDF_STATUS_E_NULL_VALUE; 9077 } 9078 9079 if (!det_info) { 9080 wmi_err("chan_info is NULL"); 9081 return QDF_STATUS_E_NULL_VALUE; 9082 } 9083 9084 if (!param_buf->det_info) { 9085 wmi_err("det_info tlv is not present in the event"); 9086 return QDF_STATUS_E_NULL_VALUE; 9087 } 9088 9089 if (idx >= param_buf->num_det_info) { 9090 wmi_err("det_info index(%u) is greater than or equal to %u", 9091 idx, param_buf->num_det_info); 9092 return QDF_STATUS_E_FAILURE; 9093 } 9094 9095 det_info_tlv = ¶m_buf->det_info[idx]; 9096 9097 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 9098 idx, det_info_tlv->detector_id, 9099 det_info_tlv->start_freq, det_info_tlv->end_freq); 9100 9101 det_info->det_id = det_info_tlv->detector_id; 9102 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 9103 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 9104 9105 return QDF_STATUS_SUCCESS; 9106 } 9107 9108 /** 9109 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 9110 * capabilities WMI event 9111 * @wmi_handle: handle to WMI. 9112 * @event: Event buffer 9113 * @params: Spectral capabilities event parameters data structure to be filled 9114 * by this API 9115 * 9116 * Return: QDF_STATUS of operation 9117 */ 9118 static QDF_STATUS 9119 extract_spectral_caps_fixed_param_tlv( 9120 wmi_unified_t wmi_handle, void *event, 9121 struct spectral_capabilities_event_params *params) 9122 { 9123 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9124 9125 if (!param_buf) { 9126 wmi_err("param_buf is NULL"); 9127 return QDF_STATUS_E_NULL_VALUE; 9128 } 9129 9130 if (!params) { 9131 wmi_err("event parameters is NULL"); 9132 return QDF_STATUS_E_NULL_VALUE; 9133 } 9134 9135 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 9136 params->num_fft_size_caps = param_buf->num_fft_size_caps; 9137 9138 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 9139 params->num_sscan_bw_caps, params->num_fft_size_caps); 9140 9141 return QDF_STATUS_SUCCESS; 9142 } 9143 9144 /** 9145 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 9146 * Spectral capabilities WMI event 9147 * @wmi_handle: handle to WMI. 9148 * @event: Event buffer 9149 * @bw_caps: Data structure to be populated by this API after extraction 9150 * 9151 * Return: QDF_STATUS of operation 9152 */ 9153 static QDF_STATUS 9154 extract_spectral_scan_bw_caps_tlv( 9155 wmi_unified_t wmi_handle, void *event, 9156 struct spectral_scan_bw_capabilities *bw_caps) 9157 { 9158 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9159 int idx; 9160 9161 if (!param_buf) { 9162 wmi_err("param_buf is NULL"); 9163 return QDF_STATUS_E_NULL_VALUE; 9164 } 9165 9166 if (!bw_caps) { 9167 wmi_err("bw_caps is null"); 9168 return QDF_STATUS_E_NULL_VALUE; 9169 } 9170 9171 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 9172 bw_caps[idx].pdev_id = 9173 wmi_handle->ops->convert_pdev_id_target_to_host( 9174 wmi_handle, 9175 param_buf->sscan_bw_caps[idx].pdev_id); 9176 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 9177 bw_caps[idx].operating_bw = wmi_map_ch_width( 9178 param_buf->sscan_bw_caps[idx].operating_bw); 9179 bw_caps[idx].supported_bws = 9180 param_buf->sscan_bw_caps[idx].supported_flags; 9181 9182 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 9183 "operating_bw:%u supported_flags:0x%x", 9184 idx, param_buf->sscan_bw_caps[idx].pdev_id, 9185 param_buf->sscan_bw_caps[idx].sscan_mode, 9186 param_buf->sscan_bw_caps[idx].operating_bw, 9187 param_buf->sscan_bw_caps[idx].supported_flags); 9188 } 9189 9190 return QDF_STATUS_SUCCESS; 9191 } 9192 9193 /** 9194 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 9195 * Spectral capabilities WMI event 9196 * @wmi_handle: handle to WMI. 9197 * @event: Event buffer 9198 * @fft_size_caps: Data structure to be populated by this API after extraction 9199 * 9200 * Return: QDF_STATUS of operation 9201 */ 9202 static QDF_STATUS 9203 extract_spectral_fft_size_caps_tlv( 9204 wmi_unified_t wmi_handle, void *event, 9205 struct spectral_fft_size_capabilities *fft_size_caps) 9206 { 9207 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9208 int idx; 9209 9210 if (!param_buf) { 9211 wmi_err("param_buf is NULL"); 9212 return QDF_STATUS_E_NULL_VALUE; 9213 } 9214 9215 if (!fft_size_caps) { 9216 wmi_err("fft size caps is NULL"); 9217 return QDF_STATUS_E_NULL_VALUE; 9218 } 9219 9220 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 9221 fft_size_caps[idx].pdev_id = 9222 wmi_handle->ops->convert_pdev_id_target_to_host( 9223 wmi_handle, 9224 param_buf->fft_size_caps[idx].pdev_id); 9225 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 9226 param_buf->fft_size_caps[idx].sscan_bw); 9227 fft_size_caps[idx].supports_fft_sizes = 9228 param_buf->fft_size_caps[idx].supported_flags; 9229 9230 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 9231 "supported_flags:0x%x", 9232 idx, param_buf->fft_size_caps[idx].pdev_id, 9233 param_buf->fft_size_caps[idx].sscan_bw, 9234 param_buf->fft_size_caps[idx].supported_flags); 9235 } 9236 9237 return QDF_STATUS_SUCCESS; 9238 } 9239 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 9240 9241 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 9242 static inline void 9243 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9244 struct thermal_mitigation_params *param) 9245 { 9246 tt_conf->client_id = param->client_id; 9247 tt_conf->priority = param->priority; 9248 } 9249 #else 9250 static inline void 9251 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9252 struct thermal_mitigation_params *param) 9253 { 9254 } 9255 #endif 9256 9257 /** 9258 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 9259 * @wmi_handle : handle to WMI. 9260 * @param : pointer to hold thermal mitigation param 9261 * 9262 * Return: QDF_STATUS_SUCCESS for success or error code 9263 */ 9264 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 9265 wmi_unified_t wmi_handle, 9266 struct thermal_mitigation_params *param) 9267 { 9268 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 9269 wmi_therm_throt_level_config_info *lvl_conf = NULL; 9270 wmi_buf_t buf = NULL; 9271 uint8_t *buf_ptr = NULL; 9272 int error; 9273 int32_t len; 9274 int i; 9275 9276 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 9277 param->num_thermal_conf * 9278 sizeof(wmi_therm_throt_level_config_info); 9279 9280 buf = wmi_buf_alloc(wmi_handle, len); 9281 if (!buf) 9282 return QDF_STATUS_E_NOMEM; 9283 9284 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 9285 9286 /* init fixed params */ 9287 WMITLV_SET_HDR(tt_conf, 9288 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 9289 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 9290 9291 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9292 wmi_handle, 9293 param->pdev_id); 9294 tt_conf->enable = param->enable; 9295 tt_conf->dc = param->dc; 9296 tt_conf->dc_per_event = param->dc_per_event; 9297 tt_conf->therm_throt_levels = param->num_thermal_conf; 9298 wmi_fill_client_id_priority(tt_conf, param); 9299 buf_ptr = (uint8_t *) ++tt_conf; 9300 /* init TLV params */ 9301 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9302 (param->num_thermal_conf * 9303 sizeof(wmi_therm_throt_level_config_info))); 9304 9305 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 9306 for (i = 0; i < param->num_thermal_conf; i++) { 9307 WMITLV_SET_HDR(&lvl_conf->tlv_header, 9308 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 9309 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 9310 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 9311 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 9312 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 9313 lvl_conf->prio = param->levelconf[i].priority; 9314 lvl_conf++; 9315 } 9316 9317 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 9318 error = wmi_unified_cmd_send(wmi_handle, buf, len, 9319 WMI_THERM_THROT_SET_CONF_CMDID); 9320 if (QDF_IS_STATUS_ERROR(error)) { 9321 wmi_buf_free(buf); 9322 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 9323 } 9324 9325 return error; 9326 } 9327 9328 /** 9329 * send_coex_config_cmd_tlv() - send coex config command to fw 9330 * @wmi_handle: wmi handle 9331 * @param: pointer to coex config param 9332 * 9333 * Return: QDF_STATUS_SUCCESS for success or error code 9334 */ 9335 static QDF_STATUS 9336 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 9337 struct coex_config_params *param) 9338 { 9339 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 9340 wmi_buf_t buf; 9341 QDF_STATUS ret; 9342 int32_t len; 9343 9344 len = sizeof(*cmd); 9345 buf = wmi_buf_alloc(wmi_handle, len); 9346 if (!buf) 9347 return QDF_STATUS_E_FAILURE; 9348 9349 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 9350 WMITLV_SET_HDR(&cmd->tlv_header, 9351 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9352 WMITLV_GET_STRUCT_TLVLEN( 9353 WMI_COEX_CONFIG_CMD_fixed_param)); 9354 9355 cmd->vdev_id = param->vdev_id; 9356 cmd->config_type = param->config_type; 9357 cmd->config_arg1 = param->config_arg1; 9358 cmd->config_arg2 = param->config_arg2; 9359 cmd->config_arg3 = param->config_arg3; 9360 cmd->config_arg4 = param->config_arg4; 9361 cmd->config_arg5 = param->config_arg5; 9362 cmd->config_arg6 = param->config_arg6; 9363 9364 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 9365 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9366 WMI_COEX_CONFIG_CMDID); 9367 9368 if (ret != 0) { 9369 wmi_err("Sending COEX CONFIG CMD failed"); 9370 wmi_buf_free(buf); 9371 } 9372 9373 return ret; 9374 } 9375 9376 /** 9377 * send_coex_multi_config_cmd_tlv() - send coex multiple config command to fw 9378 * @wmi_handle: wmi handle 9379 * @param: pointer to coex multiple config parameters 9380 * 9381 * Return: QDF_STATUS_SUCCESS for success or error code 9382 */ 9383 static QDF_STATUS 9384 send_coex_multi_config_cmd_tlv(wmi_unified_t wmi_handle, 9385 struct coex_multi_config *param) 9386 { 9387 wmi_coex_multiple_config_cmd_fixed_param *cmd; 9388 WMI_COEX_CONFIG_CMD_fixed_param *dst_cfg; 9389 struct coex_config_item *src_cfg; 9390 wmi_buf_t buf; 9391 QDF_STATUS ret; 9392 uint32_t len, i; 9393 uint8_t *buf_ptr; 9394 9395 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9396 param->num_configs * sizeof(*dst_cfg); 9397 buf = wmi_buf_alloc(wmi_handle, len); 9398 if (!buf) 9399 return QDF_STATUS_E_FAILURE; 9400 9401 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9402 cmd = (wmi_coex_multiple_config_cmd_fixed_param *)buf_ptr; 9403 WMITLV_SET_HDR(&cmd->tlv_header, 9404 WMITLV_TAG_STRUC_wmi_coex_multiple_config_cmd_fixed_param, 9405 WMITLV_GET_STRUCT_TLVLEN( 9406 wmi_coex_multiple_config_cmd_fixed_param)); 9407 9408 buf_ptr += sizeof(*cmd); 9409 9410 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9411 sizeof(*dst_cfg) * param->num_configs); 9412 buf_ptr += WMI_TLV_HDR_SIZE; 9413 9414 dst_cfg = (WMI_COEX_CONFIG_CMD_fixed_param *)buf_ptr; 9415 for (i = 0; i < param->num_configs; i++, dst_cfg++) { 9416 src_cfg = ¶m->cfg_items[i]; 9417 WMITLV_SET_HDR(&dst_cfg->tlv_header, 9418 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9419 WMITLV_GET_STRUCT_TLVLEN( 9420 WMI_COEX_CONFIG_CMD_fixed_param)); 9421 dst_cfg->vdev_id = param->vdev_id; 9422 dst_cfg->config_type = src_cfg->config_type; 9423 dst_cfg->config_arg1 = src_cfg->config_arg1; 9424 dst_cfg->config_arg2 = src_cfg->config_arg2; 9425 dst_cfg->config_arg3 = src_cfg->config_arg3; 9426 dst_cfg->config_arg4 = src_cfg->config_arg4; 9427 dst_cfg->config_arg5 = src_cfg->config_arg5; 9428 dst_cfg->config_arg6 = src_cfg->config_arg6; 9429 } 9430 9431 wmi_mtrace(WMI_COEX_MULTIPLE_CONFIG_CMDID, param->vdev_id, 0); 9432 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9433 WMI_COEX_MULTIPLE_CONFIG_CMDID); 9434 9435 if (QDF_IS_STATUS_ERROR(ret)) { 9436 wmi_err("Sending COEX MULTIPLE CONFIG CMD failed"); 9437 wmi_buf_free(buf); 9438 } 9439 9440 return ret; 9441 } 9442 9443 #ifdef WLAN_FEATURE_DBAM_CONFIG 9444 9445 static enum wmi_coex_dbam_mode_type 9446 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 9447 { 9448 switch (mode) { 9449 case COEX_DBAM_ENABLE: 9450 return WMI_COEX_DBAM_ENABLE; 9451 case COEX_DBAM_FORCE_ENABLE: 9452 return WMI_COEX_DBAM_FORCED; 9453 case COEX_DBAM_DISABLE: 9454 default: 9455 return WMI_COEX_DBAM_DISABLE; 9456 } 9457 } 9458 9459 /** 9460 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 9461 * @wmi_handle: wmi handle 9462 * @param: pointer to coex dbam config param 9463 * 9464 * Return: QDF_STATUS_SUCCESS for success or error code 9465 */ 9466 static QDF_STATUS 9467 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 9468 struct coex_dbam_config_params *param) 9469 { 9470 wmi_coex_dbam_cmd_fixed_param *cmd; 9471 wmi_buf_t buf; 9472 void *buf_ptr; 9473 QDF_STATUS ret; 9474 int32_t len; 9475 9476 len = sizeof(*cmd); 9477 buf = wmi_buf_alloc(wmi_handle, len); 9478 if (!buf) { 9479 wmi_err_rl("Failed to allocate wmi buffer"); 9480 return QDF_STATUS_E_NOMEM; 9481 } 9482 9483 buf_ptr = wmi_buf_data(buf); 9484 cmd = buf_ptr; 9485 WMITLV_SET_HDR(&cmd->tlv_header, 9486 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 9487 WMITLV_GET_STRUCT_TLVLEN( 9488 wmi_coex_dbam_cmd_fixed_param)); 9489 9490 cmd->vdev_id = param->vdev_id; 9491 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 9492 9493 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 9494 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9495 WMI_COEX_DBAM_CMDID); 9496 9497 if (QDF_IS_STATUS_ERROR(ret)) { 9498 wmi_err("Sending DBAM CONFIG CMD failed"); 9499 wmi_buf_free(buf); 9500 return QDF_STATUS_E_FAILURE; 9501 } 9502 9503 return ret; 9504 } 9505 9506 static enum coex_dbam_comp_status 9507 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 9508 { 9509 switch (status) { 9510 case WMI_COEX_DBAM_COMP_SUCCESS: 9511 case WMI_COEX_DBAM_COMP_ONGOING: 9512 case WMI_COEX_DBAM_COMP_DELAYED: 9513 return COEX_DBAM_COMP_SUCCESS; 9514 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 9515 return COEX_DBAM_COMP_NOT_SUPPORT; 9516 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 9517 case WMI_COEX_DBAM_COMP_FAIL: 9518 default: 9519 return COEX_DBAM_COMP_FAIL; 9520 } 9521 } 9522 9523 /** 9524 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 9525 * @wmi_handle: WMI handle 9526 * @evt_buf: event buffer 9527 * @resp: pointer to coex dbam config response 9528 * 9529 * Return: QDF_STATUS 9530 */ 9531 static QDF_STATUS 9532 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9533 struct coex_dbam_config_resp *resp) 9534 { 9535 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 9536 wmi_coex_dbam_complete_event_fixed_param *event; 9537 9538 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 9539 9540 event = param_buf->fixed_param; 9541 9542 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 9543 9544 return QDF_STATUS_SUCCESS; 9545 } 9546 #endif 9547 9548 #ifdef WLAN_SUPPORT_TWT 9549 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9550 target_resource_config *tgt_res_cfg) 9551 { 9552 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 9553 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 9554 } 9555 #else 9556 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9557 target_resource_config *tgt_res_cfg) 9558 { 9559 resource_cfg->twt_ap_pdev_count = 0; 9560 resource_cfg->twt_ap_sta_count = 0; 9561 } 9562 #endif 9563 9564 #ifdef WLAN_FEATURE_NAN 9565 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9566 { 9567 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 9568 resource_cfg->host_service_flags, 1); 9569 } 9570 #else 9571 static inline 9572 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9573 { 9574 } 9575 #endif 9576 9577 #if defined(CONFIG_AFC_SUPPORT) 9578 static 9579 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9580 target_resource_config *tgt_res_cfg) 9581 { 9582 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 9583 resource_cfg->host_service_flags, 9584 tgt_res_cfg->afc_indoor_support); 9585 9586 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 9587 resource_cfg->host_service_flags, 9588 tgt_res_cfg->afc_outdoor_support); 9589 } 9590 #else 9591 static 9592 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9593 target_resource_config *tgt_res_cfg) 9594 { 9595 } 9596 #endif 9597 9598 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 9599 static inline 9600 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9601 target_resource_config *tgt_res_cfg) 9602 { 9603 if (tgt_res_cfg->tx_ilp_enable) 9604 WMI_RSRC_CFG_FLAGS2_LATENCY_FLOWQ_SUPPORT_SET( 9605 resource_cfg->flags2, 1); 9606 } 9607 #else 9608 static inline 9609 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9610 target_resource_config *tgt_res_cfg) 9611 { 9612 } 9613 #endif 9614 9615 #ifdef MOBILE_DFS_SUPPORT 9616 static inline 9617 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9618 target_resource_config *tgt_res_cfg) 9619 { 9620 WMI_RSRC_CFG_HOST_SERVICE_FLAG_RADAR_FLAGS_FULL_BW_NOL_SET(resource_cfg->host_service_flags, 9621 tgt_res_cfg->is_full_bw_nol_supported); 9622 } 9623 #else 9624 static inline 9625 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9626 target_resource_config *tgt_res_cfg) 9627 { 9628 } 9629 #endif 9630 9631 static 9632 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 9633 target_resource_config *tgt_res_cfg) 9634 { 9635 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9636 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9637 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9638 resource_cfg->num_offload_reorder_buffs = 9639 tgt_res_cfg->num_offload_reorder_buffs; 9640 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9641 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9642 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9643 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9644 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9645 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9646 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9647 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9648 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9649 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9650 resource_cfg->scan_max_pending_req = 9651 tgt_res_cfg->scan_max_pending_req; 9652 resource_cfg->bmiss_offload_max_vdev = 9653 tgt_res_cfg->bmiss_offload_max_vdev; 9654 resource_cfg->roam_offload_max_vdev = 9655 tgt_res_cfg->roam_offload_max_vdev; 9656 resource_cfg->roam_offload_max_ap_profiles = 9657 tgt_res_cfg->roam_offload_max_ap_profiles; 9658 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9659 resource_cfg->num_mcast_table_elems = 9660 tgt_res_cfg->num_mcast_table_elems; 9661 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9662 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9663 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9664 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9665 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9666 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9667 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9668 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9669 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9670 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9671 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9672 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9673 resource_cfg->num_tdls_conn_table_entries = 9674 tgt_res_cfg->num_tdls_conn_table_entries; 9675 resource_cfg->beacon_tx_offload_max_vdev = 9676 tgt_res_cfg->beacon_tx_offload_max_vdev; 9677 resource_cfg->num_multicast_filter_entries = 9678 tgt_res_cfg->num_multicast_filter_entries; 9679 resource_cfg->num_wow_filters = 9680 tgt_res_cfg->num_wow_filters; 9681 resource_cfg->num_keep_alive_pattern = 9682 tgt_res_cfg->num_keep_alive_pattern; 9683 resource_cfg->keep_alive_pattern_size = 9684 tgt_res_cfg->keep_alive_pattern_size; 9685 resource_cfg->max_tdls_concurrent_sleep_sta = 9686 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9687 resource_cfg->max_tdls_concurrent_buffer_sta = 9688 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9689 resource_cfg->wmi_send_separate = 9690 tgt_res_cfg->wmi_send_separate; 9691 resource_cfg->num_ocb_vdevs = 9692 tgt_res_cfg->num_ocb_vdevs; 9693 resource_cfg->num_ocb_channels = 9694 tgt_res_cfg->num_ocb_channels; 9695 resource_cfg->num_ocb_schedules = 9696 tgt_res_cfg->num_ocb_schedules; 9697 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9698 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9699 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9700 resource_cfg->max_num_dbs_scan_duty_cycle = 9701 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9702 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9703 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9704 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9705 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9706 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9707 /* Deferred AI: Max rnr neighbors supported in multisoc case 9708 * where in SoC can support 6ghz. During WMI init of a SoC 9709 * currently there is no way to figure if another SOC is plugged in 9710 * and it can support 6Ghz. 9711 */ 9712 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9713 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9714 resource_cfg->ema_max_profile_period = 9715 tgt_res_cfg->ema_max_profile_period; 9716 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9717 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9718 9719 if (tgt_res_cfg->max_ndp_sessions) 9720 resource_cfg->max_ndp_sessions = 9721 tgt_res_cfg->max_ndp_sessions; 9722 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9723 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9724 resource_cfg->num_max_mlo_link_per_ml_bss = 9725 tgt_res_cfg->num_max_mlo_link_per_ml_bss; 9726 9727 if (tgt_res_cfg->atf_config) 9728 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9729 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9730 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9731 resource_cfg->flag1, 1); 9732 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9733 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9734 resource_cfg->flag1, 1); 9735 if (tgt_res_cfg->cce_disable) 9736 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9737 if (tgt_res_cfg->enable_pci_gen) 9738 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9739 resource_cfg->flag1, 1); 9740 if (tgt_res_cfg->eapol_minrate_set) { 9741 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9742 resource_cfg->flag1, 1); 9743 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9744 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9745 resource_cfg->flag1, 1); 9746 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9747 resource_cfg->flag1, 9748 tgt_res_cfg->eapol_minrate_ac_set); 9749 } 9750 } 9751 if (tgt_res_cfg->new_htt_msg_format) { 9752 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9753 resource_cfg->flag1, 1); 9754 } 9755 9756 if (tgt_res_cfg->peer_unmap_conf_support) 9757 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9758 resource_cfg->flag1, 1); 9759 9760 if (tgt_res_cfg->tstamp64_en) 9761 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9762 resource_cfg->flag1, 1); 9763 9764 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9765 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9766 resource_cfg->flag1, 1); 9767 if (tgt_res_cfg->pktcapture_support) 9768 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9769 resource_cfg->flag1, 1); 9770 9771 /* 9772 * Control padding using config param/ini of iphdr_pad_config 9773 */ 9774 if (tgt_res_cfg->iphdr_pad_config) 9775 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9776 resource_cfg->flag1, 1); 9777 9778 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9779 tgt_res_cfg->ipa_disable); 9780 9781 if (tgt_res_cfg->time_sync_ftm) 9782 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9783 1); 9784 9785 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9786 resource_cfg->peer_map_unmap_versions = 9787 tgt_res_cfg->peer_map_unmap_version; 9788 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9789 if (tgt_res_cfg->re_ul_resp) 9790 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9791 tgt_res_cfg->re_ul_resp); 9792 9793 /* 9794 * Enable Service Aware Wifi 9795 */ 9796 if (tgt_res_cfg->sawf) 9797 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9798 tgt_res_cfg->sawf); 9799 9800 /* 9801 * Enable ast flow override per peer 9802 */ 9803 resource_cfg->msdu_flow_override_config0 = 0; 9804 WMI_MSDU_FLOW_AST_ENABLE_SET( 9805 resource_cfg->msdu_flow_override_config0, 9806 WMI_CONFIG_MSDU_AST_INDEX_1, 9807 tgt_res_cfg->ast_1_valid_mask_enable); 9808 9809 WMI_MSDU_FLOW_AST_ENABLE_SET( 9810 resource_cfg->msdu_flow_override_config0, 9811 WMI_CONFIG_MSDU_AST_INDEX_2, 9812 tgt_res_cfg->ast_2_valid_mask_enable); 9813 9814 WMI_MSDU_FLOW_AST_ENABLE_SET( 9815 resource_cfg->msdu_flow_override_config0, 9816 WMI_CONFIG_MSDU_AST_INDEX_3, 9817 tgt_res_cfg->ast_3_valid_mask_enable); 9818 9819 /* 9820 * Enable ast flow mask and TID valid mask configurations 9821 */ 9822 resource_cfg->msdu_flow_override_config1 = 0; 9823 9824 /*Enable UDP flow for Ast index 0*/ 9825 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9826 resource_cfg->msdu_flow_override_config1, 9827 WMI_CONFIG_MSDU_AST_INDEX_0, 9828 tgt_res_cfg->ast_0_flow_mask_enable); 9829 9830 /*Enable Non UDP flow for Ast index 1*/ 9831 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9832 resource_cfg->msdu_flow_override_config1, 9833 WMI_CONFIG_MSDU_AST_INDEX_1, 9834 tgt_res_cfg->ast_1_flow_mask_enable); 9835 9836 /*Enable Hi-Priority flow for Ast index 2*/ 9837 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9838 resource_cfg->msdu_flow_override_config1, 9839 WMI_CONFIG_MSDU_AST_INDEX_2, 9840 tgt_res_cfg->ast_2_flow_mask_enable); 9841 9842 /*Enable Low-Priority flow for Ast index 3*/ 9843 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9844 resource_cfg->msdu_flow_override_config1, 9845 WMI_CONFIG_MSDU_AST_INDEX_3, 9846 tgt_res_cfg->ast_3_flow_mask_enable); 9847 9848 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9849 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9850 resource_cfg->msdu_flow_override_config1, 9851 tgt_res_cfg->ast_tid_high_mask_enable); 9852 9853 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9854 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9855 resource_cfg->msdu_flow_override_config1, 9856 tgt_res_cfg->ast_tid_low_mask_enable); 9857 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9858 resource_cfg->host_service_flags, 9859 tgt_res_cfg->nan_separate_iface_support); 9860 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9861 resource_cfg->host_service_flags, 1); 9862 9863 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9864 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9865 9866 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9867 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9868 resource_cfg->flags2, 1); 9869 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9870 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9871 resource_cfg->flags2, 1); 9872 9873 if (tgt_res_cfg->sae_eapol_offload) 9874 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9875 resource_cfg->host_service_flags, 1); 9876 9877 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9878 resource_cfg->host_service_flags, 9879 tgt_res_cfg->is_reg_cc_ext_event_supported); 9880 9881 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9882 resource_cfg->host_service_flags, 9883 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9884 9885 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9886 resource_cfg->host_service_flags, 9887 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9888 9889 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9890 resource_cfg->host_service_flags, 9891 tgt_res_cfg->afc_timer_check_disable); 9892 9893 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9894 resource_cfg->host_service_flags, 9895 tgt_res_cfg->afc_req_id_check_disable); 9896 9897 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9898 9899 wmi_set_nan_channel_support(resource_cfg); 9900 9901 if (tgt_res_cfg->twt_ack_support_cap) 9902 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9903 resource_cfg->host_service_flags, 1); 9904 9905 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9906 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9907 resource_cfg->host_service_flags, 1); 9908 /* 9909 * DP Peer Meta data FW version 9910 */ 9911 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET( 9912 resource_cfg->flags2, 9913 tgt_res_cfg->dp_peer_meta_data_ver); 9914 9915 if (tgt_res_cfg->notify_frame_support) 9916 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9917 resource_cfg->flags2, 1); 9918 9919 if (tgt_res_cfg->rf_path) 9920 WMI_RSRC_CFG_FLAGS2_RF_PATH_MODE_SET( 9921 resource_cfg->flags2, tgt_res_cfg->rf_path); 9922 9923 if (tgt_res_cfg->fw_ast_indication_disable) { 9924 WMI_RSRC_CFG_FLAGS2_DISABLE_WDS_PEER_MAP_UNMAP_EVENT_SET 9925 (resource_cfg->flags2, 9926 tgt_res_cfg->fw_ast_indication_disable); 9927 } 9928 9929 wmi_copy_latency_flowq_support(resource_cfg, tgt_res_cfg); 9930 wmi_copy_full_bw_nol_cfg(resource_cfg, tgt_res_cfg); 9931 9932 } 9933 9934 #ifdef FEATURE_SET 9935 /** 9936 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9937 * requirement2 version to target vendor1 requirement2 version 9938 * @vendor1_req2_ver: Host vendor1 requirement2 version 9939 * 9940 * Return: Target vendor1 requirement2 version 9941 */ 9942 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9943 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9944 { 9945 switch (vendor1_req2_ver) { 9946 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9947 return WMI_VENDOR1_REQ2_VERSION_3_00; 9948 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9949 return WMI_VENDOR1_REQ2_VERSION_3_01; 9950 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9951 return WMI_VENDOR1_REQ2_VERSION_3_20; 9952 case WMI_HOST_VENDOR1_REQ2_VERSION_3_50: 9953 return WMI_VENDOR1_REQ2_VERSION_3_50; 9954 default: 9955 return WMI_VENDOR1_REQ2_VERSION_3_00; 9956 } 9957 } 9958 9959 /** 9960 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9961 * requirement1 version to target vendor1 requirement1 version 9962 * @vendor1_req1_ver: Host vendor1 requirement1 version 9963 * 9964 * Return: Target vendor1 requirement1 version 9965 */ 9966 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9967 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9968 { 9969 switch (vendor1_req1_ver) { 9970 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9971 return WMI_VENDOR1_REQ1_VERSION_3_00; 9972 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9973 return WMI_VENDOR1_REQ1_VERSION_3_01; 9974 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9975 return WMI_VENDOR1_REQ1_VERSION_3_20; 9976 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9977 return WMI_VENDOR1_REQ1_VERSION_3_30; 9978 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9979 return WMI_VENDOR1_REQ1_VERSION_3_40; 9980 case WMI_HOST_VENDOR1_REQ1_VERSION_4_00: 9981 return WMI_VENDOR1_REQ1_VERSION_4_00; 9982 default: 9983 return WMI_VENDOR1_REQ1_VERSION_3_00; 9984 } 9985 } 9986 9987 /** 9988 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9989 * target wifi standard 9990 * @wifi_standard: Host wifi standard 9991 * 9992 * Return: Target wifi standard 9993 */ 9994 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9995 WMI_HOST_WIFI_STANDARD wifi_standard) 9996 { 9997 switch (wifi_standard) { 9998 case WMI_HOST_WIFI_STANDARD_4: 9999 return WMI_WIFI_STANDARD_4; 10000 case WMI_HOST_WIFI_STANDARD_5: 10001 return WMI_WIFI_STANDARD_5; 10002 case WMI_HOST_WIFI_STANDARD_6: 10003 return WMI_WIFI_STANDARD_6; 10004 case WMI_HOST_WIFI_STANDARD_6E: 10005 return WMI_WIFI_STANDARD_6E; 10006 case WMI_HOST_WIFI_STANDARD_7: 10007 return WMI_WIFI_STANDARD_7; 10008 default: 10009 return WMI_WIFI_STANDARD_4; 10010 } 10011 } 10012 10013 /** 10014 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 10015 * target band concurrency 10016 * @band_concurrency: Host Band concurrency 10017 * 10018 * Return: Target band concurrency 10019 */ 10020 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 10021 WMI_HOST_BAND_CONCURRENCY band_concurrency) 10022 { 10023 switch (band_concurrency) { 10024 case WMI_HOST_BAND_CONCURRENCY_DBS: 10025 return WMI_HOST_DBS; 10026 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 10027 return WMI_HOST_DBS_SBS; 10028 default: 10029 return WMI_HOST_NONE; 10030 } 10031 } 10032 10033 /** 10034 * convert_host_to_target_num_antennas() -Convert host num antennas to 10035 * target num antennas 10036 * @num_antennas: Host num antennas 10037 * 10038 * Return: Target num antennas 10039 */ 10040 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 10041 WMI_HOST_NUM_ANTENNAS num_antennas) 10042 { 10043 switch (num_antennas) { 10044 case WMI_HOST_SISO: 10045 return WMI_SISO; 10046 case WMI_HOST_MIMO_2X2: 10047 return WMI_MIMO_2X2; 10048 default: 10049 return WMI_SISO; 10050 } 10051 } 10052 10053 /** 10054 * convert_host_to_target_band_capability() -Convert host band capability to 10055 * target band capability 10056 * @host_band_capability: Host band capability 10057 * 10058 * Return: Target band capability bitmap 10059 */ 10060 static uint8_t 10061 convert_host_to_target_band_capability(uint32_t host_band_capability) 10062 { 10063 uint8_t band_capability; 10064 10065 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 10066 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 10067 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 10068 return band_capability; 10069 } 10070 10071 /** 10072 * copy_feature_set_info() -Copy feature set info from host to target 10073 * @feature_set_bitmap: Target feature set pointer 10074 * @feature_set: Host feature set structure 10075 * 10076 * Return: None 10077 */ 10078 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 10079 struct target_feature_set *feature_set) 10080 { 10081 WMI_NUM_ANTENNAS num_antennas; 10082 WMI_BAND_CONCURRENCY band_concurrency; 10083 WMI_WIFI_STANDARD wifi_standard; 10084 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 10085 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 10086 uint8_t band_capability; 10087 10088 num_antennas = convert_host_to_target_num_antennas( 10089 feature_set->num_antennas); 10090 band_concurrency = convert_host_to_target_band_concurrency( 10091 feature_set->concurrency_support); 10092 wifi_standard = convert_host_to_target_wifi_standard( 10093 feature_set->wifi_standard); 10094 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 10095 feature_set->vendor_req_1_version); 10096 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 10097 feature_set->vendor_req_2_version); 10098 10099 band_capability = 10100 convert_host_to_target_band_capability( 10101 feature_set->band_capability); 10102 10103 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 10104 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 10105 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 10106 feature_set->pno_in_unassoc_state); 10107 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 10108 feature_set->pno_in_assoc_state); 10109 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 10110 feature_set->enable_twt); 10111 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 10112 feature_set->enable_twt_requester); 10113 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 10114 feature_set->enable_twt_broadcast); 10115 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 10116 feature_set->enable_twt_flexible); 10117 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 10118 feature_set->enable_wifi_optimizer); 10119 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 10120 feature_set->enable_rfc835); 10121 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 10122 feature_set->sap_5g_supported); 10123 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 10124 feature_set->sap_6g_supported); 10125 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 10126 feature_set->sap_max_num_clients); 10127 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 10128 feature_set_bitmap, 10129 feature_set->set_country_code_hal_supported); 10130 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 10131 feature_set_bitmap, 10132 feature_set->get_valid_channel_supported); 10133 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 10134 feature_set->supported_dot11mode); 10135 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 10136 feature_set->sap_wpa3_support); 10137 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 10138 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 10139 feature_set_bitmap, 10140 feature_set->roaming_high_cu_roam_trigger); 10141 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 10142 feature_set_bitmap, 10143 feature_set->roaming_emergency_trigger); 10144 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 10145 feature_set->roaming_btm_trihgger); 10146 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 10147 feature_set->roaming_idle_trigger); 10148 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 10149 feature_set->roaming_wtc_trigger); 10150 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 10151 feature_set->roaming_btcoex_trigger); 10152 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 10153 feature_set->roaming_btw_wpa_wpa2); 10154 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 10155 feature_set_bitmap, 10156 feature_set->roaming_manage_chan_list_api); 10157 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 10158 feature_set->roaming_adaptive_11r); 10159 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 10160 feature_set->roaming_ctrl_api_get_set); 10161 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 10162 feature_set->roaming_ctrl_api_reassoc); 10163 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 10164 feature_set->roaming_ctrl_get_cu); 10165 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 10166 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 10167 feature_set_bitmap, 10168 feature_set->assurance_disconnect_reason_api); 10169 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 10170 feature_set->frame_pcap_log_mgmt); 10171 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 10172 feature_set->frame_pcap_log_ctrl); 10173 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 10174 feature_set->frame_pcap_log_data); 10175 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 10176 feature_set->security_wpa3_sae_h2e); 10177 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 10178 feature_set->security_wpa3_sae_ft); 10179 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 10180 feature_set_bitmap, 10181 feature_set->security_wpa3_enterp_suitb); 10182 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 10183 feature_set_bitmap, 10184 feature_set->security_wpa3_enterp_suitb_192bit); 10185 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 10186 feature_set->security_fills_sha_256); 10187 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 10188 feature_set->security_fills_sha_384); 10189 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 10190 feature_set->security_fills_sha_256_FT); 10191 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 10192 feature_set->security_fills_sha_384_FT); 10193 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 10194 feature_set->security_enhanced_open); 10195 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 10196 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 10197 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 10198 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 10199 feature_set->enable_tdls_offchannel); 10200 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 10201 feature_set->enable_tdls_capability_enhance); 10202 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 10203 feature_set->max_tdls_peers); 10204 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 10205 (feature_set->iface_combinations & 10206 MLME_IFACE_STA_DUAL_P2P_SUPPORT) > 0); 10207 WMI_SET_STA_P2P_SUPPORT(feature_set_bitmap, 10208 (feature_set->iface_combinations & 10209 MLME_IFACE_STA_P2P_SUPPORT) > 0); 10210 WMI_SET_STA_SAP_SUPPORT(feature_set_bitmap, 10211 (feature_set->iface_combinations & 10212 MLME_IFACE_STA_SAP_SUPPORT) > 0); 10213 WMI_SET_STA_NAN_SUPPORT(feature_set_bitmap, 10214 (feature_set->iface_combinations & 10215 MLME_IFACE_STA_NAN_SUPPORT) > 0); 10216 WMI_SET_STA_TDLS_SUPPORT(feature_set_bitmap, 10217 (feature_set->iface_combinations & 10218 MLME_IFACE_STA_TDLS_SUPPORT) > 0); 10219 WMI_SET_STA_SAP_P2P_SUPPORT(feature_set_bitmap, 10220 (feature_set->iface_combinations & 10221 MLME_IFACE_STA_SAP_P2P_SUPPORT) > 0); 10222 WMI_SET_STA_SAP_NAN_SUPPORT(feature_set_bitmap, 10223 (feature_set->iface_combinations & 10224 MLME_IFACE_STA_SAP_NAN_SUPPORT) > 0); 10225 WMI_SET_STA_P2P_NAN_SUPPORT(feature_set_bitmap, 10226 (feature_set->iface_combinations & 10227 MLME_IFACE_STA_P2P_NAN_SUPPORT) > 0); 10228 WMI_SET_STA_P2P_TDLS_SUPPORT(feature_set_bitmap, 10229 (feature_set->iface_combinations & 10230 MLME_IFACE_STA_P2P_TDLS_SUPPORT) > 0); 10231 WMI_SET_STA_SAP_TDLS_SUPPORT(feature_set_bitmap, 10232 (feature_set->iface_combinations & 10233 MLME_IFACE_STA_SAP_TDLS_SUPPORT) > 0); 10234 WMI_SET_STA_NAN_TDLS_SUPPORT(feature_set_bitmap, 10235 (feature_set->iface_combinations & 10236 MLME_IFACE_STA_NAN_TDLS_SUPPORT) > 0); 10237 WMI_SET_STA_SAP_P2P_TDLS_SUPPORT(feature_set_bitmap, 10238 (feature_set->iface_combinations & 10239 MLME_IFACE_STA_SAP_P2P_TDLS_SUPPORT) > 0); 10240 WMI_SET_STA_SAP_NAN_TDLS_SUPPORT(feature_set_bitmap, 10241 (feature_set->iface_combinations & 10242 MLME_IFACE_STA_SAP_NAN_TDLS_SUPPORT) > 0); 10243 WMI_SET_STA_P2P_P2P_TDLS_SUPPORT(feature_set_bitmap, 10244 (feature_set->iface_combinations & 10245 MLME_IFACE_STA_P2P_P2P_TDLS_SUPPORT) > 0); 10246 WMI_SET_STA_P2P_NAN_TDLS_SUPPORT(feature_set_bitmap, 10247 (feature_set->iface_combinations & 10248 MLME_IFACE_STA_P2P_NAN_TDLS_SUPPORT) > 0); 10249 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 10250 feature_set_bitmap, 10251 feature_set->peer_bigdata_getbssinfo_support); 10252 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 10253 feature_set_bitmap, 10254 feature_set->peer_bigdata_assocreject_info_support); 10255 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 10256 feature_set_bitmap, 10257 feature_set->peer_getstainfo_support); 10258 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 10259 feature_set->feature_set_version); 10260 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 10261 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 10262 WMI_SET_STA_DUMP_SUPPORT(feature_set_bitmap, 10263 feature_set->sta_dump_support); 10264 } 10265 10266 /** 10267 * feature_set_cmd_send_tlv() -Send feature set command 10268 * @wmi_handle: WMI handle 10269 * @feature_set: Feature set structure 10270 * 10271 * Return: QDF_STATUS_SUCCESS on success else return failure 10272 */ 10273 static QDF_STATUS feature_set_cmd_send_tlv( 10274 struct wmi_unified *wmi_handle, 10275 struct target_feature_set *feature_set) 10276 { 10277 wmi_pdev_featureset_cmd_fixed_param *cmd; 10278 wmi_buf_t buf; 10279 uint16_t len; 10280 QDF_STATUS ret; 10281 uint8_t *buf_ptr; 10282 uint32_t *feature_set_bitmap; 10283 10284 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10285 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 10286 buf = wmi_buf_alloc(wmi_handle, len); 10287 10288 if (!buf) 10289 return QDF_STATUS_E_NOMEM; 10290 10291 wmi_debug("Send feature set param"); 10292 10293 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10294 10295 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 10296 10297 WMITLV_SET_HDR(&cmd->tlv_header, 10298 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 10299 WMITLV_GET_STRUCT_TLVLEN( 10300 wmi_pdev_featureset_cmd_fixed_param)); 10301 10302 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 10303 WMI_TLV_HDR_SIZE); 10304 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 10305 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 10306 copy_feature_set_info(feature_set_bitmap, feature_set); 10307 10308 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10309 feature_set_bitmap, 10310 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 10311 sizeof(uint32_t)); 10312 10313 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 10314 10315 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10316 WMI_PDEV_FEATURESET_CMDID); 10317 if (QDF_IS_STATUS_ERROR(ret)) 10318 wmi_buf_free(buf); 10319 10320 return ret; 10321 } 10322 #endif 10323 10324 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 10325 * @wmi_handle: pointer to wmi handle 10326 * @buf_ptr: pointer to current position in init command buffer 10327 * @len: pointer to length. This will be updated with current length of cmd 10328 * @param: point host parameters for init command 10329 * 10330 * Return: Updated pointer of buf_ptr. 10331 */ 10332 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 10333 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 10334 { 10335 uint16_t idx; 10336 10337 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 10338 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 10339 wmi_pdev_band_to_mac *band_to_mac; 10340 10341 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 10342 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 10343 sizeof(wmi_resource_config) + 10344 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 10345 sizeof(wlan_host_memory_chunk))); 10346 10347 WMITLV_SET_HDR(&hw_mode->tlv_header, 10348 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 10349 (WMITLV_GET_STRUCT_TLVLEN 10350 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 10351 10352 hw_mode->hw_mode_index = param->hw_mode_id; 10353 hw_mode->num_band_to_mac = param->num_band_to_mac; 10354 10355 buf_ptr = (uint8_t *) (hw_mode + 1); 10356 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 10357 WMI_TLV_HDR_SIZE); 10358 for (idx = 0; idx < param->num_band_to_mac; idx++) { 10359 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 10360 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 10361 WMITLV_GET_STRUCT_TLVLEN 10362 (wmi_pdev_band_to_mac)); 10363 band_to_mac[idx].pdev_id = 10364 wmi_handle->ops->convert_pdev_id_host_to_target( 10365 wmi_handle, 10366 param->band_to_mac[idx].pdev_id); 10367 band_to_mac[idx].start_freq = 10368 param->band_to_mac[idx].start_freq; 10369 band_to_mac[idx].end_freq = 10370 param->band_to_mac[idx].end_freq; 10371 } 10372 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10373 (param->num_band_to_mac * 10374 sizeof(wmi_pdev_band_to_mac)) + 10375 WMI_TLV_HDR_SIZE; 10376 10377 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10378 (param->num_band_to_mac * 10379 sizeof(wmi_pdev_band_to_mac))); 10380 } 10381 10382 return buf_ptr; 10383 } 10384 10385 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 10386 wmi_init_cmd_fixed_param *cmd) 10387 { 10388 int num_allowlist; 10389 wmi_abi_version my_vers; 10390 10391 num_allowlist = sizeof(version_whitelist) / 10392 sizeof(wmi_whitelist_version_info); 10393 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 10394 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 10395 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 10396 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 10397 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 10398 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 10399 10400 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 10401 &my_vers, 10402 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 10403 &cmd->host_abi_vers); 10404 10405 qdf_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 10406 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 10407 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 10408 cmd->host_abi_vers.abi_version_ns_0, 10409 cmd->host_abi_vers.abi_version_ns_1, 10410 cmd->host_abi_vers.abi_version_ns_2, 10411 cmd->host_abi_vers.abi_version_ns_3); 10412 10413 /* Save version sent from host - 10414 * Will be used to check ready event 10415 */ 10416 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 10417 sizeof(wmi_abi_version)); 10418 } 10419 10420 /* 10421 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 10422 * @wmi_handle: Pointer to WMi handle 10423 * @ie_data: Pointer for ie data 10424 * 10425 * This function sends action frame tb ppdu cfg to FW 10426 * 10427 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10428 * 10429 */ 10430 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 10431 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 10432 { 10433 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 10434 wmi_buf_t buf; 10435 uint8_t *buf_ptr; 10436 uint32_t len, frm_len_aligned; 10437 QDF_STATUS ret; 10438 10439 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 10440 /* Allocate memory for the WMI command */ 10441 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 10442 10443 buf = wmi_buf_alloc(wmi_handle, len); 10444 if (!buf) 10445 return QDF_STATUS_E_NOMEM; 10446 10447 buf_ptr = wmi_buf_data(buf); 10448 qdf_mem_zero(buf_ptr, len); 10449 10450 /* Populate the WMI command */ 10451 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 10452 10453 WMITLV_SET_HDR(&cmd->tlv_header, 10454 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 10455 WMITLV_GET_STRUCT_TLVLEN( 10456 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 10457 cmd->enable = cfg_msg->cfg; 10458 cmd->data_len = cfg_msg->frm_len; 10459 10460 buf_ptr += sizeof(*cmd); 10461 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 10462 buf_ptr += WMI_TLV_HDR_SIZE; 10463 10464 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 10465 10466 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10467 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 10468 if (QDF_IS_STATUS_ERROR(ret)) { 10469 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 10470 wmi_buf_free(buf); 10471 } 10472 10473 return ret; 10474 } 10475 10476 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10477 { 10478 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10479 wmi_service_ready_event_fixed_param *ev; 10480 10481 10482 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10483 10484 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10485 if (!ev) 10486 return QDF_STATUS_E_FAILURE; 10487 10488 /*Save fw version from service ready message */ 10489 /*This will be used while sending INIT message */ 10490 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10491 sizeof(wmi_handle->fw_abi_version)); 10492 10493 return QDF_STATUS_SUCCESS; 10494 } 10495 10496 /** 10497 * check_and_update_fw_version_cmd_tlv() - save fw version 10498 * @wmi_handle: pointer to wmi handle 10499 * @evt_buf: pointer to the event buffer 10500 * 10501 * This function extracts and saves the firmware WMI ABI version 10502 * 10503 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10504 * 10505 */ 10506 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 10507 void *evt_buf) 10508 { 10509 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10510 wmi_ready_event_fixed_param *ev = NULL; 10511 10512 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10513 ev = param_buf->fixed_param; 10514 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 10515 &wmi_handle->final_abi_vers, 10516 &ev->fw_abi_vers)) { 10517 /* 10518 * Error: Our host version and the given firmware version 10519 * are incompatible. 10520 **/ 10521 wmi_debug("Error: Incompatible WMI version." 10522 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 10523 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 10524 abi_version_0), 10525 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 10526 abi_version_0), 10527 wmi_handle->final_abi_vers.abi_version_ns_0, 10528 wmi_handle->final_abi_vers.abi_version_ns_1, 10529 wmi_handle->final_abi_vers.abi_version_ns_2, 10530 wmi_handle->final_abi_vers.abi_version_ns_3, 10531 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 10532 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 10533 ev->fw_abi_vers.abi_version_ns_0, 10534 ev->fw_abi_vers.abi_version_ns_1, 10535 ev->fw_abi_vers.abi_version_ns_2, 10536 ev->fw_abi_vers.abi_version_ns_3); 10537 10538 return QDF_STATUS_E_FAILURE; 10539 } 10540 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 10541 sizeof(wmi_abi_version)); 10542 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10543 sizeof(wmi_abi_version)); 10544 10545 return QDF_STATUS_SUCCESS; 10546 } 10547 10548 /** 10549 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 10550 * @wmi_handle: wmi handle 10551 * @event: Event received from FW 10552 * @len: Length of the event 10553 * 10554 * Enables the low frequency events and disables the high frequency 10555 * events. Bit 17 indicates if the event if low/high frequency. 10556 * 1 - high frequency, 0 - low frequency 10557 * 10558 * Return: QDF_STATUS_SUCCESS for success or error code 10559 */ 10560 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 10561 uint8_t *event, 10562 uint32_t len) 10563 { 10564 uint32_t num_of_diag_events_logs; 10565 wmi_diag_event_log_config_fixed_param *cmd; 10566 wmi_buf_t buf; 10567 uint8_t *buf_ptr; 10568 uint32_t *cmd_args, *evt_args; 10569 uint32_t buf_len, i; 10570 10571 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 10572 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 10573 10574 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 10575 10576 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 10577 if (!param_buf) { 10578 wmi_err("Invalid log supported event buffer"); 10579 return QDF_STATUS_E_INVAL; 10580 } 10581 wmi_event = param_buf->fixed_param; 10582 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 10583 10584 if (num_of_diag_events_logs > 10585 param_buf->num_diag_events_logs_list) { 10586 wmi_err("message number of events %d is more than tlv hdr content %d", 10587 num_of_diag_events_logs, 10588 param_buf->num_diag_events_logs_list); 10589 return QDF_STATUS_E_INVAL; 10590 } 10591 10592 evt_args = param_buf->diag_events_logs_list; 10593 if (!evt_args) { 10594 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 10595 num_of_diag_events_logs); 10596 return QDF_STATUS_E_INVAL; 10597 } 10598 10599 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 10600 10601 /* Free any previous allocation */ 10602 if (wmi_handle->events_logs_list) { 10603 qdf_mem_free(wmi_handle->events_logs_list); 10604 wmi_handle->events_logs_list = NULL; 10605 } 10606 10607 if (num_of_diag_events_logs > 10608 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 10609 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 10610 QDF_ASSERT(0); 10611 return QDF_STATUS_E_INVAL; 10612 } 10613 /* Store the event list for run time enable/disable */ 10614 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 10615 sizeof(uint32_t)); 10616 if (!wmi_handle->events_logs_list) 10617 return QDF_STATUS_E_NOMEM; 10618 10619 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 10620 10621 /* Prepare the send buffer */ 10622 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10623 (num_of_diag_events_logs * sizeof(uint32_t)); 10624 10625 buf = wmi_buf_alloc(wmi_handle, buf_len); 10626 if (!buf) { 10627 qdf_mem_free(wmi_handle->events_logs_list); 10628 wmi_handle->events_logs_list = NULL; 10629 return QDF_STATUS_E_NOMEM; 10630 } 10631 10632 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10633 buf_ptr = (uint8_t *) cmd; 10634 10635 WMITLV_SET_HDR(&cmd->tlv_header, 10636 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10637 WMITLV_GET_STRUCT_TLVLEN( 10638 wmi_diag_event_log_config_fixed_param)); 10639 10640 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 10641 10642 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10643 10644 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10645 (num_of_diag_events_logs * sizeof(uint32_t))); 10646 10647 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10648 10649 /* Populate the events */ 10650 for (i = 0; i < num_of_diag_events_logs; i++) { 10651 /* Low freq (0) - Enable (1) the event 10652 * High freq (1) - Disable (0) the event 10653 */ 10654 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 10655 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 10656 /* Set the event ID */ 10657 WMI_DIAG_ID_SET(cmd_args[i], 10658 WMI_DIAG_ID_GET(evt_args[i])); 10659 /* Set the type */ 10660 WMI_DIAG_TYPE_SET(cmd_args[i], 10661 WMI_DIAG_TYPE_GET(evt_args[i])); 10662 /* Storing the event/log list in WMI */ 10663 wmi_handle->events_logs_list[i] = evt_args[i]; 10664 } 10665 10666 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10667 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 10668 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10669 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10670 wmi_buf_free(buf); 10671 /* Not clearing events_logs_list, though wmi cmd failed. 10672 * Host can still have this list 10673 */ 10674 return QDF_STATUS_E_INVAL; 10675 } 10676 10677 return 0; 10678 } 10679 10680 /** 10681 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 10682 * @wmi_handle: wmi handle 10683 * @start_log: Start logging related parameters 10684 * 10685 * Send the command to the FW based on which specific logging of diag 10686 * event/log id can be started/stopped 10687 * 10688 * Return: None 10689 */ 10690 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 10691 struct wmi_wifi_start_log *start_log) 10692 { 10693 wmi_diag_event_log_config_fixed_param *cmd; 10694 wmi_buf_t buf; 10695 uint8_t *buf_ptr; 10696 uint32_t len, count, log_level, i; 10697 uint32_t *cmd_args; 10698 uint32_t total_len; 10699 count = 0; 10700 10701 if (!wmi_handle->events_logs_list) { 10702 wmi_debug("Not received event/log list from FW, yet"); 10703 return QDF_STATUS_E_NOMEM; 10704 } 10705 /* total_len stores the number of events where BITS 17 and 18 are set. 10706 * i.e., events of high frequency (17) and for extended debugging (18) 10707 */ 10708 total_len = 0; 10709 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10710 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10711 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10712 total_len++; 10713 } 10714 10715 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10716 (total_len * sizeof(uint32_t)); 10717 10718 buf = wmi_buf_alloc(wmi_handle, len); 10719 if (!buf) 10720 return QDF_STATUS_E_NOMEM; 10721 10722 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10723 buf_ptr = (uint8_t *) cmd; 10724 10725 WMITLV_SET_HDR(&cmd->tlv_header, 10726 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10727 WMITLV_GET_STRUCT_TLVLEN( 10728 wmi_diag_event_log_config_fixed_param)); 10729 10730 cmd->num_of_diag_events_logs = total_len; 10731 10732 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10733 10734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10735 (total_len * sizeof(uint32_t))); 10736 10737 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10738 10739 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10740 log_level = 1; 10741 else 10742 log_level = 0; 10743 10744 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10745 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10746 uint32_t val = wmi_handle->events_logs_list[i]; 10747 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10748 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10749 10750 WMI_DIAG_ID_SET(cmd_args[count], 10751 WMI_DIAG_ID_GET(val)); 10752 WMI_DIAG_TYPE_SET(cmd_args[count], 10753 WMI_DIAG_TYPE_GET(val)); 10754 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10755 log_level); 10756 wmi_debug("Idx:%d, val:%x", i, val); 10757 count++; 10758 } 10759 } 10760 10761 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10762 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10763 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10764 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10765 wmi_buf_free(buf); 10766 return QDF_STATUS_E_INVAL; 10767 } 10768 10769 return QDF_STATUS_SUCCESS; 10770 } 10771 10772 /** 10773 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10774 * @wmi_handle: WMI handle 10775 * 10776 * This function is used to send the flush command to the FW, 10777 * that will flush the fw logs that are residue in the FW 10778 * 10779 * Return: None 10780 */ 10781 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10782 { 10783 wmi_debug_mesg_flush_fixed_param *cmd; 10784 wmi_buf_t buf; 10785 int len = sizeof(*cmd); 10786 QDF_STATUS ret; 10787 10788 buf = wmi_buf_alloc(wmi_handle, len); 10789 if (!buf) 10790 return QDF_STATUS_E_NOMEM; 10791 10792 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10793 WMITLV_SET_HDR(&cmd->tlv_header, 10794 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10795 WMITLV_GET_STRUCT_TLVLEN( 10796 wmi_debug_mesg_flush_fixed_param)); 10797 cmd->reserved0 = 0; 10798 10799 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10800 ret = wmi_unified_cmd_send(wmi_handle, 10801 buf, 10802 len, 10803 WMI_DEBUG_MESG_FLUSH_CMDID); 10804 if (QDF_IS_STATUS_ERROR(ret)) { 10805 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10806 wmi_buf_free(buf); 10807 return QDF_STATUS_E_INVAL; 10808 } 10809 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10810 10811 return ret; 10812 } 10813 10814 #ifdef BIG_ENDIAN_HOST 10815 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10816 /** 10817 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10818 * @wmi_handle: wmi handle 10819 * @param: fips extend param related parameters 10820 * 10821 * Return: QDF_STATUS - success or error status 10822 */ 10823 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10824 struct fips_extend_params *param) 10825 { 10826 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10827 int c; 10828 u_int8_t *key_aligned = NULL; 10829 u_int8_t *nonce_iv_aligned = NULL; 10830 u_int8_t *data_aligned = NULL; 10831 int ret = QDF_STATUS_SUCCESS; 10832 10833 /* Assigning unaligned space to copy the key */ 10834 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10835 param->cmd_params.key_len + FIPS_ALIGN); 10836 /* Checking if kmalloc is successful to allocate space */ 10837 if (!key_unaligned) 10838 return QDF_STATUS_E_INVAL; 10839 10840 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10841 FIPS_ALIGN); 10842 /* Checking if kmalloc is successful to allocate space */ 10843 if (!data_unaligned) { 10844 ret = QDF_STATUS_E_INVAL; 10845 goto fips_align_fail_data; 10846 } 10847 10848 /* Checking if space is aligned */ 10849 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10850 /* align to 4 */ 10851 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10852 FIPS_ALIGN); 10853 } else { 10854 key_aligned = (u_int8_t *)key_unaligned; 10855 } 10856 10857 /* memset and copy content from key to key aligned */ 10858 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10859 OS_MEMCPY(key_aligned, param->cmd_params.key, 10860 param->cmd_params.key_len); 10861 10862 /* print a hexdump for host debug */ 10863 wmi_debug("Aligned and Copied Key: "); 10864 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10865 key_aligned, param->cmd_params.key_len); 10866 10867 /* Checking of space is aligned */ 10868 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10869 /* align to 4 */ 10870 data_aligned = 10871 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10872 } else { 10873 data_aligned = (u_int8_t *)data_unaligned; 10874 } 10875 10876 /* memset and copy content from data to data aligned */ 10877 OS_MEMSET(data_aligned, 0, param->data_len); 10878 OS_MEMCPY(data_aligned, param->data, param->data_len); 10879 10880 /* print a hexdump for host debug */ 10881 wmi_debug("\t Properly Aligned and Copied Data: "); 10882 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10883 data_aligned, param->data_len); 10884 10885 /* converting to little Endian */ 10886 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10887 *((u_int32_t *)key_aligned + c) = 10888 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10889 } 10890 for (c = 0; c < param->data_len / 4; c++) { 10891 *((u_int32_t *)data_aligned + c) = 10892 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10893 } 10894 10895 /* update endian data */ 10896 OS_MEMCPY(param->cmd_params.key, key_aligned, 10897 param->cmd_params.key_len); 10898 OS_MEMCPY(param->data, data_aligned, param->data_len); 10899 10900 if (param->cmd_params.nonce_iv_len) { 10901 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10902 param->cmd_params.nonce_iv_len + 10903 FIPS_ALIGN); 10904 10905 /* Checking if kmalloc is successful to allocate space */ 10906 if (!nonce_iv_unaligned) { 10907 ret = QDF_STATUS_E_INVAL; 10908 goto fips_align_fail_nonce_iv; 10909 } 10910 /* Checking if space is aligned */ 10911 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10912 /* align to 4 */ 10913 nonce_iv_aligned = 10914 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10915 FIPS_ALIGN); 10916 } else { 10917 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10918 } 10919 10920 /* memset and copy content from iv to iv aligned */ 10921 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10922 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10923 param->cmd_params.nonce_iv_len); 10924 10925 /* print a hexdump for host debug */ 10926 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10927 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10928 nonce_iv_aligned, 10929 param->cmd_params.nonce_iv_len); 10930 10931 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10932 *((u_int32_t *)nonce_iv_aligned + c) = 10933 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10934 } 10935 } 10936 10937 /* clean up allocated spaces */ 10938 qdf_mem_free(nonce_iv_unaligned); 10939 nonce_iv_unaligned = NULL; 10940 nonce_iv_aligned = NULL; 10941 10942 fips_align_fail_nonce_iv: 10943 qdf_mem_free(data_unaligned); 10944 data_unaligned = NULL; 10945 data_aligned = NULL; 10946 10947 fips_align_fail_data: 10948 qdf_mem_free(key_unaligned); 10949 key_unaligned = NULL; 10950 key_aligned = NULL; 10951 10952 return ret; 10953 } 10954 #endif 10955 10956 /** 10957 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10958 * @wmi_handle: wmi handle 10959 * @param: fips param related parameters 10960 * 10961 * Return: QDF_STATUS - success or error status 10962 */ 10963 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10964 struct fips_params *param) 10965 { 10966 unsigned char *key_unaligned, *data_unaligned; 10967 int c; 10968 u_int8_t *key_aligned = NULL; 10969 u_int8_t *data_aligned = NULL; 10970 10971 /* Assigning unaligned space to copy the key */ 10972 key_unaligned = qdf_mem_malloc( 10973 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10974 data_unaligned = qdf_mem_malloc( 10975 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10976 10977 /* Checking if kmalloc is successful to allocate space */ 10978 if (!key_unaligned) 10979 return QDF_STATUS_SUCCESS; 10980 /* Checking if space is aligned */ 10981 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10982 /* align to 4 */ 10983 key_aligned = 10984 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10985 FIPS_ALIGN); 10986 } else { 10987 key_aligned = (u_int8_t *)key_unaligned; 10988 } 10989 10990 /* memset and copy content from key to key aligned */ 10991 OS_MEMSET(key_aligned, 0, param->key_len); 10992 OS_MEMCPY(key_aligned, param->key, param->key_len); 10993 10994 /* print a hexdump for host debug */ 10995 print_hex_dump(KERN_DEBUG, 10996 "\t Aligned and Copied Key:@@@@ ", 10997 DUMP_PREFIX_NONE, 10998 16, 1, key_aligned, param->key_len, true); 10999 11000 /* Checking if kmalloc is successful to allocate space */ 11001 if (!data_unaligned) 11002 return QDF_STATUS_SUCCESS; 11003 /* Checking of space is aligned */ 11004 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 11005 /* align to 4 */ 11006 data_aligned = 11007 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 11008 FIPS_ALIGN); 11009 } else { 11010 data_aligned = (u_int8_t *)data_unaligned; 11011 } 11012 11013 /* memset and copy content from data to data aligned */ 11014 OS_MEMSET(data_aligned, 0, param->data_len); 11015 OS_MEMCPY(data_aligned, param->data, param->data_len); 11016 11017 /* print a hexdump for host debug */ 11018 print_hex_dump(KERN_DEBUG, 11019 "\t Properly Aligned and Copied Data:@@@@ ", 11020 DUMP_PREFIX_NONE, 11021 16, 1, data_aligned, param->data_len, true); 11022 11023 /* converting to little Endian both key_aligned and 11024 * data_aligned*/ 11025 for (c = 0; c < param->key_len/4; c++) { 11026 *((u_int32_t *)key_aligned+c) = 11027 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 11028 } 11029 for (c = 0; c < param->data_len/4; c++) { 11030 *((u_int32_t *)data_aligned+c) = 11031 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 11032 } 11033 11034 /* update endian data to key and data vectors */ 11035 OS_MEMCPY(param->key, key_aligned, param->key_len); 11036 OS_MEMCPY(param->data, data_aligned, param->data_len); 11037 11038 /* clean up allocated spaces */ 11039 qdf_mem_free(key_unaligned); 11040 key_unaligned = NULL; 11041 key_aligned = NULL; 11042 11043 qdf_mem_free(data_unaligned); 11044 data_unaligned = NULL; 11045 data_aligned = NULL; 11046 11047 return QDF_STATUS_SUCCESS; 11048 } 11049 #else 11050 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 11051 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 11052 struct fips_extend_params *param) 11053 { 11054 return QDF_STATUS_SUCCESS; 11055 } 11056 #endif 11057 11058 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 11059 struct fips_params *param) 11060 { 11061 return QDF_STATUS_SUCCESS; 11062 } 11063 #endif 11064 11065 #ifdef WLAN_FEATURE_DISA 11066 /** 11067 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 11068 * @wmi_handle: wmi handle 11069 * @encrypt_decrypt_params: encrypt/decrypt params 11070 * 11071 * Return: QDF_STATUS_SUCCESS for success or error code 11072 */ 11073 static QDF_STATUS 11074 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 11075 struct disa_encrypt_decrypt_req_params 11076 *encrypt_decrypt_params) 11077 { 11078 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 11079 wmi_buf_t wmi_buf; 11080 uint8_t *buf_ptr; 11081 QDF_STATUS ret; 11082 uint32_t len; 11083 11084 wmi_debug("Send encrypt decrypt cmd"); 11085 11086 len = sizeof(*cmd) + 11087 encrypt_decrypt_params->data_len + 11088 WMI_TLV_HDR_SIZE; 11089 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11090 if (!wmi_buf) 11091 return QDF_STATUS_E_NOMEM; 11092 11093 buf_ptr = wmi_buf_data(wmi_buf); 11094 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 11095 11096 WMITLV_SET_HDR(&cmd->tlv_header, 11097 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 11098 WMITLV_GET_STRUCT_TLVLEN( 11099 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 11100 11101 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 11102 cmd->key_flag = encrypt_decrypt_params->key_flag; 11103 cmd->key_idx = encrypt_decrypt_params->key_idx; 11104 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 11105 cmd->key_len = encrypt_decrypt_params->key_len; 11106 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 11107 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 11108 11109 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 11110 encrypt_decrypt_params->key_len); 11111 11112 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 11113 MAX_MAC_HEADER_LEN); 11114 11115 cmd->data_len = encrypt_decrypt_params->data_len; 11116 11117 if (cmd->data_len) { 11118 buf_ptr += sizeof(*cmd); 11119 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11120 roundup(encrypt_decrypt_params->data_len, 11121 sizeof(uint32_t))); 11122 buf_ptr += WMI_TLV_HDR_SIZE; 11123 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 11124 encrypt_decrypt_params->data_len); 11125 } 11126 11127 /* This conversion is to facilitate data to FW in little endian */ 11128 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 11129 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 11130 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 11131 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 11132 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 11133 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 11134 11135 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 11136 ret = wmi_unified_cmd_send(wmi_handle, 11137 wmi_buf, len, 11138 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 11139 if (QDF_IS_STATUS_ERROR(ret)) { 11140 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 11141 wmi_buf_free(wmi_buf); 11142 } 11143 11144 return ret; 11145 } 11146 #endif /* WLAN_FEATURE_DISA */ 11147 11148 /** 11149 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 11150 * @wmi_handle: wmi handle 11151 * @param: pointer to hold pdev fips param 11152 * 11153 * Return: QDF_STATUS_SUCCESS for success or error code 11154 */ 11155 static QDF_STATUS 11156 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 11157 struct fips_params *param) 11158 { 11159 wmi_pdev_fips_cmd_fixed_param *cmd; 11160 wmi_buf_t buf; 11161 uint8_t *buf_ptr; 11162 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 11163 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11164 11165 /* Length TLV placeholder for array of bytes */ 11166 len += WMI_TLV_HDR_SIZE; 11167 if (param->data_len) 11168 len += (param->data_len*sizeof(uint8_t)); 11169 11170 /* 11171 * Data length must be multiples of 16 bytes - checked against 0xF - 11172 * and must be less than WMI_SVC_MSG_SIZE - static size of 11173 * wmi_pdev_fips_cmd structure 11174 */ 11175 11176 /* do sanity on the input */ 11177 if (!(((param->data_len & 0xF) == 0) && 11178 ((param->data_len > 0) && 11179 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 11180 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 11181 return QDF_STATUS_E_INVAL; 11182 } 11183 11184 buf = wmi_buf_alloc(wmi_handle, len); 11185 if (!buf) 11186 return QDF_STATUS_E_FAILURE; 11187 11188 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11189 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 11190 WMITLV_SET_HDR(&cmd->tlv_header, 11191 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 11192 WMITLV_GET_STRUCT_TLVLEN 11193 (wmi_pdev_fips_cmd_fixed_param)); 11194 11195 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11196 wmi_handle, 11197 param->pdev_id); 11198 if (param->key && param->data) { 11199 cmd->key_len = param->key_len; 11200 cmd->data_len = param->data_len; 11201 cmd->fips_cmd = !!(param->op); 11202 11203 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 11204 return QDF_STATUS_E_FAILURE; 11205 11206 qdf_mem_copy(cmd->key, param->key, param->key_len); 11207 11208 if (param->mode == FIPS_ENGINE_AES_CTR || 11209 param->mode == FIPS_ENGINE_AES_MIC) { 11210 cmd->mode = param->mode; 11211 } else { 11212 cmd->mode = FIPS_ENGINE_AES_CTR; 11213 } 11214 11215 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 11216 cmd->key, cmd->key_len, true); 11217 buf_ptr += sizeof(*cmd); 11218 11219 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 11220 11221 buf_ptr += WMI_TLV_HDR_SIZE; 11222 if (param->data_len) 11223 qdf_mem_copy(buf_ptr, 11224 (uint8_t *) param->data, param->data_len); 11225 11226 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 11227 16, 1, buf_ptr, cmd->data_len, true); 11228 11229 buf_ptr += param->data_len; 11230 11231 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 11232 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11233 WMI_PDEV_FIPS_CMDID); 11234 } else { 11235 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 11236 wmi_buf_free(buf); 11237 retval = -QDF_STATUS_E_BADMSG; 11238 } 11239 11240 return retval; 11241 } 11242 11243 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 11244 /** 11245 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 11246 * @wmi_handle: wmi handle 11247 * @param: pointer to hold pdev fips param 11248 * 11249 * Return: QDF_STATUS_SUCCESS for success or error code 11250 */ 11251 static QDF_STATUS 11252 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 11253 struct fips_extend_params *param) 11254 { 11255 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 11256 wmi_buf_t buf; 11257 uint8_t *buf_ptr; 11258 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 11259 uint32_t data_len_aligned; 11260 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11261 11262 len += WMI_TLV_HDR_SIZE; 11263 if (param->frag_idx == 0) 11264 len += sizeof(wmi_fips_extend_cmd_init_params); 11265 11266 /* Length TLV placeholder for array of bytes */ 11267 len += WMI_TLV_HDR_SIZE; 11268 if (param->data_len) { 11269 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 11270 len += (data_len_aligned * sizeof(uint8_t)); 11271 } 11272 11273 buf = wmi_buf_alloc(wmi_handle, len); 11274 if (!buf) 11275 return QDF_STATUS_E_FAILURE; 11276 11277 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11278 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 11279 WMITLV_SET_HDR(&cmd->tlv_header, 11280 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 11281 WMITLV_GET_STRUCT_TLVLEN 11282 (wmi_pdev_fips_extend_cmd_fixed_param)); 11283 11284 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11285 wmi_handle, 11286 param->pdev_id); 11287 11288 cmd->fips_cookie = param->cookie; 11289 cmd->frag_idx = param->frag_idx; 11290 cmd->more_bit = param->more_bit; 11291 cmd->data_len = param->data_len; 11292 11293 if (fips_extend_align_data_be(wmi_handle, param) != 11294 QDF_STATUS_SUCCESS) { 11295 wmi_buf_free(buf); 11296 return QDF_STATUS_E_FAILURE; 11297 } 11298 11299 buf_ptr = (uint8_t *)(cmd + 1); 11300 if (cmd->frag_idx == 0) { 11301 wmi_fips_extend_cmd_init_params *cmd_params; 11302 11303 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11304 sizeof(wmi_fips_extend_cmd_init_params)); 11305 buf_ptr += WMI_TLV_HDR_SIZE; 11306 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 11307 WMITLV_SET_HDR(buf_ptr, 11308 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 11309 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 11310 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 11311 cmd_params->key_cipher = param->cmd_params.key_cipher; 11312 cmd_params->key_len = param->cmd_params.key_len; 11313 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 11314 cmd_params->tag_len = param->cmd_params.tag_len; 11315 cmd_params->aad_len = param->cmd_params.aad_len; 11316 cmd_params->payload_len = param->cmd_params.payload_len; 11317 11318 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 11319 param->cmd_params.key_len); 11320 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 11321 param->cmd_params.nonce_iv_len); 11322 11323 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 11324 cmd_params->key_len, cmd_params->nonce_iv_len, 11325 cmd_params->tag_len, cmd_params->aad_len, 11326 cmd_params->payload_len); 11327 11328 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 11329 } else { 11330 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11331 buf_ptr += WMI_TLV_HDR_SIZE; 11332 } 11333 11334 if (param->data_len && param->data) { 11335 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11336 data_len_aligned); 11337 11338 buf_ptr += WMI_TLV_HDR_SIZE; 11339 if (param->data_len) 11340 qdf_mem_copy(buf_ptr, 11341 (uint8_t *)param->data, param->data_len); 11342 11343 wmi_debug("Data: "); 11344 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 11345 buf_ptr, cmd->data_len); 11346 11347 if (param->data_len) 11348 buf_ptr += param->data_len; 11349 } else { 11350 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 11351 buf_ptr += WMI_TLV_HDR_SIZE; 11352 } 11353 11354 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 11355 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11356 WMI_PDEV_FIPS_EXTEND_CMDID); 11357 11358 if (retval) { 11359 wmi_err("Failed to send FIPS cmd"); 11360 wmi_buf_free(buf); 11361 } 11362 11363 return retval; 11364 } 11365 11366 /** 11367 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 11368 * @wmi_handle: wmi handle 11369 * @param: pointer to hold pdev fips param 11370 * 11371 * Return: QDF_STATUS_SUCCESS for success or error code 11372 */ 11373 static QDF_STATUS 11374 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 11375 struct fips_mode_set_params *param) 11376 { 11377 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 11378 wmi_buf_t buf; 11379 uint8_t *buf_ptr; 11380 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 11381 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11382 11383 buf = wmi_buf_alloc(wmi_handle, len); 11384 if (!buf) 11385 return QDF_STATUS_E_FAILURE; 11386 11387 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11388 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 11389 WMITLV_SET_HDR(&cmd->tlv_header, 11390 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 11391 WMITLV_GET_STRUCT_TLVLEN 11392 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 11393 11394 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11395 wmi_handle, 11396 param->pdev_id); 11397 11398 cmd->fips_mode_set = param->mode; 11399 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 11400 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11401 WMI_PDEV_FIPS_MODE_SET_CMDID); 11402 if (retval) { 11403 wmi_err("Failed to send FIPS mode enable cmd"); 11404 wmi_buf_free(buf); 11405 } 11406 return retval; 11407 } 11408 #endif 11409 11410 /** 11411 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 11412 * to fw 11413 * @wmi_handle: wmi handle 11414 * @param: pointer to wlan profile param 11415 * 11416 * Return: QDF_STATUS_SUCCESS for success or error code 11417 */ 11418 static QDF_STATUS 11419 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 11420 struct wlan_profile_params *param) 11421 { 11422 wmi_buf_t buf; 11423 uint16_t len; 11424 QDF_STATUS ret; 11425 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 11426 11427 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 11428 buf = wmi_buf_alloc(wmi_handle, len); 11429 if (!buf) { 11430 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 11431 return QDF_STATUS_E_NOMEM; 11432 } 11433 11434 profile_enable_cmd = 11435 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 11436 wmi_buf_data(buf); 11437 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 11438 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 11439 WMITLV_GET_STRUCT_TLVLEN 11440 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 11441 11442 profile_enable_cmd->profile_id = param->profile_id; 11443 profile_enable_cmd->enable = param->enable; 11444 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 11445 NO_SESSION, 0); 11446 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11447 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 11448 if (ret) { 11449 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 11450 wmi_buf_free(buf); 11451 } 11452 return ret; 11453 } 11454 11455 /** 11456 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 11457 * to fw 11458 * @wmi_handle: wmi handle 11459 * @param: pointer to wlan profile param 11460 * 11461 * Return: QDF_STATUS_SUCCESS for success or error code 11462 */ 11463 static QDF_STATUS 11464 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 11465 struct wlan_profile_params *param) 11466 { 11467 wmi_buf_t buf; 11468 uint16_t len; 11469 QDF_STATUS ret; 11470 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 11471 11472 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 11473 buf = wmi_buf_alloc(wmi_handle, len); 11474 if (!buf) { 11475 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11476 return QDF_STATUS_E_NOMEM; 11477 } 11478 11479 prof_trig_cmd = 11480 (wmi_wlan_profile_trigger_cmd_fixed_param *) 11481 wmi_buf_data(buf); 11482 11483 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 11484 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 11485 WMITLV_GET_STRUCT_TLVLEN 11486 (wmi_wlan_profile_trigger_cmd_fixed_param)); 11487 11488 prof_trig_cmd->enable = param->enable; 11489 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 11490 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11491 WMI_WLAN_PROFILE_TRIGGER_CMDID); 11492 if (ret) { 11493 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11494 wmi_buf_free(buf); 11495 } 11496 return ret; 11497 } 11498 11499 /** 11500 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 11501 * to fw 11502 * @wmi_handle: wmi handle 11503 * @param: pointer to wlan profile param 11504 * 11505 * Return: QDF_STATUS_SUCCESS for success or error code 11506 */ 11507 static QDF_STATUS 11508 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 11509 struct wlan_profile_params *param) 11510 { 11511 wmi_buf_t buf; 11512 int32_t len = 0; 11513 QDF_STATUS ret; 11514 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 11515 11516 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 11517 buf = wmi_buf_alloc(wmi_handle, len); 11518 if (!buf) { 11519 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 11520 return QDF_STATUS_E_NOMEM; 11521 } 11522 11523 hist_intvl_cmd = 11524 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 11525 wmi_buf_data(buf); 11526 11527 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 11528 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 11529 WMITLV_GET_STRUCT_TLVLEN 11530 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 11531 11532 hist_intvl_cmd->profile_id = param->profile_id; 11533 hist_intvl_cmd->value = param->enable; 11534 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 11535 NO_SESSION, 0); 11536 11537 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11538 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 11539 if (ret) { 11540 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 11541 wmi_buf_free(buf); 11542 } 11543 return ret; 11544 } 11545 11546 /** 11547 * send_fw_test_cmd_tlv() - send fw test command to fw. 11548 * @wmi_handle: wmi handle 11549 * @wmi_fwtest: fw test command 11550 * 11551 * This function sends fw test command to fw. 11552 * 11553 * Return: CDF STATUS 11554 */ 11555 static 11556 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 11557 struct set_fwtest_params *wmi_fwtest) 11558 { 11559 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11560 wmi_buf_t wmi_buf; 11561 uint16_t len; 11562 11563 len = sizeof(*cmd); 11564 11565 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11566 if (!wmi_buf) 11567 return QDF_STATUS_E_NOMEM; 11568 11569 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11570 WMITLV_SET_HDR(&cmd->tlv_header, 11571 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11572 WMITLV_GET_STRUCT_TLVLEN( 11573 wmi_fwtest_set_param_cmd_fixed_param)); 11574 cmd->param_id = wmi_fwtest->arg; 11575 cmd->param_value = wmi_fwtest->value; 11576 11577 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 11578 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11579 WMI_FWTEST_CMDID)) { 11580 wmi_err("Failed to send fw test command"); 11581 wmi_buf_free(wmi_buf); 11582 return QDF_STATUS_E_FAILURE; 11583 } 11584 11585 return QDF_STATUS_SUCCESS; 11586 } 11587 11588 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 11589 { 11590 uint16_t len = 0; 11591 11592 if (config == WFA_CONFIG_RXNE) 11593 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 11594 else 11595 len += WMI_TLV_HDR_SIZE; 11596 11597 if (config == WFA_CONFIG_CSA) 11598 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 11599 else 11600 len += WMI_TLV_HDR_SIZE; 11601 11602 if (config == WFA_CONFIG_OCV) 11603 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 11604 else 11605 len += WMI_TLV_HDR_SIZE; 11606 11607 if (config == WFA_CONFIG_SA_QUERY) 11608 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 11609 else 11610 len += WMI_TLV_HDR_SIZE; 11611 11612 return len; 11613 } 11614 11615 /** 11616 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 11617 * @host_frmtype: Host defined OCV frame type 11618 * @ocv_frmtype: Pointer to hold WMI OCV frame type 11619 * 11620 * This function converts and fills host defined OCV frame type into WMI OCV 11621 * frame type. 11622 * 11623 * Return: CDF STATUS 11624 */ 11625 static QDF_STATUS 11626 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 11627 { 11628 switch (host_frmtype) { 11629 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 11630 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 11631 break; 11632 11633 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 11634 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 11635 break; 11636 11637 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 11638 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 11639 break; 11640 11641 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 11642 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 11643 break; 11644 11645 default: 11646 wmi_err("Invalid command type cmd %d", host_frmtype); 11647 return QDF_STATUS_E_FAILURE; 11648 } 11649 11650 return QDF_STATUS_SUCCESS; 11651 } 11652 11653 /** 11654 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 11655 * @wmi_handle: wmi handle 11656 * @wmi_wfatest: wfa test command 11657 * 11658 * This function sends wfa test command to fw. 11659 * 11660 * Return: CDF STATUS 11661 */ 11662 static 11663 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 11664 struct set_wfatest_params *wmi_wfatest) 11665 { 11666 wmi_wfa_config_cmd_fixed_param *cmd; 11667 wmi_wfa_config_rsnxe *rxne; 11668 wmi_wfa_config_csa *csa; 11669 wmi_wfa_config_ocv *ocv; 11670 wmi_wfa_config_saquery *saquery; 11671 wmi_buf_t wmi_buf; 11672 uint16_t len = sizeof(*cmd); 11673 uint8_t *buf_ptr; 11674 11675 len += wfa_config_param_len(wmi_wfatest->cmd); 11676 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11677 if (!wmi_buf) 11678 return QDF_STATUS_E_NOMEM; 11679 11680 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 11681 WMITLV_SET_HDR(&cmd->tlv_header, 11682 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 11683 WMITLV_GET_STRUCT_TLVLEN( 11684 wmi_wfa_config_cmd_fixed_param)); 11685 11686 cmd->vdev_id = wmi_wfatest->vdev_id; 11687 buf_ptr = (uint8_t *)(cmd + 1); 11688 11689 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 11690 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11691 sizeof(wmi_wfa_config_rsnxe)); 11692 buf_ptr += WMI_TLV_HDR_SIZE; 11693 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 11694 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 11695 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 11696 rxne->rsnxe_param = wmi_wfatest->value; 11697 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 11698 } else { 11699 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11700 buf_ptr += WMI_TLV_HDR_SIZE; 11701 } 11702 11703 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11704 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11705 sizeof(wmi_wfa_config_csa)); 11706 buf_ptr += WMI_TLV_HDR_SIZE; 11707 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11708 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11709 csa = (wmi_wfa_config_csa *)buf_ptr; 11710 csa->ignore_csa = wmi_wfatest->value; 11711 buf_ptr += sizeof(wmi_wfa_config_csa); 11712 } else { 11713 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11714 buf_ptr += WMI_TLV_HDR_SIZE; 11715 } 11716 11717 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11718 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11719 sizeof(wmi_wfa_config_ocv)); 11720 buf_ptr += WMI_TLV_HDR_SIZE; 11721 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11722 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11723 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11724 11725 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11726 &ocv->frame_types)) 11727 goto error; 11728 11729 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11730 buf_ptr += sizeof(wmi_wfa_config_ocv); 11731 } else { 11732 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11733 buf_ptr += WMI_TLV_HDR_SIZE; 11734 } 11735 11736 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11737 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11738 sizeof(wmi_wfa_config_saquery)); 11739 buf_ptr += WMI_TLV_HDR_SIZE; 11740 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11741 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11742 11743 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11744 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11745 } else { 11746 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11747 buf_ptr += WMI_TLV_HDR_SIZE; 11748 } 11749 11750 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11751 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11752 WMI_WFA_CONFIG_CMDID)) { 11753 wmi_err("Failed to send wfa test command"); 11754 goto error; 11755 } 11756 11757 return QDF_STATUS_SUCCESS; 11758 11759 error: 11760 wmi_buf_free(wmi_buf); 11761 return QDF_STATUS_E_FAILURE; 11762 } 11763 11764 /** 11765 * send_unit_test_cmd_tlv() - send unit test command to fw. 11766 * @wmi_handle: wmi handle 11767 * @wmi_utest: unit test command 11768 * 11769 * This function send unit test command to fw. 11770 * 11771 * Return: CDF STATUS 11772 */ 11773 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11774 struct wmi_unit_test_cmd *wmi_utest) 11775 { 11776 wmi_unit_test_cmd_fixed_param *cmd; 11777 wmi_buf_t wmi_buf; 11778 uint8_t *buf_ptr; 11779 int i; 11780 uint16_t len, args_tlv_len; 11781 uint32_t *unit_test_cmd_args; 11782 11783 args_tlv_len = 11784 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11785 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11786 11787 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11788 if (!wmi_buf) 11789 return QDF_STATUS_E_NOMEM; 11790 11791 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11792 buf_ptr = (uint8_t *) cmd; 11793 WMITLV_SET_HDR(&cmd->tlv_header, 11794 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11795 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11796 cmd->vdev_id = wmi_utest->vdev_id; 11797 cmd->module_id = wmi_utest->module_id; 11798 cmd->num_args = wmi_utest->num_args; 11799 cmd->diag_token = wmi_utest->diag_token; 11800 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11801 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11802 (wmi_utest->num_args * sizeof(uint32_t))); 11803 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11804 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11805 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11806 wmi_debug("%d num of args = ", wmi_utest->num_args); 11807 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11808 unit_test_cmd_args[i] = wmi_utest->args[i]; 11809 wmi_debug("%d,", wmi_utest->args[i]); 11810 } 11811 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11812 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11813 WMI_UNIT_TEST_CMDID)) { 11814 wmi_err("Failed to send unit test command"); 11815 wmi_buf_free(wmi_buf); 11816 return QDF_STATUS_E_FAILURE; 11817 } 11818 11819 return QDF_STATUS_SUCCESS; 11820 } 11821 11822 /** 11823 * send_power_dbg_cmd_tlv() - send power debug commands 11824 * @wmi_handle: wmi handle 11825 * @param: wmi power debug parameter 11826 * 11827 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11828 * 11829 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11830 */ 11831 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11832 struct wmi_power_dbg_params *param) 11833 { 11834 wmi_buf_t buf = NULL; 11835 QDF_STATUS status; 11836 int len, args_tlv_len; 11837 uint8_t *buf_ptr; 11838 uint8_t i; 11839 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11840 uint32_t *cmd_args; 11841 11842 /* Prepare and send power debug cmd parameters */ 11843 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11844 len = sizeof(*cmd) + args_tlv_len; 11845 buf = wmi_buf_alloc(wmi_handle, len); 11846 if (!buf) 11847 return QDF_STATUS_E_NOMEM; 11848 11849 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11850 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11851 WMITLV_SET_HDR(&cmd->tlv_header, 11852 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11853 WMITLV_GET_STRUCT_TLVLEN 11854 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11855 11856 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11857 wmi_handle, 11858 param->pdev_id); 11859 cmd->module_id = param->module_id; 11860 cmd->num_args = param->num_args; 11861 buf_ptr += sizeof(*cmd); 11862 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11863 (param->num_args * sizeof(uint32_t))); 11864 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11865 wmi_debug("%d num of args = ", param->num_args); 11866 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11867 cmd_args[i] = param->args[i]; 11868 wmi_debug("%d,", param->args[i]); 11869 } 11870 11871 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11872 status = wmi_unified_cmd_send(wmi_handle, buf, 11873 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11874 if (QDF_IS_STATUS_ERROR(status)) { 11875 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11876 status); 11877 goto error; 11878 } 11879 11880 return QDF_STATUS_SUCCESS; 11881 error: 11882 wmi_buf_free(buf); 11883 11884 return status; 11885 } 11886 11887 /** 11888 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11889 * @wmi_handle: wmi handle 11890 * @pdev_id: pdev id 11891 * 11892 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11893 * 11894 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11895 */ 11896 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11897 uint32_t pdev_id) 11898 { 11899 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11900 wmi_buf_t buf; 11901 uint16_t len; 11902 QDF_STATUS ret; 11903 11904 len = sizeof(*cmd); 11905 buf = wmi_buf_alloc(wmi_handle, len); 11906 11907 wmi_debug("pdev_id=%d", pdev_id); 11908 11909 if (!buf) 11910 return QDF_STATUS_E_NOMEM; 11911 11912 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11913 wmi_buf_data(buf); 11914 11915 WMITLV_SET_HDR(&cmd->tlv_header, 11916 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11917 WMITLV_GET_STRUCT_TLVLEN( 11918 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11919 11920 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11921 wmi_handle, 11922 pdev_id); 11923 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11924 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11925 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11926 if (QDF_IS_STATUS_ERROR(ret)) { 11927 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11928 ret, pdev_id); 11929 wmi_buf_free(buf); 11930 return QDF_STATUS_E_FAILURE; 11931 } 11932 11933 return QDF_STATUS_SUCCESS; 11934 } 11935 11936 /** 11937 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11938 * @wmi_handle: wmi handle 11939 * @pdev_id: pdev id 11940 * 11941 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11942 * 11943 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11944 */ 11945 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11946 uint32_t pdev_id) 11947 { 11948 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11949 wmi_buf_t buf; 11950 uint16_t len; 11951 QDF_STATUS ret; 11952 11953 len = sizeof(*cmd); 11954 buf = wmi_buf_alloc(wmi_handle, len); 11955 11956 wmi_debug("pdev_id=%d", pdev_id); 11957 11958 if (!buf) 11959 return QDF_STATUS_E_NOMEM; 11960 11961 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11962 wmi_buf_data(buf); 11963 11964 WMITLV_SET_HDR(&cmd->tlv_header, 11965 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11966 WMITLV_GET_STRUCT_TLVLEN( 11967 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11968 11969 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11970 wmi_handle, 11971 pdev_id); 11972 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11973 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11974 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11975 if (QDF_IS_STATUS_ERROR(ret)) { 11976 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11977 ret, pdev_id); 11978 wmi_buf_free(buf); 11979 return QDF_STATUS_E_FAILURE; 11980 } 11981 11982 return QDF_STATUS_SUCCESS; 11983 } 11984 11985 #ifdef QCA_SUPPORT_AGILE_DFS 11986 static 11987 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11988 struct vdev_adfs_ch_cfg_params *param) 11989 { 11990 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11991 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11992 wmi_buf_t buf; 11993 QDF_STATUS ret; 11994 uint16_t len; 11995 11996 len = sizeof(*cmd); 11997 buf = wmi_buf_alloc(wmi_handle, len); 11998 11999 if (!buf) { 12000 wmi_err("wmi_buf_alloc failed"); 12001 return QDF_STATUS_E_NOMEM; 12002 } 12003 12004 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 12005 wmi_buf_data(buf); 12006 12007 WMITLV_SET_HDR(&cmd->tlv_header, 12008 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 12009 WMITLV_GET_STRUCT_TLVLEN 12010 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 12011 12012 cmd->vdev_id = param->vdev_id; 12013 cmd->ocac_mode = param->ocac_mode; 12014 cmd->center_freq1 = param->center_freq1; 12015 cmd->center_freq2 = param->center_freq2; 12016 cmd->chan_freq = param->chan_freq; 12017 cmd->chan_width = param->chan_width; 12018 cmd->min_duration_ms = param->min_duration_ms; 12019 cmd->max_duration_ms = param->max_duration_ms; 12020 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 12021 cmd->vdev_id, cmd->ocac_mode, 12022 cmd->center_freq); 12023 12024 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 12025 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12026 WMI_VDEV_ADFS_CH_CFG_CMDID); 12027 12028 if (QDF_IS_STATUS_ERROR(ret)) { 12029 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12030 wmi_buf_free(buf); 12031 return QDF_STATUS_E_FAILURE; 12032 } 12033 12034 return QDF_STATUS_SUCCESS; 12035 } 12036 12037 static 12038 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 12039 struct vdev_adfs_abort_params *param) 12040 { 12041 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 12042 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 12043 wmi_buf_t buf; 12044 QDF_STATUS ret; 12045 uint16_t len; 12046 12047 len = sizeof(*cmd); 12048 buf = wmi_buf_alloc(wmi_handle, len); 12049 12050 if (!buf) { 12051 wmi_err("wmi_buf_alloc failed"); 12052 return QDF_STATUS_E_NOMEM; 12053 } 12054 12055 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 12056 wmi_buf_data(buf); 12057 12058 WMITLV_SET_HDR 12059 (&cmd->tlv_header, 12060 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 12061 WMITLV_GET_STRUCT_TLVLEN 12062 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 12063 12064 cmd->vdev_id = param->vdev_id; 12065 12066 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 12067 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12068 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 12069 12070 if (QDF_IS_STATUS_ERROR(ret)) { 12071 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12072 wmi_buf_free(buf); 12073 return QDF_STATUS_E_FAILURE; 12074 } 12075 12076 return QDF_STATUS_SUCCESS; 12077 } 12078 #endif 12079 12080 /** 12081 * init_cmd_send_tlv() - send initialization cmd to fw 12082 * @wmi_handle: wmi handle 12083 * @param: pointer to wmi init param 12084 * 12085 * Return: QDF_STATUS_SUCCESS for success or error code 12086 */ 12087 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 12088 struct wmi_init_cmd_param *param) 12089 { 12090 wmi_buf_t buf; 12091 wmi_init_cmd_fixed_param *cmd; 12092 uint8_t *buf_ptr; 12093 wmi_resource_config *resource_cfg; 12094 wlan_host_memory_chunk *host_mem_chunks; 12095 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 12096 uint16_t idx; 12097 int len; 12098 QDF_STATUS ret; 12099 12100 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 12101 WMI_TLV_HDR_SIZE; 12102 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 12103 12104 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 12105 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12106 WMI_TLV_HDR_SIZE + 12107 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 12108 12109 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 12110 if (!buf) 12111 return QDF_STATUS_E_FAILURE; 12112 12113 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12114 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 12115 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 12116 12117 host_mem_chunks = (wlan_host_memory_chunk *) 12118 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 12119 + WMI_TLV_HDR_SIZE); 12120 12121 WMITLV_SET_HDR(&cmd->tlv_header, 12122 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 12123 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 12124 wmi_copy_resource_config(resource_cfg, param->res_cfg); 12125 WMITLV_SET_HDR(&resource_cfg->tlv_header, 12126 WMITLV_TAG_STRUC_wmi_resource_config, 12127 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 12128 12129 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 12130 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 12131 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 12132 WMITLV_GET_STRUCT_TLVLEN 12133 (wlan_host_memory_chunk)); 12134 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 12135 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 12136 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 12137 if (is_service_enabled_tlv(wmi_handle, 12138 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 12139 host_mem_chunks[idx].ptr_high = 12140 qdf_get_upper_32_bits( 12141 param->mem_chunks[idx].paddr); 12142 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 12143 "chunk %d len %d requested ,ptr 0x%x ", 12144 idx, host_mem_chunks[idx].size, 12145 host_mem_chunks[idx].ptr); 12146 } 12147 cmd->num_host_mem_chunks = param->num_mem_chunks; 12148 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 12149 12150 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 12151 WMITLV_TAG_ARRAY_STRUC, 12152 (sizeof(wlan_host_memory_chunk) * 12153 param->num_mem_chunks)); 12154 12155 wmi_debug("num peers: %d , num offload peers: %d, num vdevs: %d, num tids: %d, num tdls conn tb entries: %d, num tdls vdevs: %d", 12156 resource_cfg->num_peers, resource_cfg->num_offload_peers, 12157 resource_cfg->num_vdevs, resource_cfg->num_tids, 12158 resource_cfg->num_tdls_conn_table_entries, 12159 resource_cfg->num_tdls_vdevs); 12160 12161 /* Fill hw mode id config */ 12162 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 12163 12164 /* Fill fw_abi_vers */ 12165 copy_fw_abi_version_tlv(wmi_handle, cmd); 12166 12167 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 12168 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 12169 if (QDF_IS_STATUS_ERROR(ret)) { 12170 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 12171 ret); 12172 wmi_buf_free(buf); 12173 } 12174 12175 return ret; 12176 12177 } 12178 12179 /** 12180 * send_addba_send_cmd_tlv() - send addba send command to fw 12181 * @wmi_handle: wmi handle 12182 * @param: pointer to delba send params 12183 * @macaddr: peer mac address 12184 * 12185 * Send WMI_ADDBA_SEND_CMDID command to firmware 12186 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 12187 */ 12188 static QDF_STATUS 12189 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 12190 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12191 struct addba_send_params *param) 12192 { 12193 wmi_addba_send_cmd_fixed_param *cmd; 12194 wmi_buf_t buf; 12195 uint16_t len; 12196 QDF_STATUS ret; 12197 12198 len = sizeof(*cmd); 12199 12200 buf = wmi_buf_alloc(wmi_handle, len); 12201 if (!buf) 12202 return QDF_STATUS_E_NOMEM; 12203 12204 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 12205 12206 WMITLV_SET_HDR(&cmd->tlv_header, 12207 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 12208 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 12209 12210 cmd->vdev_id = param->vdev_id; 12211 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12212 cmd->tid = param->tidno; 12213 cmd->buffersize = param->buffersize; 12214 12215 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 12216 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 12217 if (QDF_IS_STATUS_ERROR(ret)) { 12218 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12219 wmi_buf_free(buf); 12220 return QDF_STATUS_E_FAILURE; 12221 } 12222 12223 return QDF_STATUS_SUCCESS; 12224 } 12225 12226 /** 12227 * send_delba_send_cmd_tlv() - send delba send command to fw 12228 * @wmi_handle: wmi handle 12229 * @param: pointer to delba send params 12230 * @macaddr: peer mac address 12231 * 12232 * Send WMI_DELBA_SEND_CMDID command to firmware 12233 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 12234 */ 12235 static QDF_STATUS 12236 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 12237 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12238 struct delba_send_params *param) 12239 { 12240 wmi_delba_send_cmd_fixed_param *cmd; 12241 wmi_buf_t buf; 12242 uint16_t len; 12243 QDF_STATUS ret; 12244 12245 len = sizeof(*cmd); 12246 12247 buf = wmi_buf_alloc(wmi_handle, len); 12248 if (!buf) 12249 return QDF_STATUS_E_NOMEM; 12250 12251 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 12252 12253 WMITLV_SET_HDR(&cmd->tlv_header, 12254 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 12255 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 12256 12257 cmd->vdev_id = param->vdev_id; 12258 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12259 cmd->tid = param->tidno; 12260 cmd->initiator = param->initiator; 12261 cmd->reasoncode = param->reasoncode; 12262 12263 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 12264 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 12265 if (QDF_IS_STATUS_ERROR(ret)) { 12266 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12267 wmi_buf_free(buf); 12268 return QDF_STATUS_E_FAILURE; 12269 } 12270 12271 return QDF_STATUS_SUCCESS; 12272 } 12273 12274 /** 12275 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 12276 * to fw 12277 * @wmi_handle: wmi handle 12278 * @param: pointer to addba clearresp params 12279 * @macaddr: peer mac address 12280 * Return: QDF_STATUS_SUCCESS for success or error code 12281 */ 12282 static QDF_STATUS 12283 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 12284 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12285 struct addba_clearresponse_params *param) 12286 { 12287 wmi_addba_clear_resp_cmd_fixed_param *cmd; 12288 wmi_buf_t buf; 12289 uint16_t len; 12290 QDF_STATUS ret; 12291 12292 len = sizeof(*cmd); 12293 12294 buf = wmi_buf_alloc(wmi_handle, len); 12295 if (!buf) 12296 return QDF_STATUS_E_FAILURE; 12297 12298 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 12299 12300 WMITLV_SET_HDR(&cmd->tlv_header, 12301 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 12302 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 12303 12304 cmd->vdev_id = param->vdev_id; 12305 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12306 12307 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 12308 ret = wmi_unified_cmd_send(wmi_handle, 12309 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 12310 if (QDF_IS_STATUS_ERROR(ret)) { 12311 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12312 wmi_buf_free(buf); 12313 return QDF_STATUS_E_FAILURE; 12314 } 12315 12316 return QDF_STATUS_SUCCESS; 12317 } 12318 12319 #ifdef OBSS_PD 12320 /** 12321 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 12322 * def thresh to fw 12323 * @wmi_handle: wmi handle 12324 * @thresh: pointer to obss_spatial_reuse_def_thresh 12325 * 12326 * Return: QDF_STATUS_SUCCESS for success or error code 12327 */ 12328 static 12329 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 12330 wmi_unified_t wmi_handle, 12331 struct wmi_host_obss_spatial_reuse_set_def_thresh 12332 *thresh) 12333 { 12334 wmi_buf_t buf; 12335 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 12336 QDF_STATUS ret; 12337 uint32_t cmd_len; 12338 uint32_t tlv_len; 12339 12340 cmd_len = sizeof(*cmd); 12341 12342 buf = wmi_buf_alloc(wmi_handle, cmd_len); 12343 if (!buf) 12344 return QDF_STATUS_E_NOMEM; 12345 12346 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 12347 wmi_buf_data(buf); 12348 12349 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 12350 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 12351 12352 WMITLV_SET_HDR(&cmd->tlv_header, 12353 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 12354 tlv_len); 12355 12356 cmd->obss_min = thresh->obss_min; 12357 cmd->obss_max = thresh->obss_max; 12358 cmd->vdev_type = thresh->vdev_type; 12359 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 12360 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 12361 if (QDF_IS_STATUS_ERROR(ret)) 12362 wmi_buf_free(buf); 12363 12364 return ret; 12365 } 12366 12367 /** 12368 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 12369 * @wmi_handle: wmi handle 12370 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 12371 * 12372 * Return: QDF_STATUS_SUCCESS for success or error code 12373 */ 12374 static 12375 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 12376 struct wmi_host_obss_spatial_reuse_set_param 12377 *obss_spatial_reuse_param) 12378 { 12379 wmi_buf_t buf; 12380 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 12381 QDF_STATUS ret; 12382 uint32_t len; 12383 12384 len = sizeof(*cmd); 12385 12386 buf = wmi_buf_alloc(wmi_handle, len); 12387 if (!buf) 12388 return QDF_STATUS_E_FAILURE; 12389 12390 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 12391 WMITLV_SET_HDR(&cmd->tlv_header, 12392 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 12393 WMITLV_GET_STRUCT_TLVLEN 12394 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 12395 12396 cmd->enable = obss_spatial_reuse_param->enable; 12397 cmd->obss_min = obss_spatial_reuse_param->obss_min; 12398 cmd->obss_max = obss_spatial_reuse_param->obss_max; 12399 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 12400 12401 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12402 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 12403 12404 if (QDF_IS_STATUS_ERROR(ret)) { 12405 wmi_err( 12406 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 12407 ret); 12408 wmi_buf_free(buf); 12409 } 12410 12411 return ret; 12412 } 12413 12414 /** 12415 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 12416 * to be used by SRG based Spatial Reuse feature to the FW 12417 * @wmi_handle: wmi handle 12418 * @bitmap_0: lower 32 bits in BSS color bitmap 12419 * @bitmap_1: upper 32 bits in BSS color bitmap 12420 * @pdev_id: pdev ID 12421 * 12422 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12423 */ 12424 static QDF_STATUS 12425 send_self_srg_bss_color_bitmap_set_cmd_tlv( 12426 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12427 uint32_t bitmap_1, uint8_t pdev_id) 12428 { 12429 wmi_buf_t buf; 12430 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 12431 QDF_STATUS ret; 12432 uint32_t len; 12433 12434 len = sizeof(*cmd); 12435 12436 buf = wmi_buf_alloc(wmi_handle, len); 12437 if (!buf) 12438 return QDF_STATUS_E_FAILURE; 12439 12440 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 12441 wmi_buf_data(buf); 12442 12443 WMITLV_SET_HDR( 12444 &cmd->tlv_header, 12445 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 12446 WMITLV_GET_STRUCT_TLVLEN 12447 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 12448 12449 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12450 wmi_handle, pdev_id); 12451 cmd->srg_bss_color_bitmap[0] = bitmap_0; 12452 cmd->srg_bss_color_bitmap[1] = bitmap_1; 12453 12454 ret = wmi_unified_cmd_send( 12455 wmi_handle, buf, len, 12456 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 12457 12458 if (QDF_IS_STATUS_ERROR(ret)) { 12459 wmi_err( 12460 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 12461 ret); 12462 wmi_buf_free(buf); 12463 } 12464 12465 return ret; 12466 } 12467 12468 /** 12469 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 12470 * bitmap to be used by SRG based Spatial Reuse feature to the FW 12471 * @wmi_handle: wmi handle 12472 * @bitmap_0: lower 32 bits in partial BSSID bitmap 12473 * @bitmap_1: upper 32 bits in partial BSSID bitmap 12474 * @pdev_id: pdev ID 12475 * 12476 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12477 */ 12478 static QDF_STATUS 12479 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 12480 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12481 uint32_t bitmap_1, uint8_t pdev_id) 12482 { 12483 wmi_buf_t buf; 12484 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 12485 QDF_STATUS ret; 12486 uint32_t len; 12487 12488 len = sizeof(*cmd); 12489 12490 buf = wmi_buf_alloc(wmi_handle, len); 12491 if (!buf) 12492 return QDF_STATUS_E_FAILURE; 12493 12494 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 12495 wmi_buf_data(buf); 12496 12497 WMITLV_SET_HDR( 12498 &cmd->tlv_header, 12499 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 12500 WMITLV_GET_STRUCT_TLVLEN 12501 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 12502 12503 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12504 wmi_handle, pdev_id); 12505 12506 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 12507 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 12508 12509 ret = wmi_unified_cmd_send( 12510 wmi_handle, buf, len, 12511 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 12512 12513 if (QDF_IS_STATUS_ERROR(ret)) { 12514 wmi_err( 12515 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 12516 ret); 12517 wmi_buf_free(buf); 12518 } 12519 12520 return ret; 12521 } 12522 12523 /** 12524 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12525 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12526 * @wmi_handle: wmi handle 12527 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12528 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12529 * @pdev_id: pdev ID 12530 * 12531 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12532 */ 12533 static QDF_STATUS 12534 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 12535 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12536 uint32_t bitmap_1, uint8_t pdev_id) 12537 { 12538 wmi_buf_t buf; 12539 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12540 QDF_STATUS ret; 12541 uint32_t len; 12542 12543 len = sizeof(*cmd); 12544 12545 buf = wmi_buf_alloc(wmi_handle, len); 12546 if (!buf) 12547 return QDF_STATUS_E_FAILURE; 12548 12549 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12550 wmi_buf_data(buf); 12551 12552 WMITLV_SET_HDR( 12553 &cmd->tlv_header, 12554 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 12555 WMITLV_GET_STRUCT_TLVLEN 12556 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12557 12558 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12559 wmi_handle, pdev_id); 12560 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 12561 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 12562 12563 ret = wmi_unified_cmd_send( 12564 wmi_handle, buf, len, 12565 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12566 12567 if (QDF_IS_STATUS_ERROR(ret)) { 12568 wmi_err( 12569 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12570 ret); 12571 wmi_buf_free(buf); 12572 } 12573 12574 return ret; 12575 } 12576 12577 /** 12578 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12579 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12580 * @wmi_handle: wmi handle 12581 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12582 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12583 * @pdev_id: pdev ID 12584 * 12585 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12586 */ 12587 static QDF_STATUS 12588 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 12589 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12590 uint32_t bitmap_1, uint8_t pdev_id) 12591 { 12592 wmi_buf_t buf; 12593 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12594 QDF_STATUS ret; 12595 uint32_t len; 12596 12597 len = sizeof(*cmd); 12598 12599 buf = wmi_buf_alloc(wmi_handle, len); 12600 if (!buf) 12601 return QDF_STATUS_E_FAILURE; 12602 12603 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12604 wmi_buf_data(buf); 12605 12606 WMITLV_SET_HDR( 12607 &cmd->tlv_header, 12608 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12609 WMITLV_GET_STRUCT_TLVLEN 12610 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12611 12612 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12613 wmi_handle, pdev_id); 12614 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 12615 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 12616 12617 ret = wmi_unified_cmd_send( 12618 wmi_handle, buf, len, 12619 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12620 12621 if (QDF_IS_STATUS_ERROR(ret)) { 12622 wmi_err( 12623 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12624 ret); 12625 wmi_buf_free(buf); 12626 } 12627 12628 return ret; 12629 } 12630 12631 /** 12632 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12633 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12634 * @wmi_handle: wmi handle 12635 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12636 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12637 * @pdev_id: pdev ID 12638 * 12639 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12640 */ 12641 static QDF_STATUS 12642 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 12643 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12644 uint32_t bitmap_1, uint8_t pdev_id) 12645 { 12646 wmi_buf_t buf; 12647 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12648 QDF_STATUS ret; 12649 uint32_t len; 12650 12651 len = sizeof(*cmd); 12652 12653 buf = wmi_buf_alloc(wmi_handle, len); 12654 if (!buf) 12655 return QDF_STATUS_E_FAILURE; 12656 12657 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12658 wmi_buf_data(buf); 12659 12660 WMITLV_SET_HDR( 12661 &cmd->tlv_header, 12662 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 12663 WMITLV_GET_STRUCT_TLVLEN 12664 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12665 12666 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12667 wmi_handle, pdev_id); 12668 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 12669 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 12670 12671 ret = wmi_unified_cmd_send( 12672 wmi_handle, buf, len, 12673 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12674 12675 if (QDF_IS_STATUS_ERROR(ret)) { 12676 wmi_err( 12677 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12678 ret); 12679 wmi_buf_free(buf); 12680 } 12681 12682 return ret; 12683 } 12684 12685 /** 12686 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12687 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12688 * @wmi_handle: wmi handle 12689 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12690 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12691 * @pdev_id: pdev ID 12692 * 12693 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12694 */ 12695 static QDF_STATUS 12696 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 12697 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12698 uint32_t bitmap_1, uint8_t pdev_id) 12699 { 12700 wmi_buf_t buf; 12701 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12702 QDF_STATUS ret; 12703 uint32_t len; 12704 12705 len = sizeof(*cmd); 12706 12707 buf = wmi_buf_alloc(wmi_handle, len); 12708 if (!buf) 12709 return QDF_STATUS_E_FAILURE; 12710 12711 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12712 wmi_buf_data(buf); 12713 12714 WMITLV_SET_HDR( 12715 &cmd->tlv_header, 12716 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12717 WMITLV_GET_STRUCT_TLVLEN 12718 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12719 12720 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12721 wmi_handle, pdev_id); 12722 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12723 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12724 12725 ret = wmi_unified_cmd_send( 12726 wmi_handle, buf, len, 12727 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12728 12729 if (QDF_IS_STATUS_ERROR(ret)) { 12730 wmi_err( 12731 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12732 ret); 12733 wmi_buf_free(buf); 12734 } 12735 12736 return ret; 12737 } 12738 #endif 12739 12740 static 12741 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12742 struct wmi_host_injector_frame_params *inject_config_params) 12743 { 12744 wmi_buf_t buf; 12745 wmi_frame_inject_cmd_fixed_param *cmd; 12746 QDF_STATUS ret; 12747 uint32_t len; 12748 12749 len = sizeof(*cmd); 12750 12751 buf = wmi_buf_alloc(wmi_handle, len); 12752 if (!buf) 12753 return QDF_STATUS_E_NOMEM; 12754 12755 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12756 WMITLV_SET_HDR(&cmd->tlv_header, 12757 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12758 WMITLV_GET_STRUCT_TLVLEN 12759 (wmi_frame_inject_cmd_fixed_param)); 12760 12761 cmd->vdev_id = inject_config_params->vdev_id; 12762 cmd->enable = inject_config_params->enable; 12763 cmd->frame_type = inject_config_params->frame_type; 12764 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12765 cmd->fc_duration = inject_config_params->frame_duration; 12766 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12767 &cmd->frame_addr1); 12768 cmd->bw = inject_config_params->frame_bw; 12769 12770 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12771 WMI_PDEV_FRAME_INJECT_CMDID); 12772 12773 if (QDF_IS_STATUS_ERROR(ret)) { 12774 wmi_err( 12775 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12776 ret); 12777 wmi_buf_free(buf); 12778 } 12779 12780 return ret; 12781 } 12782 #ifdef QCA_SUPPORT_CP_STATS 12783 /** 12784 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12785 * @wmi_handle: wma handle 12786 * @evt_buf: event buffer 12787 * @out_buff: buffer to populated after stats extraction 12788 * 12789 * Return: status of operation 12790 */ 12791 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12792 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12793 { 12794 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12795 wmi_congestion_stats *congestion_stats; 12796 12797 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12798 congestion_stats = param_buf->congestion_stats; 12799 if (!congestion_stats) 12800 return QDF_STATUS_E_INVAL; 12801 12802 out_buff->vdev_id = congestion_stats->vdev_id; 12803 out_buff->congestion = congestion_stats->congestion; 12804 12805 wmi_debug("cca stats event processed"); 12806 return QDF_STATUS_SUCCESS; 12807 } 12808 #endif /* QCA_SUPPORT_CP_STATS */ 12809 12810 /** 12811 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12812 * event 12813 * @wmi_handle: wmi handle 12814 * @evt_buf: pointer to event buffer 12815 * @param: Pointer to hold peer ctl data 12816 * 12817 * Return: QDF_STATUS_SUCCESS for success or error code 12818 */ 12819 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12820 wmi_unified_t wmi_handle, 12821 void *evt_buf, 12822 struct wmi_host_pdev_ctl_failsafe_event *param) 12823 { 12824 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12825 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12826 12827 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12828 if (!param_buf) { 12829 wmi_err("Invalid ctl_failsafe event buffer"); 12830 return QDF_STATUS_E_INVAL; 12831 } 12832 12833 fix_param = param_buf->fixed_param; 12834 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12835 12836 return QDF_STATUS_SUCCESS; 12837 } 12838 12839 /** 12840 * save_service_bitmap_tlv() - save service bitmap 12841 * @wmi_handle: wmi handle 12842 * @evt_buf: pointer to event buffer 12843 * @bitmap_buf: bitmap buffer, for converged legacy support 12844 * 12845 * Return: QDF_STATUS 12846 */ 12847 static 12848 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12849 void *bitmap_buf) 12850 { 12851 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12852 struct wmi_soc *soc = wmi_handle->soc; 12853 12854 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12855 12856 /* If it is already allocated, use that buffer. This can happen 12857 * during target stop/start scenarios where host allocation is skipped. 12858 */ 12859 if (!soc->wmi_service_bitmap) { 12860 soc->wmi_service_bitmap = 12861 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12862 if (!soc->wmi_service_bitmap) 12863 return QDF_STATUS_E_NOMEM; 12864 } 12865 12866 qdf_mem_copy(soc->wmi_service_bitmap, 12867 param_buf->wmi_service_bitmap, 12868 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12869 12870 if (bitmap_buf) 12871 qdf_mem_copy(bitmap_buf, 12872 param_buf->wmi_service_bitmap, 12873 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12874 12875 return QDF_STATUS_SUCCESS; 12876 } 12877 12878 /** 12879 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12880 * @wmi_handle: wmi handle 12881 * @evt_buf: pointer to event buffer 12882 * @bitmap_buf: bitmap buffer, for converged legacy support 12883 * 12884 * Return: QDF_STATUS 12885 */ 12886 static 12887 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12888 void *bitmap_buf) 12889 { 12890 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12891 wmi_service_available_event_fixed_param *ev; 12892 struct wmi_soc *soc = wmi_handle->soc; 12893 uint32_t i = 0; 12894 12895 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12896 12897 ev = param_buf->fixed_param; 12898 12899 /* If it is already allocated, use that buffer. This can happen 12900 * during target stop/start scenarios where host allocation is skipped. 12901 */ 12902 if (!soc->wmi_ext_service_bitmap) { 12903 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12904 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12905 if (!soc->wmi_ext_service_bitmap) 12906 return QDF_STATUS_E_NOMEM; 12907 } 12908 12909 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12910 ev->wmi_service_segment_bitmap, 12911 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12912 12913 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12914 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12915 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12916 12917 if (bitmap_buf) 12918 qdf_mem_copy(bitmap_buf, 12919 soc->wmi_ext_service_bitmap, 12920 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12921 12922 if (!param_buf->wmi_service_ext_bitmap) { 12923 wmi_debug("wmi_service_ext_bitmap not available"); 12924 return QDF_STATUS_SUCCESS; 12925 } 12926 12927 if (!soc->wmi_ext2_service_bitmap || 12928 (param_buf->num_wmi_service_ext_bitmap > 12929 soc->wmi_ext2_service_bitmap_len)) { 12930 if (soc->wmi_ext2_service_bitmap) { 12931 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12932 soc->wmi_ext2_service_bitmap = NULL; 12933 } 12934 soc->wmi_ext2_service_bitmap = 12935 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12936 sizeof(uint32_t)); 12937 if (!soc->wmi_ext2_service_bitmap) 12938 return QDF_STATUS_E_NOMEM; 12939 12940 soc->wmi_ext2_service_bitmap_len = 12941 param_buf->num_wmi_service_ext_bitmap; 12942 } 12943 12944 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12945 param_buf->wmi_service_ext_bitmap, 12946 (param_buf->num_wmi_service_ext_bitmap * 12947 sizeof(uint32_t))); 12948 12949 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12950 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12951 i, soc->wmi_ext2_service_bitmap[i]); 12952 } 12953 12954 return QDF_STATUS_SUCCESS; 12955 } 12956 12957 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12958 struct wlan_psoc_target_capability_info *cap) 12959 { 12960 /* except LDPC all flags are common between legacy and here 12961 * also IBFEER is not defined for TLV 12962 */ 12963 cap->ht_cap_info |= ev_target_cap & ( 12964 WMI_HT_CAP_ENABLED 12965 | WMI_HT_CAP_HT20_SGI 12966 | WMI_HT_CAP_DYNAMIC_SMPS 12967 | WMI_HT_CAP_TX_STBC 12968 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12969 | WMI_HT_CAP_RX_STBC 12970 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12971 | WMI_HT_CAP_LDPC 12972 | WMI_HT_CAP_L_SIG_TXOP_PROT 12973 | WMI_HT_CAP_MPDU_DENSITY 12974 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12975 | WMI_HT_CAP_HT40_SGI); 12976 if (ev_target_cap & WMI_HT_CAP_LDPC) 12977 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12978 WMI_HOST_HT_CAP_TX_LDPC; 12979 } 12980 /** 12981 * extract_service_ready_tlv() - extract service ready event 12982 * @wmi_handle: wmi handle 12983 * @evt_buf: pointer to received event buffer 12984 * @cap: pointer to hold target capability information extracted from even 12985 * 12986 * Return: QDF_STATUS_SUCCESS for success or error code 12987 */ 12988 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12989 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12990 { 12991 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12992 wmi_service_ready_event_fixed_param *ev; 12993 12994 12995 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12996 12997 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 12998 if (!ev) { 12999 qdf_print("%s: wmi_buf_alloc failed", __func__); 13000 return QDF_STATUS_E_FAILURE; 13001 } 13002 13003 cap->phy_capability = ev->phy_capability; 13004 cap->max_frag_entry = ev->max_frag_entry; 13005 cap->num_rf_chains = ev->num_rf_chains; 13006 copy_ht_cap_info(ev->ht_cap_info, cap); 13007 cap->vht_cap_info = ev->vht_cap_info; 13008 cap->vht_supp_mcs = ev->vht_supp_mcs; 13009 cap->hw_min_tx_power = ev->hw_min_tx_power; 13010 cap->hw_max_tx_power = ev->hw_max_tx_power; 13011 cap->sys_cap_info = ev->sys_cap_info; 13012 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 13013 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 13014 cap->max_num_scan_channels = ev->max_num_scan_channels; 13015 cap->max_supported_macs = ev->max_supported_macs; 13016 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 13017 cap->txrx_chainmask = ev->txrx_chainmask; 13018 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 13019 cap->num_msdu_desc = ev->num_msdu_desc; 13020 cap->fw_version = ev->fw_build_vers; 13021 /* fw_version_1 is not available in TLV. */ 13022 cap->fw_version_1 = 0; 13023 13024 return QDF_STATUS_SUCCESS; 13025 } 13026 13027 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 13028 * to host internal HOST_REGDMN_MODE values. 13029 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 13030 * host currently. Add this in the future if required. 13031 * 11AX (Phase II) : 11ax related values are not currently 13032 * advertised separately by FW. As part of phase II regulatory bring-up, 13033 * finalize the advertisement mechanism. 13034 * @target_wireless_mode: target wireless mode received in message 13035 * 13036 * Return: returns the host internal wireless mode. 13037 */ 13038 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 13039 { 13040 13041 uint32_t wireless_modes = 0; 13042 13043 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 13044 13045 if (target_wireless_mode & REGDMN_MODE_11A) 13046 wireless_modes |= HOST_REGDMN_MODE_11A; 13047 13048 if (target_wireless_mode & REGDMN_MODE_TURBO) 13049 wireless_modes |= HOST_REGDMN_MODE_TURBO; 13050 13051 if (target_wireless_mode & REGDMN_MODE_11B) 13052 wireless_modes |= HOST_REGDMN_MODE_11B; 13053 13054 if (target_wireless_mode & REGDMN_MODE_PUREG) 13055 wireless_modes |= HOST_REGDMN_MODE_PUREG; 13056 13057 if (target_wireless_mode & REGDMN_MODE_11G) 13058 wireless_modes |= HOST_REGDMN_MODE_11G; 13059 13060 if (target_wireless_mode & REGDMN_MODE_108G) 13061 wireless_modes |= HOST_REGDMN_MODE_108G; 13062 13063 if (target_wireless_mode & REGDMN_MODE_108A) 13064 wireless_modes |= HOST_REGDMN_MODE_108A; 13065 13066 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 13067 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 13068 13069 if (target_wireless_mode & REGDMN_MODE_XR) 13070 wireless_modes |= HOST_REGDMN_MODE_XR; 13071 13072 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 13073 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 13074 13075 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 13076 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 13077 13078 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 13079 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 13080 13081 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 13082 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 13083 13084 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 13085 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 13086 13087 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 13088 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 13089 13090 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 13091 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 13092 13093 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 13094 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 13095 13096 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 13097 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 13098 13099 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 13100 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 13101 13102 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 13103 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 13104 13105 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 13106 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 13107 13108 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 13109 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 13110 13111 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 13112 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 13113 13114 return wireless_modes; 13115 } 13116 13117 /** 13118 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 13119 * to regulatory flags. 13120 * @target_phybitmap: target phybitmap. 13121 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 13122 * phybitmap. 13123 * 13124 * Return: None 13125 */ 13126 13127 #ifdef WLAN_FEATURE_11BE 13128 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 13129 uint32_t *phybitmap) 13130 { 13131 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 13132 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 13133 } 13134 #else 13135 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 13136 uint32_t *phybitmap) 13137 { 13138 } 13139 #endif 13140 13141 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 13142 * target to host internal REGULATORY_PHYMODE values. 13143 * 13144 * @target_target_phybitmap: target phybitmap received in the message. 13145 * 13146 * Return: returns the host internal REGULATORY_PHYMODE. 13147 */ 13148 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 13149 { 13150 uint32_t phybitmap = 0; 13151 13152 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 13153 13154 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 13155 phybitmap |= REGULATORY_PHYMODE_NO11A; 13156 13157 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 13158 phybitmap |= REGULATORY_PHYMODE_NO11B; 13159 13160 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 13161 phybitmap |= REGULATORY_PHYMODE_NO11G; 13162 13163 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 13164 phybitmap |= REGULATORY_CHAN_NO11N; 13165 13166 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 13167 phybitmap |= REGULATORY_PHYMODE_NO11AC; 13168 13169 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 13170 phybitmap |= REGULATORY_PHYMODE_NO11AX; 13171 13172 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 13173 13174 return phybitmap; 13175 } 13176 13177 /** 13178 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 13179 * advertised by the target to wireless mode ext flags. 13180 * @target_wireless_modes_ext: Target wireless mode 13181 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 13182 * 13183 * Return: None 13184 */ 13185 #ifdef WLAN_FEATURE_11BE 13186 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 13187 uint64_t *wireless_modes_ext) 13188 { 13189 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 13190 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 13191 13192 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 13193 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 13194 13195 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 13196 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 13197 13198 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 13199 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 13200 13201 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 13202 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 13203 13204 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 13205 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 13206 13207 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 13208 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 13209 13210 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 13211 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 13212 13213 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 13214 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 13215 } 13216 #else 13217 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 13218 uint64_t *wireless_modes_ext) 13219 { 13220 } 13221 #endif 13222 13223 static inline uint64_t convert_wireless_modes_ext_tlv( 13224 uint32_t target_wireless_modes_ext) 13225 { 13226 uint64_t wireless_modes_ext = 0; 13227 13228 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 13229 13230 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 13231 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 13232 13233 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 13234 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 13235 13236 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 13237 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 13238 13239 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 13240 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 13241 13242 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 13243 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 13244 13245 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 13246 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 13247 13248 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 13249 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 13250 13251 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 13252 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 13253 13254 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 13255 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 13256 13257 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 13258 &wireless_modes_ext); 13259 13260 return wireless_modes_ext; 13261 } 13262 13263 /** 13264 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 13265 * @wmi_handle: wmi handle 13266 * @evt_buf: Pointer to event buffer 13267 * @cap: pointer to hold HAL reg capabilities 13268 * 13269 * Return: QDF_STATUS_SUCCESS for success or error code 13270 */ 13271 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 13272 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 13273 { 13274 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13275 13276 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13277 if (!param_buf || !param_buf->hal_reg_capabilities) { 13278 wmi_err("Invalid arguments"); 13279 return QDF_STATUS_E_FAILURE; 13280 } 13281 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 13282 sizeof(uint32_t)), 13283 sizeof(struct wlan_psoc_hal_reg_capability)); 13284 13285 cap->wireless_modes = convert_wireless_modes_tlv( 13286 param_buf->hal_reg_capabilities->wireless_modes); 13287 13288 return QDF_STATUS_SUCCESS; 13289 } 13290 13291 /** 13292 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 13293 * @wmi_handle: wmi handle 13294 * @evt_buf: Pointer to event buffer 13295 * @phy_idx: Specific phy to extract 13296 * @param: pointer to hold HAL reg capabilities 13297 * 13298 * Return: QDF_STATUS_SUCCESS for success or error code 13299 */ 13300 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 13301 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 13302 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 13303 { 13304 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13305 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 13306 13307 if (!evt_buf) { 13308 wmi_err("null evt_buf"); 13309 return QDF_STATUS_E_INVAL; 13310 } 13311 13312 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 13313 13314 if (!param_buf->num_hal_reg_caps) 13315 return QDF_STATUS_SUCCESS; 13316 13317 if (phy_idx >= param_buf->num_hal_reg_caps) 13318 return QDF_STATUS_E_INVAL; 13319 13320 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 13321 13322 param->phy_id = reg_caps->phy_id; 13323 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13324 reg_caps->wireless_modes_ext); 13325 param->low_2ghz_chan_ext = reg_caps->low_2ghz_chan_ext; 13326 param->high_2ghz_chan_ext = reg_caps->high_2ghz_chan_ext; 13327 param->low_5ghz_chan_ext = reg_caps->low_5ghz_chan_ext; 13328 param->high_5ghz_chan_ext = reg_caps->high_5ghz_chan_ext; 13329 13330 return QDF_STATUS_SUCCESS; 13331 } 13332 13333 /** 13334 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 13335 * @wmi_handle: wmi handle 13336 * @evt_buf: pointer to event buffer 13337 * 13338 * Return: Number of entries requested 13339 */ 13340 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 13341 void *evt_buf) 13342 { 13343 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13344 wmi_service_ready_event_fixed_param *ev; 13345 13346 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13347 13348 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13349 if (!ev) { 13350 qdf_print("%s: wmi_buf_alloc failed", __func__); 13351 return 0; 13352 } 13353 13354 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 13355 wmi_err("Invalid num_mem_reqs %d:%d", 13356 ev->num_mem_reqs, param_buf->num_mem_reqs); 13357 return 0; 13358 } 13359 13360 return ev->num_mem_reqs; 13361 } 13362 13363 /** 13364 * extract_host_mem_req_tlv() - Extract host memory required from 13365 * service ready event 13366 * @wmi_handle: wmi handle 13367 * @evt_buf: pointer to event buffer 13368 * @mem_reqs: pointer to host memory request structure 13369 * @num_active_peers: number of active peers for peer cache 13370 * @num_peers: number of peers 13371 * @fw_prio: FW priority 13372 * @idx: index for memory request 13373 * 13374 * Return: Host memory request parameters requested by target 13375 */ 13376 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 13377 void *evt_buf, 13378 host_mem_req *mem_reqs, 13379 uint32_t num_active_peers, 13380 uint32_t num_peers, 13381 enum wmi_fw_mem_prio fw_prio, 13382 uint16_t idx) 13383 { 13384 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13385 13386 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 13387 13388 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 13389 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 13390 mem_reqs->num_unit_info = 13391 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 13392 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 13393 mem_reqs->tgt_num_units = 0; 13394 13395 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 13396 (mem_reqs->num_unit_info & 13397 REQ_TO_HOST_FOR_CONT_MEMORY)) || 13398 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 13399 (!(mem_reqs->num_unit_info & 13400 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 13401 /* First allocate the memory that requires contiguous memory */ 13402 mem_reqs->tgt_num_units = mem_reqs->num_units; 13403 if (mem_reqs->num_unit_info) { 13404 if (mem_reqs->num_unit_info & 13405 NUM_UNITS_IS_NUM_PEERS) { 13406 /* 13407 * number of units allocated is equal to number 13408 * of peers, 1 extra for self peer on target. 13409 * this needs to be fixed, host and target can 13410 * get out of sync 13411 */ 13412 mem_reqs->tgt_num_units = num_peers + 1; 13413 } 13414 if (mem_reqs->num_unit_info & 13415 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 13416 /* 13417 * Requesting allocation of memory using 13418 * num_active_peers in qcache. if qcache is 13419 * disabled in host, then it should allocate 13420 * memory for num_peers instead of 13421 * num_active_peers. 13422 */ 13423 if (num_active_peers) 13424 mem_reqs->tgt_num_units = 13425 num_active_peers + 1; 13426 else 13427 mem_reqs->tgt_num_units = 13428 num_peers + 1; 13429 } 13430 } 13431 13432 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 13433 "unit size %d actual units %d", 13434 idx, mem_reqs->req_id, 13435 mem_reqs->num_units, 13436 mem_reqs->num_unit_info, 13437 mem_reqs->unit_size, 13438 mem_reqs->tgt_num_units); 13439 } 13440 13441 return QDF_STATUS_SUCCESS; 13442 } 13443 13444 /** 13445 * save_fw_version_in_service_ready_tlv() - Save fw version in service 13446 * ready function 13447 * @wmi_handle: wmi handle 13448 * @evt_buf: pointer to event buffer 13449 * 13450 * Return: QDF_STATUS_SUCCESS for success or error code 13451 */ 13452 static QDF_STATUS 13453 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13454 { 13455 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13456 wmi_service_ready_event_fixed_param *ev; 13457 13458 13459 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13460 13461 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13462 if (!ev) { 13463 qdf_print("%s: wmi_buf_alloc failed", __func__); 13464 return QDF_STATUS_E_FAILURE; 13465 } 13466 13467 /*Save fw version from service ready message */ 13468 /*This will be used while sending INIT message */ 13469 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13470 sizeof(wmi_handle->fw_abi_version)); 13471 13472 return QDF_STATUS_SUCCESS; 13473 } 13474 13475 /** 13476 * ready_extract_init_status_tlv() - Extract init status from ready event 13477 * @wmi_handle: wmi handle 13478 * @evt_buf: Pointer to event buffer 13479 * 13480 * Return: ready status 13481 */ 13482 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 13483 void *evt_buf) 13484 { 13485 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13486 wmi_ready_event_fixed_param *ev = NULL; 13487 13488 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13489 ev = param_buf->fixed_param; 13490 13491 wmi_info("%s:%d", __func__, ev->status); 13492 13493 return ev->status; 13494 } 13495 13496 /** 13497 * ready_extract_mac_addr_tlv() - extract mac address from ready event 13498 * @wmi_handle: wmi handle 13499 * @evt_buf: pointer to event buffer 13500 * @macaddr: Pointer to hold MAC address 13501 * 13502 * Return: QDF_STATUS_SUCCESS for success or error code 13503 */ 13504 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 13505 void *evt_buf, uint8_t *macaddr) 13506 { 13507 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13508 wmi_ready_event_fixed_param *ev = NULL; 13509 13510 13511 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13512 ev = param_buf->fixed_param; 13513 13514 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 13515 13516 return QDF_STATUS_SUCCESS; 13517 } 13518 13519 /** 13520 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 13521 * @wmi_handle: wmi handle 13522 * @evt_buf: pointer to event buffer 13523 * @num_mac: Pointer to hold number of MAC addresses 13524 * 13525 * Return: Pointer to addr list 13526 */ 13527 static wmi_host_mac_addr * 13528 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 13529 void *evt_buf, uint8_t *num_mac) 13530 { 13531 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13532 wmi_ready_event_fixed_param *ev = NULL; 13533 13534 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13535 ev = param_buf->fixed_param; 13536 13537 *num_mac = ev->num_extra_mac_addr; 13538 13539 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 13540 } 13541 13542 /** 13543 * extract_ready_event_params_tlv() - Extract data from ready event apart from 13544 * status, macaddr and version. 13545 * @wmi_handle: Pointer to WMI handle. 13546 * @evt_buf: Pointer to Ready event buffer. 13547 * @ev_param: Pointer to host defined struct to copy the data from event. 13548 * 13549 * Return: QDF_STATUS_SUCCESS on success. 13550 */ 13551 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 13552 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 13553 { 13554 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13555 wmi_ready_event_fixed_param *ev = NULL; 13556 13557 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13558 ev = param_buf->fixed_param; 13559 13560 ev_param->status = ev->status; 13561 ev_param->num_dscp_table = ev->num_dscp_table; 13562 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 13563 ev_param->num_total_peer = ev->num_total_peers; 13564 ev_param->num_extra_peer = ev->num_extra_peers; 13565 /* Agile_capability in ready event is supported in TLV target, 13566 * as per aDFS FR 13567 */ 13568 ev_param->max_ast_index = ev->max_ast_index; 13569 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 13570 ev_param->agile_capability = 1; 13571 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 13572 13573 return QDF_STATUS_SUCCESS; 13574 } 13575 13576 /** 13577 * extract_dbglog_data_len_tlv() - extract debuglog data length 13578 * @wmi_handle: wmi handle 13579 * @evt_buf: pointer to event buffer 13580 * @len: length of the log 13581 * 13582 * Return: pointer to the debug log 13583 */ 13584 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 13585 void *evt_buf, uint32_t *len) 13586 { 13587 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 13588 13589 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 13590 13591 *len = param_buf->num_bufp; 13592 13593 return param_buf->bufp; 13594 } 13595 13596 13597 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 13598 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 13599 #else 13600 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 13601 ((_status) & WMI_RXERR_DECRYPT) 13602 #endif 13603 13604 /** 13605 * extract_mgmt_rx_params_tlv() - extract management rx params from event 13606 * @wmi_handle: wmi handle 13607 * @evt_buf: pointer to event buffer 13608 * @hdr: Pointer to hold header 13609 * @bufp: Pointer to hold pointer to rx param buffer 13610 * 13611 * Return: QDF_STATUS_SUCCESS for success or error code 13612 */ 13613 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 13614 void *evt_buf, struct mgmt_rx_event_params *hdr, 13615 uint8_t **bufp) 13616 { 13617 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 13618 wmi_mgmt_rx_hdr *ev_hdr = NULL; 13619 int i; 13620 13621 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13622 if (!param_tlvs) { 13623 wmi_err_rl("Get NULL point message from FW"); 13624 return QDF_STATUS_E_INVAL; 13625 } 13626 13627 ev_hdr = param_tlvs->hdr; 13628 if (!hdr) { 13629 wmi_err_rl("Rx event is NULL"); 13630 return QDF_STATUS_E_INVAL; 13631 } 13632 13633 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 13634 wmi_err_rl("RX mgmt frame decrypt error, discard it"); 13635 return QDF_STATUS_E_INVAL; 13636 } 13637 if ((ev_hdr->status) & WMI_RXERR_MIC) { 13638 wmi_err_rl("RX mgmt frame MIC mismatch for beacon protected frame"); 13639 } 13640 13641 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 13642 wmi_err_rl("Rx mgmt frame length mismatch, discard it"); 13643 return QDF_STATUS_E_INVAL; 13644 } 13645 13646 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13647 wmi_handle, 13648 ev_hdr->pdev_id); 13649 hdr->chan_freq = ev_hdr->chan_freq; 13650 hdr->channel = ev_hdr->channel; 13651 hdr->snr = ev_hdr->snr; 13652 hdr->rate = ev_hdr->rate; 13653 hdr->phy_mode = ev_hdr->phy_mode; 13654 hdr->buf_len = ev_hdr->buf_len; 13655 hdr->status = ev_hdr->status; 13656 hdr->flags = ev_hdr->flags; 13657 hdr->rssi = ev_hdr->rssi; 13658 hdr->tsf_delta = ev_hdr->tsf_delta; 13659 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 13660 for (i = 0; i < ATH_MAX_ANTENNA; i++) 13661 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 13662 13663 *bufp = param_tlvs->bufp; 13664 13665 extract_mgmt_rx_mlo_link_removal_tlv_count( 13666 param_tlvs->num_link_removal_tbtt_count, hdr); 13667 13668 return QDF_STATUS_SUCCESS; 13669 } 13670 13671 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 13672 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 13673 { 13674 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13675 wmi_mgmt_rx_params_ext *ext_params_tlv; 13676 wmi_mgmt_rx_hdr *ev_hdr; 13677 wmi_mgmt_rx_params_ext_meta_t meta_id; 13678 uint8_t *ie_data; 13679 13680 /* initialize to zero and set it only if tlv has valid meta data */ 13681 ext_params->u.addba.ba_win_size = 0; 13682 ext_params->u.addba.reo_win_size = 0; 13683 13684 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13685 if (!param_tlvs) { 13686 wmi_err("param_tlvs is NULL"); 13687 return QDF_STATUS_E_INVAL; 13688 } 13689 13690 ev_hdr = param_tlvs->hdr; 13691 if (!ev_hdr) { 13692 wmi_err("Rx event is NULL"); 13693 return QDF_STATUS_E_INVAL; 13694 } 13695 13696 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 13697 if (ext_params_tlv) { 13698 meta_id = WMI_RX_PARAM_EXT_META_ID_GET( 13699 ext_params_tlv->mgmt_rx_params_ext_dword0); 13700 if (meta_id == WMI_RX_PARAMS_EXT_META_ADDBA) { 13701 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_ADDBA; 13702 ext_params->u.addba.ba_win_size = 13703 WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 13704 ext_params_tlv->mgmt_rx_params_ext_dword1); 13705 if (ext_params->u.addba.ba_win_size > 1024) { 13706 wmi_info("ba win size %d from TLV is Invalid", 13707 ext_params->u.addba.ba_win_size); 13708 return QDF_STATUS_E_INVAL; 13709 } 13710 13711 ext_params->u.addba.reo_win_size = 13712 WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 13713 ext_params_tlv->mgmt_rx_params_ext_dword1); 13714 if (ext_params->u.addba.reo_win_size > 2048) { 13715 wmi_info("reo win size %d from TLV is Invalid", 13716 ext_params->u.addba.reo_win_size); 13717 return QDF_STATUS_E_INVAL; 13718 } 13719 } 13720 if (meta_id == WMI_RX_PARAMS_EXT_META_TWT) { 13721 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_TWT; 13722 ext_params->u.twt.ie_len = 13723 ext_params_tlv->twt_ie_buf_len; 13724 ie_data = param_tlvs->ie_data; 13725 if (ext_params->u.twt.ie_len && 13726 (ext_params->u.twt.ie_len < 13727 MAX_TWT_IE_RX_PARAMS_LEN)) { 13728 qdf_mem_copy(ext_params->u.twt.ie_data, 13729 ie_data, 13730 ext_params_tlv->twt_ie_buf_len); 13731 } 13732 } 13733 } 13734 13735 return QDF_STATUS_SUCCESS; 13736 } 13737 13738 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13739 /** 13740 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13741 * @wmi_handle: wmi handle 13742 * @evt_buf: pointer to event buffer 13743 * @params: Pointer to MGMT Rx REO parameters 13744 * 13745 * Return: QDF_STATUS_SUCCESS for success or error code 13746 */ 13747 static QDF_STATUS 13748 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13749 void *evt_buf, 13750 struct mgmt_rx_reo_params *params) 13751 { 13752 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13753 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13754 13755 param_tlvs = evt_buf; 13756 if (!param_tlvs) { 13757 wmi_err("param_tlvs is NULL"); 13758 return QDF_STATUS_E_INVAL; 13759 } 13760 13761 ev_hdr = param_tlvs->hdr; 13762 if (!params) { 13763 wmi_err("Rx REO parameters is NULL"); 13764 return QDF_STATUS_E_INVAL; 13765 } 13766 13767 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13768 wmi_handle, 13769 ev_hdr->pdev_id); 13770 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13771 ev_hdr->mgmt_pkt_ctr_info); 13772 params->global_timestamp = ev_hdr->global_timestamp; 13773 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13774 ev_hdr->mgmt_pkt_ctr_info); 13775 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13776 params->start_timestamp = params->global_timestamp; 13777 params->end_timestamp = params->start_timestamp + 13778 params->duration_us; 13779 13780 return QDF_STATUS_SUCCESS; 13781 } 13782 13783 /** 13784 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13785 * MGMT_RX_EVENT_ID 13786 * @wmi_handle: wmi handle 13787 * @evt_buf: pointer to event buffer 13788 * @reo_params: Pointer to MGMT Rx REO parameters 13789 * 13790 * Return: QDF_STATUS_SUCCESS for success or error code 13791 */ 13792 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13793 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13794 { 13795 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13796 wmi_mgmt_rx_reo_params *reo_params_tlv; 13797 wmi_mgmt_rx_hdr *ev_hdr; 13798 13799 param_tlvs = evt_buf; 13800 if (!param_tlvs) { 13801 wmi_err("param_tlvs is NULL"); 13802 return QDF_STATUS_E_INVAL; 13803 } 13804 13805 ev_hdr = param_tlvs->hdr; 13806 if (!ev_hdr) { 13807 wmi_err("Rx event is NULL"); 13808 return QDF_STATUS_E_INVAL; 13809 } 13810 13811 reo_params_tlv = param_tlvs->reo_params; 13812 if (!reo_params_tlv) { 13813 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13814 return QDF_STATUS_E_INVAL; 13815 } 13816 13817 if (!reo_params) { 13818 wmi_err("MGMT Rx REO params is NULL"); 13819 return QDF_STATUS_E_INVAL; 13820 } 13821 13822 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13823 wmi_handle, 13824 ev_hdr->pdev_id); 13825 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13826 reo_params_tlv->mgmt_pkt_ctr_link_info); 13827 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13828 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13829 reo_params_tlv->mgmt_pkt_ctr_link_info); 13830 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13831 reo_params->start_timestamp = reo_params->global_timestamp; 13832 reo_params->end_timestamp = reo_params->start_timestamp + 13833 reo_params->duration_us; 13834 13835 return QDF_STATUS_SUCCESS; 13836 } 13837 13838 /** 13839 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13840 * configuration command 13841 * @wmi_handle: wmi handle 13842 * @pdev_id: pdev ID of the radio 13843 * @filter: Pointer to MGMT Rx REO filter 13844 * 13845 * Return: QDF_STATUS_SUCCESS for success or error code 13846 */ 13847 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13848 wmi_unified_t wmi_handle, 13849 uint8_t pdev_id, 13850 struct mgmt_rx_reo_filter *filter) 13851 { 13852 QDF_STATUS ret; 13853 wmi_buf_t buf; 13854 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13855 size_t len = sizeof(*cmd); 13856 13857 if (!filter) { 13858 wmi_err("mgmt_rx_reo_filter is NULL"); 13859 return QDF_STATUS_E_INVAL; 13860 } 13861 13862 buf = wmi_buf_alloc(wmi_handle, len); 13863 if (!buf) { 13864 wmi_err("wmi_buf_alloc failed"); 13865 return QDF_STATUS_E_NOMEM; 13866 } 13867 13868 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13869 wmi_buf_data(buf); 13870 13871 WMITLV_SET_HDR(&cmd->tlv_header, 13872 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13873 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13874 13875 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13876 wmi_handle, 13877 pdev_id); 13878 cmd->filter_low = filter->low; 13879 cmd->filter_high = filter->high; 13880 13881 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13882 ret = wmi_unified_cmd_send( 13883 wmi_handle, buf, len, 13884 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13885 13886 if (QDF_IS_STATUS_ERROR(ret)) { 13887 wmi_err("Failed to send WMI command"); 13888 wmi_buf_free(buf); 13889 } 13890 13891 return ret; 13892 } 13893 #endif 13894 13895 /** 13896 * extract_frame_pn_params_tlv() - extract PN params from event 13897 * @wmi_handle: wmi handle 13898 * @evt_buf: pointer to event buffer 13899 * @pn_params: Pointer to Frame PN params 13900 * 13901 * Return: QDF_STATUS_SUCCESS for success or error code 13902 */ 13903 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13904 void *evt_buf, 13905 struct frame_pn_params *pn_params) 13906 { 13907 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13908 wmi_frame_pn_params *pn_params_tlv; 13909 13910 if (!is_service_enabled_tlv(wmi_handle, 13911 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13912 return QDF_STATUS_SUCCESS; 13913 13914 param_tlvs = evt_buf; 13915 if (!param_tlvs) { 13916 wmi_err("Got NULL point message from FW"); 13917 return QDF_STATUS_E_INVAL; 13918 } 13919 13920 if (!pn_params) { 13921 wmi_err("PN Params is NULL"); 13922 return QDF_STATUS_E_INVAL; 13923 } 13924 13925 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13926 * found by target 13927 */ 13928 pn_params_tlv = param_tlvs->pn_params; 13929 if (!pn_params_tlv) 13930 return QDF_STATUS_SUCCESS; 13931 13932 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13933 sizeof(pn_params->curr_pn)); 13934 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13935 sizeof(pn_params->prev_pn)); 13936 13937 return QDF_STATUS_SUCCESS; 13938 } 13939 13940 /** 13941 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13942 * event 13943 * @wmi_handle: wmi handle 13944 * @evt_buf: pointer to event buffer 13945 * @is_conn_ap: Pointer for is_conn_ap frame 13946 * 13947 * Return: QDF_STATUS_SUCCESS for success or error code 13948 */ 13949 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13950 wmi_unified_t wmi_handle, 13951 void *evt_buf, 13952 struct frm_conn_ap *is_conn_ap) 13953 { 13954 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13955 wmi_is_my_mgmt_frame *my_frame_tlv; 13956 13957 param_tlvs = evt_buf; 13958 if (!param_tlvs) { 13959 wmi_err("Got NULL point message from FW"); 13960 return QDF_STATUS_E_INVAL; 13961 } 13962 13963 if (!is_conn_ap) { 13964 wmi_err(" is connected ap param is NULL"); 13965 return QDF_STATUS_E_INVAL; 13966 } 13967 13968 my_frame_tlv = param_tlvs->my_frame; 13969 if (!my_frame_tlv) 13970 return QDF_STATUS_SUCCESS; 13971 13972 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13973 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13974 13975 return QDF_STATUS_SUCCESS; 13976 } 13977 13978 /** 13979 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13980 * @wmi_handle: wmi handle 13981 * @evt_buf: pointer to event buffer 13982 * @param: Pointer to hold roam param 13983 * 13984 * Return: QDF_STATUS_SUCCESS for success or error code 13985 */ 13986 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13987 void *evt_buf, wmi_host_roam_event *param) 13988 { 13989 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13990 wmi_roam_event_fixed_param *evt; 13991 13992 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13993 if (!param_buf) { 13994 wmi_err("Invalid roam event buffer"); 13995 return QDF_STATUS_E_INVAL; 13996 } 13997 13998 evt = param_buf->fixed_param; 13999 qdf_mem_zero(param, sizeof(*param)); 14000 14001 param->vdev_id = evt->vdev_id; 14002 param->reason = evt->reason; 14003 param->rssi = evt->rssi; 14004 14005 return QDF_STATUS_SUCCESS; 14006 } 14007 14008 /** 14009 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 14010 * @wmi_handle: wmi handle 14011 * @evt_buf: pointer to event buffer 14012 * @param: Pointer to hold vdev scan param 14013 * 14014 * Return: QDF_STATUS_SUCCESS for success or error code 14015 */ 14016 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 14017 void *evt_buf, struct scan_event *param) 14018 { 14019 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 14020 wmi_scan_event_fixed_param *evt = NULL; 14021 14022 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 14023 evt = param_buf->fixed_param; 14024 14025 qdf_mem_zero(param, sizeof(*param)); 14026 14027 switch (evt->event) { 14028 case WMI_SCAN_EVENT_STARTED: 14029 param->type = SCAN_EVENT_TYPE_STARTED; 14030 break; 14031 case WMI_SCAN_EVENT_COMPLETED: 14032 param->type = SCAN_EVENT_TYPE_COMPLETED; 14033 break; 14034 case WMI_SCAN_EVENT_BSS_CHANNEL: 14035 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 14036 break; 14037 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 14038 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 14039 break; 14040 case WMI_SCAN_EVENT_DEQUEUED: 14041 param->type = SCAN_EVENT_TYPE_DEQUEUED; 14042 break; 14043 case WMI_SCAN_EVENT_PREEMPTED: 14044 param->type = SCAN_EVENT_TYPE_PREEMPTED; 14045 break; 14046 case WMI_SCAN_EVENT_START_FAILED: 14047 param->type = SCAN_EVENT_TYPE_START_FAILED; 14048 break; 14049 case WMI_SCAN_EVENT_RESTARTED: 14050 param->type = SCAN_EVENT_TYPE_RESTARTED; 14051 break; 14052 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 14053 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 14054 break; 14055 case WMI_SCAN_EVENT_MAX: 14056 default: 14057 param->type = SCAN_EVENT_TYPE_MAX; 14058 break; 14059 }; 14060 14061 switch (evt->reason) { 14062 case WMI_SCAN_REASON_NONE: 14063 param->reason = SCAN_REASON_NONE; 14064 break; 14065 case WMI_SCAN_REASON_COMPLETED: 14066 param->reason = SCAN_REASON_COMPLETED; 14067 break; 14068 case WMI_SCAN_REASON_CANCELLED: 14069 param->reason = SCAN_REASON_CANCELLED; 14070 break; 14071 case WMI_SCAN_REASON_PREEMPTED: 14072 param->reason = SCAN_REASON_PREEMPTED; 14073 break; 14074 case WMI_SCAN_REASON_TIMEDOUT: 14075 param->reason = SCAN_REASON_TIMEDOUT; 14076 break; 14077 case WMI_SCAN_REASON_INTERNAL_FAILURE: 14078 param->reason = SCAN_REASON_INTERNAL_FAILURE; 14079 break; 14080 case WMI_SCAN_REASON_SUSPENDED: 14081 param->reason = SCAN_REASON_SUSPENDED; 14082 break; 14083 case WMI_SCAN_REASON_DFS_VIOLATION: 14084 param->reason = SCAN_REASON_DFS_VIOLATION; 14085 break; 14086 case WMI_SCAN_REASON_MAX: 14087 param->reason = SCAN_REASON_MAX; 14088 break; 14089 default: 14090 param->reason = SCAN_REASON_MAX; 14091 break; 14092 }; 14093 14094 param->chan_freq = evt->channel_freq; 14095 param->requester = evt->requestor; 14096 param->scan_id = evt->scan_id; 14097 param->vdev_id = evt->vdev_id; 14098 param->timestamp = evt->tsf_timestamp; 14099 14100 return QDF_STATUS_SUCCESS; 14101 } 14102 14103 #ifdef FEATURE_WLAN_SCAN_PNO 14104 /** 14105 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 14106 * @wmi_handle: pointer to WMI handle 14107 * @evt_buf: pointer to WMI event buffer 14108 * @param: pointer to scan event param for NLO match 14109 * 14110 * Return: QDF_STATUS_SUCCESS for success or error code 14111 */ 14112 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 14113 void *evt_buf, 14114 struct scan_event *param) 14115 { 14116 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 14117 wmi_nlo_event *evt = param_buf->fixed_param; 14118 14119 qdf_mem_zero(param, sizeof(*param)); 14120 14121 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 14122 param->vdev_id = evt->vdev_id; 14123 14124 return QDF_STATUS_SUCCESS; 14125 } 14126 14127 /** 14128 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 14129 * @wmi_handle: pointer to WMI handle 14130 * @evt_buf: pointer to WMI event buffer 14131 * @param: pointer to scan event param for NLO complete 14132 * 14133 * Return: QDF_STATUS_SUCCESS for success or error code 14134 */ 14135 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 14136 void *evt_buf, 14137 struct scan_event *param) 14138 { 14139 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 14140 wmi_nlo_event *evt = param_buf->fixed_param; 14141 14142 qdf_mem_zero(param, sizeof(*param)); 14143 14144 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 14145 param->vdev_id = evt->vdev_id; 14146 14147 return QDF_STATUS_SUCCESS; 14148 } 14149 #endif 14150 14151 /** 14152 * extract_unit_test_tlv() - extract unit test data 14153 * @wmi_handle: wmi handle 14154 * @evt_buf: pointer to event buffer 14155 * @unit_test: pointer to hold unit test data 14156 * @maxspace: Amount of space in evt_buf 14157 * 14158 * Return: QDF_STATUS_SUCCESS for success or error code 14159 */ 14160 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 14161 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 14162 { 14163 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 14164 wmi_unit_test_event_fixed_param *ev_param; 14165 uint32_t num_bufp; 14166 uint32_t copy_size; 14167 uint8_t *bufp; 14168 14169 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 14170 ev_param = param_buf->fixed_param; 14171 bufp = param_buf->bufp; 14172 num_bufp = param_buf->num_bufp; 14173 unit_test->vdev_id = ev_param->vdev_id; 14174 unit_test->module_id = ev_param->module_id; 14175 unit_test->diag_token = ev_param->diag_token; 14176 unit_test->flag = ev_param->flag; 14177 unit_test->payload_len = ev_param->payload_len; 14178 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 14179 ev_param->vdev_id, 14180 ev_param->module_id, 14181 ev_param->diag_token, 14182 ev_param->flag); 14183 wmi_debug("Unit-test data given below %d", num_bufp); 14184 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 14185 bufp, num_bufp); 14186 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 14187 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 14188 unit_test->buffer_len = copy_size; 14189 14190 return QDF_STATUS_SUCCESS; 14191 } 14192 14193 /** 14194 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 14195 * @wmi_handle: wmi handle 14196 * @evt_buf: pointer to event buffer 14197 * @index: Index into extended pdev stats 14198 * @pdev_ext_stats: Pointer to hold extended pdev stats 14199 * 14200 * Return: QDF_STATUS_SUCCESS for success or error code 14201 */ 14202 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 14203 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 14204 { 14205 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14206 wmi_pdev_extd_stats *ev; 14207 14208 param_buf = evt_buf; 14209 if (!param_buf) 14210 return QDF_STATUS_E_FAILURE; 14211 14212 if (!param_buf->pdev_extd_stats) 14213 return QDF_STATUS_E_FAILURE; 14214 14215 ev = param_buf->pdev_extd_stats + index; 14216 14217 pdev_ext_stats->pdev_id = 14218 wmi_handle->ops->convert_target_pdev_id_to_host( 14219 wmi_handle, 14220 ev->pdev_id); 14221 pdev_ext_stats->my_rx_count = ev->my_rx_count; 14222 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 14223 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 14224 14225 return QDF_STATUS_SUCCESS; 14226 } 14227 14228 /** 14229 * extract_bcn_stats_tlv() - extract bcn stats from event 14230 * @wmi_handle: wmi handle 14231 * @evt_buf: pointer to event buffer 14232 * @index: Index into vdev stats 14233 * @bcn_stats: Pointer to hold bcn stats 14234 * 14235 * Return: QDF_STATUS_SUCCESS for success or error code 14236 */ 14237 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 14238 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 14239 { 14240 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14241 wmi_stats_event_fixed_param *ev_param; 14242 uint8_t *data; 14243 14244 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14245 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14246 data = (uint8_t *) param_buf->data; 14247 14248 if (index < ev_param->num_bcn_stats) { 14249 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 14250 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14251 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14252 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14253 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 14254 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 14255 (index * sizeof(wmi_bcn_stats))); 14256 14257 bcn_stats->vdev_id = ev->vdev_id; 14258 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 14259 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 14260 } 14261 14262 return QDF_STATUS_SUCCESS; 14263 } 14264 14265 #ifdef WLAN_FEATURE_11BE_MLO 14266 /** 14267 * wmi_is_mlo_vdev_active() - get if mlo vdev is active or not 14268 * @flag: vdev link status info 14269 * 14270 * Return: True if active, else False 14271 */ 14272 static bool wmi_is_mlo_vdev_active(uint32_t flag) 14273 { 14274 if ((flag & WMI_VDEV_STATS_FLAGS_LINK_ACTIVE_FLAG_IS_VALID_MASK) && 14275 (flag & WMI_VDEV_STATS_FLAGS_IS_LINK_ACTIVE_MASK)) 14276 return true; 14277 14278 return false; 14279 } 14280 14281 static QDF_STATUS 14282 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14283 wmi_vdev_extd_stats *ev, 14284 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14285 { 14286 if (!param_buf->num_vdev_extd_stats) { 14287 wmi_err("No vdev_extd_stats in the event buffer"); 14288 return QDF_STATUS_E_INVAL; 14289 } 14290 14291 vdev_stats->is_mlo_vdev_active = wmi_is_mlo_vdev_active(ev->flags); 14292 return QDF_STATUS_SUCCESS; 14293 } 14294 #else 14295 static QDF_STATUS 14296 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14297 wmi_vdev_extd_stats *ev, 14298 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14299 { 14300 return QDF_STATUS_SUCCESS; 14301 } 14302 #endif 14303 14304 /** 14305 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 14306 * stats from event 14307 * @wmi_handle: wmi handle 14308 * @evt_buf: pointer to event buffer 14309 * @index: Index into vdev stats 14310 * @vdev_stats: Pointer to hold vdev probe and fils stats 14311 * 14312 * Return: QDF_STATUS_SUCCESS for success or error code 14313 */ 14314 static QDF_STATUS 14315 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 14316 void *evt_buf, uint32_t index, 14317 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14318 { 14319 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14320 wmi_vdev_extd_stats *ev; 14321 QDF_STATUS status = QDF_STATUS_SUCCESS; 14322 14323 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 14324 14325 if (param_buf->vdev_extd_stats) { 14326 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 14327 index); 14328 vdev_stats->vdev_id = ev->vdev_id; 14329 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 14330 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 14331 vdev_stats->unsolicited_prb_succ_cnt = 14332 ev->unsolicited_prb_succ_cnt; 14333 vdev_stats->unsolicited_prb_fail_cnt = 14334 ev->unsolicited_prb_fail_cnt; 14335 status = extract_mlo_vdev_status_info(param_buf, ev, 14336 vdev_stats); 14337 vdev_stats->vdev_tx_power = ev->vdev_tx_power; 14338 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 14339 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 14340 ev->unsolicited_prb_succ_cnt, 14341 ev->unsolicited_prb_fail_cnt); 14342 wmi_debug("vdev txpwr: %d", ev->vdev_tx_power); 14343 } 14344 14345 return status; 14346 } 14347 14348 /** 14349 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 14350 * @wmi_handle: wmi handle 14351 * @evt_buf: pointer to event buffer 14352 * @index: Index into bcn fault stats 14353 * @bcnflt_stats: Pointer to hold bcn fault stats 14354 * 14355 * Return: QDF_STATUS_SUCCESS for success or error code 14356 */ 14357 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 14358 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 14359 { 14360 return QDF_STATUS_SUCCESS; 14361 } 14362 14363 /** 14364 * extract_chan_stats_tlv() - extract chan stats from event 14365 * @wmi_handle: wmi handle 14366 * @evt_buf: pointer to event buffer 14367 * @index: Index into chan stats 14368 * @chan_stats: Pointer to hold chan stats 14369 * 14370 * Return: QDF_STATUS_SUCCESS for success or error code 14371 */ 14372 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 14373 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 14374 { 14375 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14376 wmi_stats_event_fixed_param *ev_param; 14377 uint8_t *data; 14378 14379 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14380 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14381 data = (uint8_t *) param_buf->data; 14382 14383 if (index < ev_param->num_chan_stats) { 14384 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 14385 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14386 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14387 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14388 (index * sizeof(wmi_chan_stats))); 14389 14390 14391 /* Non-TLV doesn't have num_chan_stats */ 14392 chan_stats->chan_mhz = ev->chan_mhz; 14393 chan_stats->sampling_period_us = ev->sampling_period_us; 14394 chan_stats->rx_clear_count = ev->rx_clear_count; 14395 chan_stats->tx_duration_us = ev->tx_duration_us; 14396 chan_stats->rx_duration_us = ev->rx_duration_us; 14397 } 14398 14399 return QDF_STATUS_SUCCESS; 14400 } 14401 14402 /** 14403 * extract_profile_ctx_tlv() - extract profile context from event 14404 * @wmi_handle: wmi handle 14405 * @evt_buf: pointer to event buffer 14406 * @profile_ctx: Pointer to hold profile context 14407 * 14408 * Return: QDF_STATUS_SUCCESS for success or error code 14409 */ 14410 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 14411 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 14412 { 14413 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14414 14415 wmi_wlan_profile_ctx_t *ev; 14416 14417 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14418 if (!param_buf) { 14419 wmi_err("Invalid profile data event buf"); 14420 return QDF_STATUS_E_INVAL; 14421 } 14422 14423 ev = param_buf->profile_ctx; 14424 14425 profile_ctx->tot = ev->tot; 14426 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 14427 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 14428 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 14429 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 14430 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 14431 profile_ctx->bin_count = ev->bin_count; 14432 14433 return QDF_STATUS_SUCCESS; 14434 } 14435 14436 /** 14437 * extract_profile_data_tlv() - extract profile data from event 14438 * @wmi_handle: wmi handle 14439 * @evt_buf: pointer to event buffer 14440 * @idx: profile stats index to extract 14441 * @profile_data: Pointer to hold profile data 14442 * 14443 * Return: QDF_STATUS_SUCCESS for success or error code 14444 */ 14445 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 14446 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 14447 { 14448 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14449 wmi_wlan_profile_t *ev; 14450 14451 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14452 if (!param_buf) { 14453 wmi_err("Invalid profile data event buf"); 14454 return QDF_STATUS_E_INVAL; 14455 } 14456 14457 ev = ¶m_buf->profile_data[idx]; 14458 profile_data->id = ev->id; 14459 profile_data->cnt = ev->cnt; 14460 profile_data->tot = ev->tot; 14461 profile_data->min = ev->min; 14462 profile_data->max = ev->max; 14463 profile_data->hist_intvl = ev->hist_intvl; 14464 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 14465 14466 return QDF_STATUS_SUCCESS; 14467 } 14468 14469 /** 14470 * extract_pdev_utf_event_tlv() - extract UTF data info from event 14471 * @wmi_handle: WMI handle 14472 * @evt_buf: Pointer to event buffer 14473 * @event: Pointer to hold data 14474 * 14475 * Return: QDF_STATUS_SUCCESS for success or error code 14476 */ 14477 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 14478 uint8_t *evt_buf, 14479 struct wmi_host_pdev_utf_event *event) 14480 { 14481 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 14482 struct wmi_host_utf_seg_header_info *seg_hdr; 14483 wmi_pdev_utf_event_fixed_param *ev_param; 14484 bool is_pdev_id_over_utf; 14485 14486 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 14487 event->data = param_buf->data; 14488 event->datalen = param_buf->num_data; 14489 14490 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 14491 wmi_err("Invalid datalen: %d", event->datalen); 14492 return QDF_STATUS_E_INVAL; 14493 } 14494 14495 is_pdev_id_over_utf = is_service_enabled_tlv(wmi_handle, 14496 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI); 14497 if (is_pdev_id_over_utf && param_buf->fixed_param && 14498 param_buf->num_fixed_param) { 14499 ev_param = 14500 (wmi_pdev_utf_event_fixed_param *)param_buf->fixed_param; 14501 event->pdev_id = 14502 wmi_handle->ops->convert_pdev_id_target_to_host( 14503 wmi_handle, 14504 ev_param->pdev_id); 14505 } else { 14506 seg_hdr = 14507 (struct wmi_host_utf_seg_header_info *)param_buf->data; 14508 event->pdev_id = 14509 wmi_handle->ops->convert_pdev_id_target_to_host( 14510 wmi_handle, 14511 seg_hdr->pdev_id); 14512 } 14513 14514 return QDF_STATUS_SUCCESS; 14515 } 14516 14517 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14518 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14519 uint8_t *event, 14520 uint32_t *num_rf_characterization_entries) 14521 { 14522 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14523 14524 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14525 if (!param_buf) 14526 return QDF_STATUS_E_INVAL; 14527 14528 *num_rf_characterization_entries = 14529 param_buf->num_wmi_chan_rf_characterization_info; 14530 14531 return QDF_STATUS_SUCCESS; 14532 } 14533 14534 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14535 uint8_t *event, 14536 uint32_t num_rf_characterization_entries, 14537 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 14538 { 14539 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14540 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 14541 uint8_t ix; 14542 14543 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14544 if (!param_buf) 14545 return QDF_STATUS_E_INVAL; 14546 14547 wmi_rf_characterization_entry = 14548 param_buf->wmi_chan_rf_characterization_info; 14549 if (!wmi_rf_characterization_entry) 14550 return QDF_STATUS_E_INVAL; 14551 14552 /* 14553 * Using num_wmi_chan_rf_characterization instead of param_buf value 14554 * since memory for rf_characterization_entries was allocated using 14555 * the former. 14556 */ 14557 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 14558 rf_characterization_entries[ix].freq = 14559 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 14560 &wmi_rf_characterization_entry[ix]); 14561 14562 rf_characterization_entries[ix].bw = 14563 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 14564 &wmi_rf_characterization_entry[ix]); 14565 14566 rf_characterization_entries[ix].chan_metric = 14567 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 14568 &wmi_rf_characterization_entry[ix]); 14569 14570 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 14571 "bw: %u, chan_metric: %u", 14572 ix, rf_characterization_entries[ix].freq, 14573 rf_characterization_entries[ix].bw, 14574 rf_characterization_entries[ix].chan_metric); 14575 } 14576 14577 return QDF_STATUS_SUCCESS; 14578 } 14579 #endif 14580 14581 #ifdef WLAN_FEATURE_11BE 14582 static void 14583 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14584 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14585 { 14586 cap->supports_chan_width_320 = 14587 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 14588 cap->supports_aDFS_320 = 14589 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 14590 } 14591 #else 14592 static void 14593 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14594 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14595 { 14596 } 14597 #endif /* WLAN_FEATURE_11BE */ 14598 14599 /** 14600 * extract_chainmask_tables_tlv() - extract chain mask tables from event 14601 * @wmi_handle: wmi handle 14602 * @event: pointer to event buffer 14603 * @chainmask_table: Pointer to hold extracted chainmask tables 14604 * 14605 * Return: QDF_STATUS_SUCCESS for success or error code 14606 */ 14607 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 14608 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 14609 { 14610 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14611 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 14612 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14613 uint8_t i = 0, j = 0; 14614 uint32_t num_mac_phy_chainmask_caps = 0; 14615 14616 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14617 if (!param_buf) 14618 return QDF_STATUS_E_INVAL; 14619 14620 hw_caps = param_buf->soc_hw_mode_caps; 14621 if (!hw_caps) 14622 return QDF_STATUS_E_INVAL; 14623 14624 if ((!hw_caps->num_chainmask_tables) || 14625 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 14626 (hw_caps->num_chainmask_tables > 14627 param_buf->num_mac_phy_chainmask_combo)) 14628 return QDF_STATUS_E_INVAL; 14629 14630 chainmask_caps = param_buf->mac_phy_chainmask_caps; 14631 14632 if (!chainmask_caps) 14633 return QDF_STATUS_E_INVAL; 14634 14635 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14636 if (chainmask_table[i].num_valid_chainmasks > 14637 (UINT_MAX - num_mac_phy_chainmask_caps)) { 14638 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 14639 num_mac_phy_chainmask_caps, i, 14640 chainmask_table[i].num_valid_chainmasks); 14641 return QDF_STATUS_E_INVAL; 14642 } 14643 num_mac_phy_chainmask_caps += 14644 chainmask_table[i].num_valid_chainmasks; 14645 } 14646 14647 if (num_mac_phy_chainmask_caps > 14648 param_buf->num_mac_phy_chainmask_caps) { 14649 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 14650 num_mac_phy_chainmask_caps, 14651 param_buf->num_mac_phy_chainmask_caps); 14652 return QDF_STATUS_E_INVAL; 14653 } 14654 14655 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14656 14657 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 14658 i); 14659 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 14660 14661 chainmask_table[i].cap_list[j].chainmask = 14662 chainmask_caps->chainmask; 14663 14664 chainmask_table[i].cap_list[j].supports_chan_width_20 = 14665 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 14666 14667 chainmask_table[i].cap_list[j].supports_chan_width_40 = 14668 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 14669 14670 chainmask_table[i].cap_list[j].supports_chan_width_80 = 14671 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 14672 14673 chainmask_table[i].cap_list[j].supports_chan_width_160 = 14674 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 14675 14676 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 14677 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 14678 14679 chainmask_table[i].cap_list[j].chain_mask_2G = 14680 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 14681 14682 chainmask_table[i].cap_list[j].chain_mask_5G = 14683 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 14684 14685 chainmask_table[i].cap_list[j].chain_mask_tx = 14686 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 14687 14688 chainmask_table[i].cap_list[j].chain_mask_rx = 14689 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 14690 14691 chainmask_table[i].cap_list[j].supports_aDFS = 14692 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 14693 14694 chainmask_table[i].cap_list[j].supports_aSpectral = 14695 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 14696 14697 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 14698 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 14699 14700 chainmask_table[i].cap_list[j].supports_aDFS_160 = 14701 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 14702 14703 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 14704 chainmask_caps); 14705 14706 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 14707 chainmask_caps->supported_flags, 14708 chainmask_caps->chainmask); 14709 chainmask_caps++; 14710 } 14711 } 14712 14713 return QDF_STATUS_SUCCESS; 14714 } 14715 14716 /** 14717 * extract_service_ready_ext_tlv() - extract basic extended service ready params 14718 * from event 14719 * @wmi_handle: wmi handle 14720 * @event: pointer to event buffer 14721 * @param: Pointer to hold evt buf 14722 * 14723 * Return: QDF_STATUS_SUCCESS for success or error code 14724 */ 14725 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 14726 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 14727 { 14728 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14729 wmi_service_ready_ext_event_fixed_param *ev; 14730 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14731 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14732 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 14733 uint8_t i = 0; 14734 14735 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14736 if (!param_buf) 14737 return QDF_STATUS_E_INVAL; 14738 14739 ev = param_buf->fixed_param; 14740 if (!ev) 14741 return QDF_STATUS_E_INVAL; 14742 14743 /* Move this to host based bitmap */ 14744 param->default_conc_scan_config_bits = 14745 ev->default_conc_scan_config_bits; 14746 param->default_fw_config_bits = ev->default_fw_config_bits; 14747 param->he_cap_info = ev->he_cap_info; 14748 param->mpdu_density = ev->mpdu_density; 14749 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 14750 param->fw_build_vers_ext = ev->fw_build_vers_ext; 14751 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14752 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 14753 param->max_bssid_indicator = ev->max_bssid_indicator; 14754 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 14755 14756 hw_caps = param_buf->soc_hw_mode_caps; 14757 if (hw_caps) 14758 param->num_hw_modes = hw_caps->num_hw_modes; 14759 else 14760 param->num_hw_modes = 0; 14761 14762 reg_caps = param_buf->soc_hal_reg_caps; 14763 if (reg_caps) 14764 param->num_phy = reg_caps->num_phy; 14765 else 14766 param->num_phy = 0; 14767 14768 if (hw_caps) { 14769 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 14770 wmi_nofl_debug("Num chain mask tables: %d", 14771 hw_caps->num_chainmask_tables); 14772 } else 14773 param->num_chainmask_tables = 0; 14774 14775 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 14776 param->num_chainmask_tables > 14777 param_buf->num_mac_phy_chainmask_combo) { 14778 wmi_err_rl("num_chainmask_tables is OOB: %u", 14779 param->num_chainmask_tables); 14780 return QDF_STATUS_E_INVAL; 14781 } 14782 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 14783 14784 if (!chain_mask_combo) 14785 return QDF_STATUS_SUCCESS; 14786 14787 wmi_nofl_info_high("Dumping chain mask combo data"); 14788 14789 for (i = 0; i < param->num_chainmask_tables; i++) { 14790 14791 wmi_nofl_info_high("table_id : %d Num valid chainmasks: %d", 14792 chain_mask_combo->chainmask_table_id, 14793 chain_mask_combo->num_valid_chainmask); 14794 14795 param->chainmask_table[i].table_id = 14796 chain_mask_combo->chainmask_table_id; 14797 param->chainmask_table[i].num_valid_chainmasks = 14798 chain_mask_combo->num_valid_chainmask; 14799 chain_mask_combo++; 14800 } 14801 wmi_nofl_info_high("chain mask combo end"); 14802 14803 return QDF_STATUS_SUCCESS; 14804 } 14805 14806 #if defined(CONFIG_AFC_SUPPORT) 14807 /** 14808 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14809 * type from event 14810 * @ev: pointer to event fixed param 14811 * @param: Pointer to hold the params 14812 * 14813 * Return: void 14814 */ 14815 static void 14816 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14817 struct wlan_psoc_host_service_ext2_param *param) 14818 { 14819 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14820 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14821 14822 tgt_afc_dev_type = ev->afc_deployment_type; 14823 switch (tgt_afc_dev_type) { 14824 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14825 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14826 break; 14827 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14828 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14829 break; 14830 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14831 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14832 break; 14833 default: 14834 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14835 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14836 break; 14837 } 14838 param->afc_dev_type = reg_afc_dev_type; 14839 14840 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14841 } 14842 #else 14843 static inline void 14844 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14845 struct wlan_psoc_host_service_ext2_param *param) 14846 { 14847 } 14848 #endif 14849 14850 /** 14851 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14852 * @param: Pointer to hold the params 14853 * 14854 * Return: Void 14855 */ 14856 static void 14857 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14858 { 14859 uint32_t tgt_cap = param->target_cap_flags; 14860 14861 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14862 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14863 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14864 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14865 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14866 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14867 } 14868 14869 /** 14870 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14871 * type from event 14872 * @ev: pointer to event fixed param 14873 * 14874 * Return: void 14875 */ 14876 14877 static void 14878 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14879 { 14880 uint8_t hw_bdf_s; 14881 14882 hw_bdf_s = ev->hw_bd_status; 14883 switch (hw_bdf_s) { 14884 case WMI_BDF_VERSION_CHECK_DISABLED: 14885 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14886 hw_bdf_s); 14887 break; 14888 case WMI_BDF_VERSION_CHECK_GOOD: 14889 wmi_info("BDF VER is %d, FW and BDF ver check good", 14890 hw_bdf_s); 14891 break; 14892 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14893 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14894 hw_bdf_s); 14895 break; 14896 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14897 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14898 hw_bdf_s); 14899 break; 14900 case WMI_BDF_VERSION_FW_TOO_OLD: 14901 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14902 hw_bdf_s); 14903 break; 14904 case WMI_BDF_VERSION_FW_TOO_NEW: 14905 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14906 hw_bdf_s); 14907 break; 14908 default: 14909 wmi_info("unknown BDF VER %d", hw_bdf_s); 14910 break; 14911 } 14912 } 14913 14914 #ifdef QCA_MULTIPASS_SUPPORT 14915 static void 14916 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14917 uint32_t target_cap_flag) 14918 { 14919 param->is_multipass_sap = 14920 WMI_TARGET_CAP_MULTIPASS_SAP_SUPPORT_GET(target_cap_flag); 14921 } 14922 #else 14923 static void 14924 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14925 uint32_t target_cap_flag) 14926 { 14927 } 14928 #endif 14929 14930 #if defined(WLAN_FEATURE_11BE_MLO_ADV_FEATURE) 14931 static inline void 14932 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14933 struct wlan_psoc_host_service_ext2_param *param) 14934 { 14935 param->num_max_mlo_link_per_ml_bss_supp = 14936 ev->num_max_mlo_link_per_ml_bss_supp; 14937 14938 wmi_debug("Firmware Max MLO link support: %d", 14939 param->num_max_mlo_link_per_ml_bss_supp); 14940 } 14941 #else 14942 static inline void 14943 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14944 struct wlan_psoc_host_service_ext2_param *param) 14945 { 14946 } 14947 #endif 14948 14949 /** 14950 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14951 * event 14952 * @wmi_handle: wmi handle 14953 * @event: pointer to event buffer 14954 * @param: Pointer to hold the params 14955 * 14956 * Return: QDF_STATUS_SUCCESS for success or error code 14957 */ 14958 static QDF_STATUS 14959 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14960 struct wlan_psoc_host_service_ext2_param *param) 14961 { 14962 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14963 wmi_service_ready_ext2_event_fixed_param *ev; 14964 14965 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14966 if (!param_buf) 14967 return QDF_STATUS_E_INVAL; 14968 14969 ev = param_buf->fixed_param; 14970 if (!ev) 14971 return QDF_STATUS_E_INVAL; 14972 14973 param->reg_db_version_major = 14974 WMI_REG_DB_VERSION_MAJOR_GET( 14975 ev->reg_db_version); 14976 param->reg_db_version_minor = 14977 WMI_REG_DB_VERSION_MINOR_GET( 14978 ev->reg_db_version); 14979 param->bdf_reg_db_version_major = 14980 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14981 ev->reg_db_version); 14982 param->bdf_reg_db_version_minor = 14983 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14984 ev->reg_db_version); 14985 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14986 14987 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14988 14989 param->num_msdu_idx_qtype_map = 14990 param_buf->num_htt_msdu_idx_to_qtype_map; 14991 14992 if (param_buf->nan_cap) { 14993 param->max_ndp_sessions = 14994 param_buf->nan_cap->max_ndp_sessions; 14995 param->max_nan_pairing_sessions = 14996 param_buf->nan_cap->max_pairing_sessions; 14997 } else { 14998 param->max_ndp_sessions = 0; 14999 param->max_nan_pairing_sessions = 0; 15000 } 15001 15002 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 15003 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 15004 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 15005 ev->max_user_per_ppdu_ofdma); 15006 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 15007 ev->max_user_per_ppdu_ofdma); 15008 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 15009 ev->max_user_per_ppdu_mumimo); 15010 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 15011 ev->max_user_per_ppdu_mumimo); 15012 param->target_cap_flags = ev->target_cap_flags; 15013 15014 param->dp_peer_meta_data_ver = 15015 WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION_GET( 15016 ev->target_cap_flags); 15017 15018 extract_multipass_sap_cap(param, ev->target_cap_flags); 15019 15020 extract_ul_mumimo_support(param); 15021 wmi_debug("htt peer data :%d", ev->target_cap_flags); 15022 15023 extract_svc_rdy_ext2_afc_tlv(ev, param); 15024 15025 extract_hw_bdf_status(ev); 15026 15027 extract_num_max_mlo_link(ev, param); 15028 15029 param->num_aux_dev_caps = param_buf->num_aux_dev_caps; 15030 15031 return QDF_STATUS_SUCCESS; 15032 } 15033 15034 /* 15035 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 15036 * service ready ext 2 15037 * 15038 * @wmi_handle: wmi handle 15039 * @event: pointer to event buffer 15040 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 15041 * it indicates async SBS mode is supported, and 15042 * lower-band/higher band to MAC mapping is 15043 * switch-able. unit: mhz. examples 5180, 5320 15044 * 15045 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15046 */ 15047 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 15048 wmi_unified_t wmi_handle, uint8_t *event, 15049 uint32_t *sbs_lower_band_end_freq) 15050 { 15051 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15052 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 15053 15054 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15055 if (!param_buf) 15056 return QDF_STATUS_E_INVAL; 15057 15058 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 15059 if (!dbs_or_sbs_caps) 15060 return QDF_STATUS_E_INVAL; 15061 15062 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 15063 15064 return QDF_STATUS_SUCCESS; 15065 } 15066 15067 /** 15068 * extract_sar_cap_service_ready_ext_tlv() - 15069 * extract SAR cap from service ready event 15070 * @wmi_handle: wmi handle 15071 * @event: pointer to event buffer 15072 * @ext_param: extended target info 15073 * 15074 * Return: QDF_STATUS_SUCCESS for success or error code 15075 */ 15076 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 15077 wmi_unified_t wmi_handle, 15078 uint8_t *event, 15079 struct wlan_psoc_host_service_ext_param *ext_param) 15080 { 15081 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15082 WMI_SAR_CAPABILITIES *sar_caps; 15083 15084 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15085 15086 if (!param_buf) 15087 return QDF_STATUS_E_INVAL; 15088 15089 sar_caps = param_buf->sar_caps; 15090 if (sar_caps) 15091 ext_param->sar_version = sar_caps->active_version; 15092 else 15093 ext_param->sar_version = 0; 15094 15095 return QDF_STATUS_SUCCESS; 15096 } 15097 15098 /** 15099 * extract_hw_mode_cap_service_ready_ext_tlv() - 15100 * extract HW mode cap from service ready event 15101 * @wmi_handle: wmi handle 15102 * @event: pointer to event buffer 15103 * @hw_mode_idx: hw mode idx should be less than num_mode 15104 * @param: Pointer to hold evt buf 15105 * 15106 * Return: QDF_STATUS_SUCCESS for success or error code 15107 */ 15108 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 15109 wmi_unified_t wmi_handle, 15110 uint8_t *event, uint8_t hw_mode_idx, 15111 struct wlan_psoc_host_hw_mode_caps *param) 15112 { 15113 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15114 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 15115 15116 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15117 if (!param_buf) 15118 return QDF_STATUS_E_INVAL; 15119 15120 hw_caps = param_buf->soc_hw_mode_caps; 15121 if (!hw_caps) 15122 return QDF_STATUS_E_INVAL; 15123 15124 if (!hw_caps->num_hw_modes || 15125 !param_buf->hw_mode_caps || 15126 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 15127 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 15128 return QDF_STATUS_E_INVAL; 15129 15130 if (hw_mode_idx >= hw_caps->num_hw_modes) 15131 return QDF_STATUS_E_INVAL; 15132 15133 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 15134 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 15135 15136 param->hw_mode_config_type = 15137 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 15138 15139 return QDF_STATUS_SUCCESS; 15140 } 15141 15142 /** 15143 * extract_service_ready_11be_support() - api to extract 11be support 15144 * @param: host mac phy capabilities 15145 * @mac_phy_caps: mac phy capabilities 15146 * 15147 * Return: void 15148 */ 15149 #ifdef WLAN_FEATURE_11BE 15150 static void 15151 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 15152 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15153 { 15154 param->supports_11be = 15155 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 15156 15157 wmi_debug("11be support %d", param->supports_11be); 15158 } 15159 #else 15160 static void 15161 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 15162 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15163 { 15164 } 15165 #endif 15166 15167 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 15168 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 15169 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15170 { 15171 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 15172 } 15173 #else 15174 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 15175 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15176 { 15177 } 15178 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 15179 15180 /** 15181 * extract_mac_phy_cap_service_ready_ext_tlv() - 15182 * extract MAC phy cap from service ready event 15183 * @wmi_handle: wmi handle 15184 * @event: pointer to event buffer 15185 * @hw_mode_id: hw mode idx should be less than num_mode 15186 * @phy_id: phy id within hw_mode 15187 * @param: Pointer to hold evt buf 15188 * 15189 * Return: QDF_STATUS_SUCCESS for success or error code 15190 */ 15191 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 15192 wmi_unified_t wmi_handle, 15193 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15194 struct wlan_psoc_host_mac_phy_caps *param) 15195 { 15196 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15197 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 15198 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 15199 uint32_t phy_map; 15200 uint8_t hw_idx, phy_idx = 0, pdev_id; 15201 15202 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15203 if (!param_buf) 15204 return QDF_STATUS_E_INVAL; 15205 15206 hw_caps = param_buf->soc_hw_mode_caps; 15207 if (!hw_caps) 15208 return QDF_STATUS_E_INVAL; 15209 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 15210 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 15211 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 15212 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 15213 return QDF_STATUS_E_INVAL; 15214 } 15215 15216 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 15217 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 15218 break; 15219 15220 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 15221 while (phy_map) { 15222 phy_map >>= 1; 15223 phy_idx++; 15224 } 15225 } 15226 15227 if (hw_idx == hw_caps->num_hw_modes) 15228 return QDF_STATUS_E_INVAL; 15229 15230 phy_idx += phy_id; 15231 if (phy_idx >= param_buf->num_mac_phy_caps) 15232 return QDF_STATUS_E_INVAL; 15233 15234 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15235 15236 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15237 param->phy_idx = phy_idx; 15238 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 15239 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15240 wmi_handle, 15241 pdev_id); 15242 param->tgt_pdev_id = pdev_id; 15243 extract_hw_link_id(param, mac_phy_caps); 15244 param->phy_id = mac_phy_caps->phy_id; 15245 param->supports_11b = 15246 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 15247 param->supports_11g = 15248 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 15249 param->supports_11a = 15250 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 15251 param->supports_11n = 15252 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 15253 param->supports_11ac = 15254 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 15255 param->supports_11ax = 15256 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 15257 15258 extract_service_ready_11be_support(param, mac_phy_caps); 15259 15260 param->supported_bands = mac_phy_caps->supported_bands; 15261 param->ampdu_density = mac_phy_caps->ampdu_density; 15262 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 15263 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 15264 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 15265 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 15266 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 15267 mac_phy_caps->he_cap_info_2G; 15268 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 15269 mac_phy_caps->he_cap_info_2G_ext; 15270 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 15271 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 15272 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 15273 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 15274 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 15275 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 15276 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 15277 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 15278 mac_phy_caps->he_cap_info_5G; 15279 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 15280 mac_phy_caps->he_cap_info_5G_ext; 15281 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 15282 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 15283 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 15284 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 15285 qdf_mem_copy(¶m->he_cap_phy_info_2G, 15286 &mac_phy_caps->he_cap_phy_info_2G, 15287 sizeof(param->he_cap_phy_info_2G)); 15288 qdf_mem_copy(¶m->he_cap_phy_info_5G, 15289 &mac_phy_caps->he_cap_phy_info_5G, 15290 sizeof(param->he_cap_phy_info_5G)); 15291 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 15292 sizeof(param->he_ppet2G)); 15293 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 15294 sizeof(param->he_ppet5G)); 15295 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 15296 param->lmac_id = mac_phy_caps->lmac_id; 15297 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 15298 (mac_phy_caps->wireless_modes); 15299 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 15300 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 15301 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 15302 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 15303 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 15304 mac_phy_caps->nss_ratio); 15305 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 15306 15307 return QDF_STATUS_SUCCESS; 15308 } 15309 15310 #ifdef WLAN_FEATURE_11BE_MLO 15311 /** 15312 * extract_mac_phy_emlcap() - API to extract EML Capabilities 15313 * @param: host ext2 mac phy capabilities 15314 * @mac_phy_caps: ext mac phy capabilities 15315 * 15316 * Return: void 15317 */ 15318 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15319 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15320 { 15321 if (!param || !mac_phy_caps) 15322 return; 15323 15324 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 15325 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 15326 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 15327 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 15328 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 15329 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 15330 } 15331 15332 /** 15333 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 15334 * @param: host ext2 mac phy capabilities 15335 * @mac_phy_caps: ext mac phy capabilities 15336 * 15337 * Return: void 15338 */ 15339 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15340 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15341 { 15342 if (!param || !mac_phy_caps) 15343 return; 15344 15345 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 15346 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 15347 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 15348 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 15349 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 15350 } 15351 15352 /** 15353 * extract_mac_phy_msdcap() - API to extract MSD Capabilities 15354 * @param: host ext2 mac phy capabilities 15355 * @mac_phy_caps: ext mac phy capabilities 15356 * 15357 * Return: void 15358 */ 15359 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15360 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15361 { 15362 if (!param || !mac_phy_caps) 15363 return; 15364 15365 param->msdcap.medium_sync_duration = WMI_MEDIUM_SYNC_DURATION_GET(mac_phy_caps->msd_capability); 15366 param->msdcap.medium_sync_ofdm_ed_thresh = WMI_MEDIUM_SYNC_OFDM_ED_THRESHOLD_GET(mac_phy_caps->msd_capability); 15367 param->msdcap.medium_sync_max_txop_num = WMI_MEDIUM_SYNC_MAX_NO_TXOPS_GET(mac_phy_caps->msd_capability); 15368 } 15369 #else 15370 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15371 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15372 { 15373 } 15374 15375 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15376 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15377 { 15378 } 15379 15380 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15381 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15382 { 15383 } 15384 #endif 15385 15386 /** 15387 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 15388 * @param: host ext2 mac phy capabilities 15389 * @mac_phy_caps: ext mac phy capabilities 15390 * 15391 * Return: void 15392 */ 15393 #ifdef WLAN_FEATURE_11BE 15394 static void extract_mac_phy_cap_ehtcaps( 15395 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15396 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15397 { 15398 uint32_t i; 15399 15400 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 15401 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 15402 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 15403 15404 qdf_mem_copy(¶m->eht_cap_info_2G, 15405 &mac_phy_caps->eht_cap_mac_info_2G, 15406 sizeof(param->eht_cap_info_2G)); 15407 qdf_mem_copy(¶m->eht_cap_info_5G, 15408 &mac_phy_caps->eht_cap_mac_info_5G, 15409 sizeof(param->eht_cap_info_5G)); 15410 15411 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 15412 &mac_phy_caps->eht_cap_phy_info_2G, 15413 sizeof(param->eht_cap_phy_info_2G)); 15414 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 15415 &mac_phy_caps->eht_cap_phy_info_5G, 15416 sizeof(param->eht_cap_phy_info_5G)); 15417 15418 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 15419 &mac_phy_caps->eht_supp_mcs_ext_2G, 15420 sizeof(param->eht_supp_mcs_ext_2G)); 15421 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 15422 &mac_phy_caps->eht_supp_mcs_ext_5G, 15423 sizeof(param->eht_supp_mcs_ext_5G)); 15424 15425 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 15426 sizeof(param->eht_ppet2G)); 15427 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 15428 sizeof(param->eht_ppet5G)); 15429 15430 wmi_debug("EHT mac caps: mac cap_info_2G %x, mac cap_info_5G %x, supp_mcs_2G %x, supp_mcs_5G %x, info_internal %x", 15431 mac_phy_caps->eht_cap_mac_info_2G[0], 15432 mac_phy_caps->eht_cap_mac_info_5G[0], 15433 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 15434 mac_phy_caps->eht_cap_info_internal); 15435 15436 wmi_nofl_debug("EHT phy caps: "); 15437 15438 wmi_nofl_debug("2G:"); 15439 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15440 wmi_nofl_debug("index %d value %x", 15441 i, param->eht_cap_phy_info_2G[i]); 15442 } 15443 wmi_nofl_debug("5G:"); 15444 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15445 wmi_nofl_debug("index %d value %x", 15446 i, param->eht_cap_phy_info_5G[i]); 15447 } 15448 wmi_nofl_debug("2G MCS ext Map:"); 15449 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 15450 wmi_nofl_debug("index %d value %x", 15451 i, param->eht_supp_mcs_ext_2G[i]); 15452 } 15453 wmi_nofl_debug("5G MCS ext Map:"); 15454 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 15455 wmi_nofl_debug("index %d value %x", 15456 i, param->eht_supp_mcs_ext_5G[i]); 15457 } 15458 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 15459 param->eht_ppet2G.numss_m1, 15460 param->eht_ppet2G.ru_bit_mask); 15461 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15462 wmi_nofl_debug("index %d value %x", 15463 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 15464 } 15465 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 15466 param->eht_ppet5G.numss_m1, 15467 param->eht_ppet5G.ru_bit_mask); 15468 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15469 wmi_nofl_debug("index %d value %x", 15470 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 15471 } 15472 } 15473 #else 15474 static void extract_mac_phy_cap_ehtcaps( 15475 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15476 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15477 { 15478 } 15479 #endif 15480 15481 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 15482 wmi_unified_t wmi_handle, 15483 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15484 uint8_t phy_idx, 15485 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 15486 { 15487 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15488 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 15489 15490 if (!event) { 15491 wmi_err("null evt_buf"); 15492 return QDF_STATUS_E_INVAL; 15493 } 15494 15495 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15496 15497 if (!param_buf->num_mac_phy_caps) 15498 return QDF_STATUS_SUCCESS; 15499 15500 if (phy_idx >= param_buf->num_mac_phy_caps) 15501 return QDF_STATUS_E_INVAL; 15502 15503 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15504 15505 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 15506 (phy_id != mac_phy_caps->phy_id)) 15507 return QDF_STATUS_E_INVAL; 15508 15509 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15510 param->phy_id = mac_phy_caps->phy_id; 15511 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15512 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 15513 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 15514 mac_phy_caps->wireless_modes_ext); 15515 15516 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 15517 extract_mac_phy_emlcap(param, mac_phy_caps); 15518 extract_mac_phy_mldcap(param, mac_phy_caps); 15519 extract_mac_phy_msdcap(param, mac_phy_caps); 15520 15521 return QDF_STATUS_SUCCESS; 15522 } 15523 15524 /** 15525 * extract_reg_cap_service_ready_ext_tlv() - 15526 * extract REG cap from service ready event 15527 * @wmi_handle: wmi handle 15528 * @event: pointer to event buffer 15529 * @phy_idx: phy idx should be less than num_mode 15530 * @param: Pointer to hold evt buf 15531 * 15532 * Return: QDF_STATUS_SUCCESS for success or error code 15533 */ 15534 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 15535 wmi_unified_t wmi_handle, 15536 uint8_t *event, uint8_t phy_idx, 15537 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 15538 { 15539 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15540 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 15541 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 15542 15543 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15544 if (!param_buf) 15545 return QDF_STATUS_E_INVAL; 15546 15547 reg_caps = param_buf->soc_hal_reg_caps; 15548 if (!reg_caps) 15549 return QDF_STATUS_E_INVAL; 15550 15551 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 15552 return QDF_STATUS_E_INVAL; 15553 15554 if (phy_idx >= reg_caps->num_phy) 15555 return QDF_STATUS_E_INVAL; 15556 15557 if (!param_buf->hal_reg_caps) 15558 return QDF_STATUS_E_INVAL; 15559 15560 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 15561 15562 param->phy_id = ext_reg_cap->phy_id; 15563 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 15564 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 15565 param->regcap1 = ext_reg_cap->regcap1; 15566 param->regcap2 = ext_reg_cap->regcap2; 15567 param->wireless_modes = convert_wireless_modes_tlv( 15568 ext_reg_cap->wireless_modes); 15569 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 15570 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 15571 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 15572 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 15573 15574 return QDF_STATUS_SUCCESS; 15575 } 15576 15577 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 15578 uint8_t num_dma_ring_caps) 15579 { 15580 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 15581 if (!num_dma_ring_caps) { 15582 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 15583 return QDF_STATUS_E_INVAL; 15584 } 15585 if (idx >= num_dma_ring_caps) { 15586 wmi_err("Index %d exceeds range", idx); 15587 return QDF_STATUS_E_INVAL; 15588 } 15589 return QDF_STATUS_SUCCESS; 15590 } 15591 15592 static void 15593 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 15594 struct wlan_psoc_host_dbr_ring_caps *param, 15595 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 15596 { 15597 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 15598 wmi_handle, 15599 dbr_ring_caps->pdev_id); 15600 param->mod_id = dbr_ring_caps->mod_id; 15601 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 15602 param->min_buf_size = dbr_ring_caps->min_buf_size; 15603 param->min_buf_align = dbr_ring_caps->min_buf_align; 15604 } 15605 15606 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 15607 wmi_unified_t wmi_handle, 15608 uint8_t *event, uint8_t idx, 15609 struct wlan_psoc_host_dbr_ring_caps *param) 15610 { 15611 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15612 QDF_STATUS status; 15613 15614 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15615 if (!param_buf) 15616 return QDF_STATUS_E_INVAL; 15617 15618 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15619 if (status != QDF_STATUS_SUCCESS) 15620 return status; 15621 15622 populate_dbr_ring_cap_elems(wmi_handle, param, 15623 ¶m_buf->dma_ring_caps[idx]); 15624 return QDF_STATUS_SUCCESS; 15625 } 15626 15627 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 15628 wmi_unified_t wmi_handle, 15629 uint8_t *event, uint8_t idx, 15630 struct wlan_psoc_host_dbr_ring_caps *param) 15631 { 15632 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15633 QDF_STATUS status; 15634 15635 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15636 if (!param_buf) 15637 return QDF_STATUS_E_INVAL; 15638 15639 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15640 if (status != QDF_STATUS_SUCCESS) 15641 return status; 15642 15643 populate_dbr_ring_cap_elems(wmi_handle, param, 15644 ¶m_buf->dma_ring_caps[idx]); 15645 return QDF_STATUS_SUCCESS; 15646 } 15647 15648 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 15649 wmi_unified_t wmi_handle, 15650 uint8_t *event, uint8_t idx, 15651 struct wlan_psoc_host_scan_radio_caps *param) 15652 { 15653 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15654 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 15655 15656 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15657 if (!param_buf) 15658 return QDF_STATUS_E_INVAL; 15659 15660 if (idx >= param_buf->num_wmi_scan_radio_caps) 15661 return QDF_STATUS_E_INVAL; 15662 15663 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 15664 param->phy_id = scan_radio_caps->phy_id; 15665 param->scan_radio_supported = 15666 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 15667 param->dfs_en = 15668 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 15669 param->blanking_en = 15670 WMI_SCAN_RADIO_CAP_BLANKING_SUPPORT_GET(scan_radio_caps->flags); 15671 15672 return QDF_STATUS_SUCCESS; 15673 } 15674 15675 static QDF_STATUS extract_msdu_idx_qtype_map_service_ready_ext2_tlv( 15676 wmi_unified_t wmi_handle, 15677 uint8_t *event, uint8_t idx, 15678 uint8_t *msdu_qtype) 15679 { 15680 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15681 wmi_htt_msdu_idx_to_htt_msdu_qtype *msdu_idx_to_qtype; 15682 uint8_t wmi_htt_msdu_idx; 15683 15684 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15685 if (!param_buf) 15686 return QDF_STATUS_E_INVAL; 15687 15688 if (idx >= param_buf->num_htt_msdu_idx_to_qtype_map) 15689 return QDF_STATUS_E_INVAL; 15690 15691 msdu_idx_to_qtype = ¶m_buf->htt_msdu_idx_to_qtype_map[idx]; 15692 wmi_htt_msdu_idx = 15693 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_INDEX_GET( 15694 msdu_idx_to_qtype->index_and_type); 15695 if (wmi_htt_msdu_idx != idx) { 15696 wmi_err("wmi_htt_msdu_idx 0x%x is not same as idx 0x%x", 15697 wmi_htt_msdu_idx, idx); 15698 return QDF_STATUS_E_INVAL; 15699 } 15700 15701 *msdu_qtype = 15702 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_TYPE_GET( 15703 msdu_idx_to_qtype->index_and_type); 15704 15705 return QDF_STATUS_SUCCESS; 15706 } 15707 15708 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 15709 uint8_t *event, 15710 struct wmi_host_sw_cal_ver *cal) 15711 { 15712 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15713 wmi_sw_cal_ver_cap *fw_cap; 15714 15715 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15716 if (!param_buf) 15717 return QDF_STATUS_E_INVAL; 15718 15719 fw_cap = param_buf->sw_cal_ver_cap; 15720 if (!fw_cap) 15721 return QDF_STATUS_E_INVAL; 15722 15723 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 15724 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 15725 cal->status = fw_cap->status; 15726 15727 return QDF_STATUS_SUCCESS; 15728 } 15729 15730 static QDF_STATUS extract_aux_dev_cap_service_ready_ext2_tlv( 15731 wmi_unified_t wmi_handle, 15732 uint8_t *event, uint8_t idx, 15733 struct wlan_psoc_host_aux_dev_caps *param) 15734 15735 { 15736 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15737 wmi_aux_dev_capabilities *aux_dev_caps; 15738 15739 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15740 15741 if (!param_buf->num_aux_dev_caps) 15742 return QDF_STATUS_E_INVAL; 15743 15744 if (!param_buf->aux_dev_caps) { 15745 wmi_err("aux_dev_caps is NULL"); 15746 return QDF_STATUS_E_INVAL; 15747 } 15748 15749 if (idx >= param_buf->num_aux_dev_caps) 15750 return QDF_STATUS_E_INVAL; 15751 15752 aux_dev_caps = ¶m_buf->aux_dev_caps[idx]; 15753 15754 param->aux_index = aux_dev_caps->aux_index; 15755 param->hw_mode_id = aux_dev_caps->hw_mode_id; 15756 param->supported_modes_bitmap = aux_dev_caps->supported_modes_bitmap; 15757 param->listen_pdev_id_map = aux_dev_caps->listen_pdev_id_map; 15758 param->emlsr_pdev_id_map = aux_dev_caps->emlsr_pdev_id_map; 15759 15760 wmi_info("idx %u aux_index %u, hw_mode_id %u, supported_modes_bitmap 0x%x, listen_pdev_id_map 0x%x, emlsr_pdev_id_map 0x%x", 15761 idx, aux_dev_caps->aux_index, 15762 aux_dev_caps->hw_mode_id, 15763 aux_dev_caps->supported_modes_bitmap, 15764 aux_dev_caps->listen_pdev_id_map, 15765 aux_dev_caps->emlsr_pdev_id_map); 15766 15767 return QDF_STATUS_SUCCESS; 15768 } 15769 15770 /** 15771 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 15772 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 15773 * 15774 * Return: host thermal throt level 15775 */ 15776 static enum thermal_throttle_level 15777 wmi_tgt_thermal_level_to_host(uint32_t level) 15778 { 15779 switch (level) { 15780 case WMI_THERMAL_FULLPERF: 15781 return THERMAL_FULLPERF; 15782 case WMI_THERMAL_MITIGATION: 15783 return THERMAL_MITIGATION; 15784 case WMI_THERMAL_SHUTOFF: 15785 return THERMAL_SHUTOFF; 15786 case WMI_THERMAL_SHUTDOWN_TGT: 15787 return THERMAL_SHUTDOWN_TARGET; 15788 default: 15789 return THERMAL_UNKNOWN; 15790 } 15791 } 15792 15793 #ifdef THERMAL_STATS_SUPPORT 15794 static void 15795 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15796 uint32_t *therm_throt_levels, 15797 struct thermal_throt_level_stats *tt_temp_range_stats) 15798 { 15799 uint8_t lvl_idx; 15800 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15801 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 15802 15803 tt_stats_event = param_buf->fixed_param; 15804 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 15805 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 15806 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 15807 tt_stats_event->therm_throt_levels; 15808 15809 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 15810 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 15811 *therm_throt_levels, 15812 param_buf->num_temp_range_stats); 15813 return; 15814 } 15815 15816 wmi_tt_stats = param_buf->temp_range_stats; 15817 if (!wmi_tt_stats) { 15818 wmi_err("wmi_tt_stats Null"); 15819 return; 15820 } 15821 15822 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 15823 tt_temp_range_stats[lvl_idx].start_temp_level = 15824 wmi_tt_stats[lvl_idx].start_temp_level; 15825 tt_temp_range_stats[lvl_idx].end_temp_level = 15826 wmi_tt_stats[lvl_idx].end_temp_level; 15827 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 15828 wmi_tt_stats[lvl_idx].total_time_ms_lo; 15829 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 15830 wmi_tt_stats[lvl_idx].total_time_ms_hi; 15831 tt_temp_range_stats[lvl_idx].num_entry = 15832 wmi_tt_stats[lvl_idx].num_entry; 15833 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 15834 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 15835 wmi_tt_stats[lvl_idx].end_temp_level, 15836 wmi_tt_stats[lvl_idx].total_time_ms_lo, 15837 wmi_tt_stats[lvl_idx].total_time_ms_hi, 15838 wmi_tt_stats[lvl_idx].num_entry); 15839 } 15840 } 15841 #else 15842 static void 15843 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15844 uint32_t *therm_throt_levels, 15845 struct thermal_throt_level_stats *tt_temp_range_stats) 15846 { 15847 } 15848 #endif 15849 15850 /** 15851 * extract_thermal_stats_tlv() - extract thermal stats from event 15852 * @wmi_handle: wmi handle 15853 * @evt_buf: Pointer to event buffer 15854 * @temp: Pointer to hold extracted temperature 15855 * @level: Pointer to hold extracted level in host enum 15856 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 15857 * range 15858 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 15859 * every level 15860 * @pdev_id: Pointer to hold extracted pdev id 15861 * 15862 * Return: QDF_STATUS_SUCCESS for success or error code 15863 */ 15864 static QDF_STATUS 15865 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 15866 void *evt_buf, uint32_t *temp, 15867 enum thermal_throttle_level *level, 15868 uint32_t *therm_throt_levels, 15869 struct thermal_throt_level_stats *tt_temp_range_stats_event, 15870 uint32_t *pdev_id) 15871 { 15872 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15873 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15874 15875 param_buf = 15876 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15877 if (!param_buf) 15878 return QDF_STATUS_E_INVAL; 15879 15880 tt_stats_event = param_buf->fixed_param; 15881 wmi_debug("thermal temperature %d level %d", 15882 tt_stats_event->temp, tt_stats_event->level); 15883 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15884 wmi_handle, 15885 tt_stats_event->pdev_id); 15886 *temp = tt_stats_event->temp; 15887 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 15888 15889 if (tt_stats_event->therm_throt_levels) 15890 populate_thermal_stats(param_buf, therm_throt_levels, 15891 tt_temp_range_stats_event); 15892 15893 return QDF_STATUS_SUCCESS; 15894 } 15895 15896 /** 15897 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 15898 * @wmi_handle: wmi handle 15899 * @evt_buf: pointer to event buffer 15900 * @idx: Index to level stats 15901 * @levelcount: Pointer to hold levelcount 15902 * @dccount: Pointer to hold dccount 15903 * 15904 * Return: QDF_STATUS_SUCCESS for success or error code 15905 */ 15906 static QDF_STATUS 15907 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 15908 void *evt_buf, uint8_t idx, uint32_t *levelcount, 15909 uint32_t *dccount) 15910 { 15911 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15912 wmi_therm_throt_level_stats_info *tt_level_info; 15913 15914 param_buf = 15915 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15916 if (!param_buf) 15917 return QDF_STATUS_E_INVAL; 15918 15919 tt_level_info = param_buf->therm_throt_level_stats_info; 15920 15921 if (idx < THERMAL_LEVELS) { 15922 *levelcount = tt_level_info[idx].level_count; 15923 *dccount = tt_level_info[idx].dc_count; 15924 return QDF_STATUS_SUCCESS; 15925 } 15926 15927 return QDF_STATUS_E_FAILURE; 15928 } 15929 15930 /** 15931 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 15932 * @data_len: data length 15933 * @data: pointer to data 15934 * 15935 * Return: QDF_STATUS - success or error status 15936 */ 15937 #ifdef BIG_ENDIAN_HOST 15938 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15939 { 15940 uint8_t *data_aligned = NULL; 15941 int c; 15942 unsigned char *data_unaligned; 15943 15944 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15945 FIPS_ALIGN)); 15946 /* Assigning unaligned space to copy the data */ 15947 /* Checking if kmalloc does successful allocation */ 15948 if (!data_unaligned) 15949 return QDF_STATUS_E_FAILURE; 15950 15951 /* Checking if space is aligned */ 15952 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15953 /* align the data space */ 15954 data_aligned = 15955 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15956 } else { 15957 data_aligned = (u_int8_t *)data_unaligned; 15958 } 15959 15960 /* memset and copy content from data to data aligned */ 15961 OS_MEMSET(data_aligned, 0, data_len); 15962 OS_MEMCPY(data_aligned, data, data_len); 15963 /* Endianness to LE */ 15964 for (c = 0; c < data_len/4; c++) { 15965 *((u_int32_t *)data_aligned + c) = 15966 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15967 } 15968 15969 /* Copy content to event->data */ 15970 OS_MEMCPY(data, data_aligned, data_len); 15971 15972 /* clean up allocated space */ 15973 qdf_mem_free(data_unaligned); 15974 data_aligned = NULL; 15975 data_unaligned = NULL; 15976 15977 /*************************************************************/ 15978 15979 return QDF_STATUS_SUCCESS; 15980 } 15981 #else 15982 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15983 { 15984 return QDF_STATUS_SUCCESS; 15985 } 15986 #endif 15987 15988 /** 15989 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15990 * @wmi_handle: wmi handle 15991 * @params: PN request params for peer 15992 * 15993 * Return: QDF_STATUS - success or error status 15994 */ 15995 static QDF_STATUS 15996 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15997 struct peer_request_pn_param *params) 15998 { 15999 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 16000 wmi_buf_t buf; 16001 uint8_t *buf_ptr; 16002 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 16003 16004 buf = wmi_buf_alloc(wmi_handle, len); 16005 if (!buf) { 16006 wmi_err("wmi_buf_alloc failed"); 16007 return QDF_STATUS_E_FAILURE; 16008 } 16009 16010 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16011 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 16012 16013 WMITLV_SET_HDR(&cmd->tlv_header, 16014 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 16015 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 16016 16017 cmd->vdev_id = params->vdev_id; 16018 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 16019 cmd->key_type = params->key_type; 16020 cmd->key_ix = params->keyix; 16021 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16022 WMI_PEER_TX_PN_REQUEST_CMDID)) { 16023 wmi_err("Failed to send WMI command"); 16024 wmi_buf_free(buf); 16025 return QDF_STATUS_E_FAILURE; 16026 } 16027 return QDF_STATUS_SUCCESS; 16028 } 16029 16030 /** 16031 * extract_get_pn_data_tlv() - extract pn resp 16032 * @wmi_handle: wmi handle 16033 * @evt_buf: pointer to event buffer 16034 * @param: PN response params for peer 16035 * 16036 * Return: QDF_STATUS - success or error status 16037 */ 16038 static QDF_STATUS 16039 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16040 struct wmi_host_get_pn_event *param) 16041 { 16042 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 16043 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 16044 16045 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 16046 event = 16047 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 16048 16049 param->vdev_id = event->vdev_id; 16050 param->key_type = event->key_type; 16051 param->key_ix = event->key_ix; 16052 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 16053 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 16054 16055 return QDF_STATUS_SUCCESS; 16056 } 16057 16058 /** 16059 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 16060 * @wmi_handle: wmi handle 16061 * @params: Rx PN request params for peer 16062 * 16063 * Return: QDF_STATUS - success or error status 16064 */ 16065 static QDF_STATUS 16066 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 16067 struct peer_request_rxpn_param *params) 16068 { 16069 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 16070 wmi_buf_t buf; 16071 uint8_t *buf_ptr; 16072 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 16073 16074 if (!is_service_enabled_tlv(wmi_handle, 16075 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 16076 wmi_err("Rx PN Replay Check not supported by target"); 16077 return QDF_STATUS_E_NOSUPPORT; 16078 } 16079 16080 buf = wmi_buf_alloc(wmi_handle, len); 16081 if (!buf) { 16082 wmi_err("wmi_buf_alloc failed"); 16083 return QDF_STATUS_E_FAILURE; 16084 } 16085 16086 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16087 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 16088 16089 WMITLV_SET_HDR(&cmd->tlv_header, 16090 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 16091 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 16092 16093 cmd->vdev_id = params->vdev_id; 16094 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 16095 cmd->key_ix = params->keyix; 16096 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16097 WMI_PEER_RX_PN_REQUEST_CMDID)) { 16098 wmi_err("Failed to send WMI command"); 16099 wmi_buf_free(buf); 16100 return QDF_STATUS_E_FAILURE; 16101 } 16102 return QDF_STATUS_SUCCESS; 16103 } 16104 16105 /** 16106 * extract_get_rxpn_data_tlv() - extract Rx PN resp 16107 * @wmi_handle: wmi handle 16108 * @evt_buf: pointer to event buffer 16109 * @params: Rx PN response params for peer 16110 * 16111 * Return: QDF_STATUS - success or error status 16112 */ 16113 static QDF_STATUS 16114 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16115 struct wmi_host_get_rxpn_event *params) 16116 { 16117 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 16118 wmi_peer_rx_pn_response_event_fixed_param *event; 16119 16120 param_buf = evt_buf; 16121 event = param_buf->fixed_param; 16122 16123 params->vdev_id = event->vdev_id; 16124 params->keyix = event->key_idx; 16125 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 16126 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 16127 16128 return QDF_STATUS_SUCCESS; 16129 } 16130 16131 /** 16132 * extract_fips_event_data_tlv() - extract fips event data 16133 * @wmi_handle: wmi handle 16134 * @evt_buf: pointer to event buffer 16135 * @param: pointer FIPS event params 16136 * 16137 * Return: QDF_STATUS_SUCCESS for success or error code 16138 */ 16139 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 16140 void *evt_buf, struct wmi_host_fips_event_param *param) 16141 { 16142 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 16143 wmi_pdev_fips_event_fixed_param *event; 16144 16145 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 16146 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 16147 16148 if (event->data_len > param_buf->num_data) 16149 return QDF_STATUS_E_FAILURE; 16150 16151 if (fips_conv_data_be(event->data_len, param_buf->data) != 16152 QDF_STATUS_SUCCESS) 16153 return QDF_STATUS_E_FAILURE; 16154 16155 param->data = (uint32_t *)param_buf->data; 16156 param->data_len = event->data_len; 16157 param->error_status = event->error_status; 16158 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16159 wmi_handle, 16160 event->pdev_id); 16161 16162 return QDF_STATUS_SUCCESS; 16163 } 16164 16165 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 16166 /** 16167 * extract_fips_extend_event_data_tlv() - extract fips event data 16168 * @wmi_handle: wmi handle 16169 * @evt_buf: pointer to event buffer 16170 * @param: pointer FIPS event params 16171 * 16172 * Return: QDF_STATUS_SUCCESS for success or error code 16173 */ 16174 static QDF_STATUS 16175 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 16176 void *evt_buf, 16177 struct wmi_host_fips_extend_event_param 16178 *param) 16179 { 16180 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 16181 wmi_pdev_fips_extend_event_fixed_param *event; 16182 16183 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 16184 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 16185 16186 if (fips_conv_data_be(event->data_len, param_buf->data) != 16187 QDF_STATUS_SUCCESS) 16188 return QDF_STATUS_E_FAILURE; 16189 16190 param->data = (uint32_t *)param_buf->data; 16191 param->data_len = event->data_len; 16192 param->error_status = event->error_status; 16193 param->fips_cookie = event->fips_cookie; 16194 param->cmd_frag_idx = event->cmd_frag_idx; 16195 param->more_bit = event->more_bit; 16196 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16197 wmi_handle, 16198 event->pdev_id); 16199 16200 return QDF_STATUS_SUCCESS; 16201 } 16202 #endif 16203 16204 #ifdef WLAN_FEATURE_DISA 16205 /** 16206 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 16207 * params from event 16208 * @wmi_handle: wmi handle 16209 * @evt_buf: pointer to event buffer 16210 * @resp: Pointer to hold resp parameters 16211 * 16212 * Return: QDF_STATUS_SUCCESS for success or error code 16213 */ 16214 static QDF_STATUS 16215 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 16216 void *evt_buf, 16217 struct disa_encrypt_decrypt_resp_params 16218 *resp) 16219 { 16220 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 16221 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 16222 16223 param_buf = evt_buf; 16224 if (!param_buf) { 16225 wmi_err("encrypt decrypt resp evt_buf is NULL"); 16226 return QDF_STATUS_E_INVAL; 16227 } 16228 16229 data_event = param_buf->fixed_param; 16230 16231 resp->vdev_id = data_event->vdev_id; 16232 resp->status = data_event->status; 16233 16234 if ((data_event->data_length > param_buf->num_enc80211_frame) || 16235 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 16236 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 16237 wmi_err("FW msg data_len %d more than TLV hdr %d", 16238 data_event->data_length, 16239 param_buf->num_enc80211_frame); 16240 return QDF_STATUS_E_INVAL; 16241 } 16242 16243 resp->data_len = data_event->data_length; 16244 16245 if (resp->data_len) 16246 resp->data = (uint8_t *)param_buf->enc80211_frame; 16247 16248 return QDF_STATUS_SUCCESS; 16249 } 16250 #endif /* WLAN_FEATURE_DISA */ 16251 16252 static bool is_management_record_tlv(uint32_t cmd_id) 16253 { 16254 switch (cmd_id) { 16255 case WMI_MGMT_TX_SEND_CMDID: 16256 case WMI_MGMT_TX_COMPLETION_EVENTID: 16257 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 16258 case WMI_MGMT_RX_EVENTID: 16259 return true; 16260 default: 16261 return false; 16262 } 16263 } 16264 16265 static bool is_force_fw_hang_cmd_tlv(uint32_t cmd_id) 16266 { 16267 if (cmd_id == WMI_FORCE_FW_HANG_CMDID) 16268 return true; 16269 16270 return false; 16271 } 16272 16273 static bool is_diag_event_tlv(uint32_t event_id) 16274 { 16275 if (WMI_DIAG_EVENTID == event_id) 16276 return true; 16277 16278 return false; 16279 } 16280 16281 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 16282 { 16283 uint16_t tag = 0; 16284 16285 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 16286 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 16287 __func__); 16288 return tag; 16289 } 16290 16291 if (wmi_handle->tag_crash_inject) 16292 tag = HTC_TX_PACKET_TAG_AUTO_PM; 16293 16294 wmi_handle->tag_crash_inject = false; 16295 return tag; 16296 } 16297 16298 /** 16299 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 16300 * @wmi_handle: WMI handle 16301 * @buf: WMI buffer 16302 * @cmd_id: WMI command Id 16303 * 16304 * Return: htc_tx_tag 16305 */ 16306 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 16307 wmi_buf_t buf, 16308 uint32_t cmd_id) 16309 { 16310 uint16_t htc_tx_tag = 0; 16311 16312 switch (cmd_id) { 16313 case WMI_WOW_ENABLE_CMDID: 16314 case WMI_PDEV_SUSPEND_CMDID: 16315 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 16316 case WMI_PDEV_RESUME_CMDID: 16317 case WMI_HB_SET_ENABLE_CMDID: 16318 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 16319 #ifdef FEATURE_WLAN_D0WOW 16320 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 16321 #endif 16322 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 16323 break; 16324 case WMI_FORCE_FW_HANG_CMDID: 16325 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 16326 break; 16327 default: 16328 break; 16329 } 16330 16331 return htc_tx_tag; 16332 } 16333 16334 #ifdef CONFIG_BAND_6GHZ 16335 16336 static struct cur_reg_rule 16337 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 16338 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 16339 { 16340 struct cur_reg_rule *reg_rule_ptr; 16341 uint32_t count; 16342 16343 if (!num_reg_rules) 16344 return NULL; 16345 16346 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16347 sizeof(*reg_rule_ptr)); 16348 16349 if (!reg_rule_ptr) 16350 return NULL; 16351 16352 for (count = 0; count < num_reg_rules; count++) { 16353 reg_rule_ptr[count].start_freq = 16354 WMI_REG_RULE_START_FREQ_GET( 16355 wmi_reg_rule[count].freq_info); 16356 reg_rule_ptr[count].end_freq = 16357 WMI_REG_RULE_END_FREQ_GET( 16358 wmi_reg_rule[count].freq_info); 16359 reg_rule_ptr[count].max_bw = 16360 WMI_REG_RULE_MAX_BW_GET( 16361 wmi_reg_rule[count].bw_pwr_info); 16362 reg_rule_ptr[count].reg_power = 16363 WMI_REG_RULE_REG_POWER_GET( 16364 wmi_reg_rule[count].bw_pwr_info); 16365 reg_rule_ptr[count].ant_gain = 16366 WMI_REG_RULE_ANTENNA_GAIN_GET( 16367 wmi_reg_rule[count].bw_pwr_info); 16368 reg_rule_ptr[count].flags = 16369 WMI_REG_RULE_FLAGS_GET( 16370 wmi_reg_rule[count].flag_info); 16371 reg_rule_ptr[count].psd_flag = 16372 WMI_REG_RULE_PSD_FLAG_GET( 16373 wmi_reg_rule[count].psd_power_info); 16374 reg_rule_ptr[count].psd_eirp = 16375 WMI_REG_RULE_PSD_EIRP_GET( 16376 wmi_reg_rule[count].psd_power_info); 16377 } 16378 16379 return reg_rule_ptr; 16380 } 16381 #endif 16382 16383 static struct cur_reg_rule 16384 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 16385 wmi_regulatory_rule_struct *wmi_reg_rule) 16386 { 16387 struct cur_reg_rule *reg_rule_ptr; 16388 uint32_t count; 16389 16390 if (!num_reg_rules) 16391 return NULL; 16392 16393 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16394 sizeof(*reg_rule_ptr)); 16395 16396 if (!reg_rule_ptr) 16397 return NULL; 16398 16399 for (count = 0; count < num_reg_rules; count++) { 16400 reg_rule_ptr[count].start_freq = 16401 WMI_REG_RULE_START_FREQ_GET( 16402 wmi_reg_rule[count].freq_info); 16403 reg_rule_ptr[count].end_freq = 16404 WMI_REG_RULE_END_FREQ_GET( 16405 wmi_reg_rule[count].freq_info); 16406 reg_rule_ptr[count].max_bw = 16407 WMI_REG_RULE_MAX_BW_GET( 16408 wmi_reg_rule[count].bw_pwr_info); 16409 reg_rule_ptr[count].reg_power = 16410 WMI_REG_RULE_REG_POWER_GET( 16411 wmi_reg_rule[count].bw_pwr_info); 16412 reg_rule_ptr[count].ant_gain = 16413 WMI_REG_RULE_ANTENNA_GAIN_GET( 16414 wmi_reg_rule[count].bw_pwr_info); 16415 reg_rule_ptr[count].flags = 16416 WMI_REG_RULE_FLAGS_GET( 16417 wmi_reg_rule[count].flag_info); 16418 } 16419 16420 return reg_rule_ptr; 16421 } 16422 16423 static enum cc_setting_code wmi_reg_status_to_reg_status( 16424 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 16425 { 16426 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 16427 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 16428 return REG_SET_CC_STATUS_PASS; 16429 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 16430 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 16431 return REG_CURRENT_ALPHA2_NOT_FOUND; 16432 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 16433 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 16434 return REG_INIT_ALPHA2_NOT_FOUND; 16435 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 16436 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 16437 return REG_SET_CC_CHANGE_NOT_ALLOWED; 16438 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 16439 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 16440 return REG_SET_CC_STATUS_NO_MEMORY; 16441 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 16442 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 16443 return REG_SET_CC_STATUS_FAIL; 16444 } 16445 16446 wmi_debug("Unknown reg status code from WMI"); 16447 return REG_SET_CC_STATUS_FAIL; 16448 } 16449 16450 #ifdef CONFIG_BAND_6GHZ 16451 /** 16452 * reg_print_ap_power_type_6ghz - Prints the AP Power type 16453 * @ap_type: 6ghz-AP Power type 16454 * 16455 * Return: void 16456 */ 16457 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16458 { 16459 switch (ap_type) { 16460 case REG_INDOOR_AP: 16461 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 16462 break; 16463 case REG_STANDARD_POWER_AP: 16464 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 16465 break; 16466 case REG_VERY_LOW_POWER_AP: 16467 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 16468 break; 16469 default: 16470 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 16471 } 16472 } 16473 16474 /** 16475 * reg_print_6ghz_client_type - Prints the client type 16476 * @client_type: 6ghz-client type 16477 * 16478 * Return: void 16479 */ 16480 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16481 { 16482 switch (client_type) { 16483 case REG_DEFAULT_CLIENT: 16484 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 16485 break; 16486 case REG_SUBORDINATE_CLIENT: 16487 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 16488 break; 16489 default: 16490 wmi_nofl_debug("Invalid Client type %u", client_type); 16491 } 16492 } 16493 #else 16494 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16495 { 16496 } 16497 16498 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16499 { 16500 } 16501 #endif /* CONFIG_BAND_6GHZ */ 16502 16503 #ifdef CONFIG_BAND_6GHZ 16504 16505 #ifdef CONFIG_REG_CLIENT 16506 #define MAX_NUM_FCC_RULES 2 16507 16508 /** 16509 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 16510 * @num_fcc_rules: Number of FCC rules 16511 * @wmi_fcc_rule: WMI FCC rules TLV 16512 * 16513 * Return: fcc_rule_ptr 16514 */ 16515 static struct cur_fcc_rule 16516 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 16517 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 16518 { 16519 struct cur_fcc_rule *fcc_rule_ptr; 16520 uint32_t count; 16521 16522 if (!wmi_fcc_rule) 16523 return NULL; 16524 16525 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 16526 sizeof(*fcc_rule_ptr)); 16527 if (!fcc_rule_ptr) 16528 return NULL; 16529 16530 for (count = 0; count < num_fcc_rules; count++) { 16531 fcc_rule_ptr[count].center_freq = 16532 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 16533 wmi_fcc_rule[count].freq_info); 16534 fcc_rule_ptr[count].tx_power = 16535 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 16536 wmi_fcc_rule[count].freq_info); 16537 } 16538 16539 return fcc_rule_ptr; 16540 } 16541 16542 /** 16543 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 16544 * @param_buf: Pointer to WMI params TLV 16545 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 16546 * Params TLV 16547 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 16548 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 16549 * Priority TLV 16550 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 16551 * @reg_info: Pointer to Regulatory Info 16552 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 16553 * 16554 * Return: QDF_STATUS 16555 */ 16556 static QDF_STATUS extract_reg_fcc_rules_tlv( 16557 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16558 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16559 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16560 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16561 uint8_t *evt_buf, 16562 struct cur_regulatory_info *reg_info, 16563 uint32_t len) 16564 { 16565 int i; 16566 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 16567 16568 if (!param_buf) { 16569 wmi_err("invalid channel list event buf"); 16570 return QDF_STATUS_E_INVAL; 16571 } 16572 16573 reg_info->num_fcc_rules = 0; 16574 if (param_buf->reg_fcc_rule) { 16575 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 16576 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 16577 return QDF_STATUS_E_INVAL; 16578 } 16579 16580 ext_wmi_fcc_rule = 16581 (wmi_regulatory_fcc_rule_struct *) 16582 ((uint8_t *)ext_chan_list_event_hdr + 16583 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16584 WMI_TLV_HDR_SIZE + 16585 sizeof(wmi_regulatory_rule_ext_struct) * 16586 param_buf->num_reg_rule_array + 16587 WMI_TLV_HDR_SIZE + 16588 sizeof(wmi_regulatory_chan_priority_struct) * 16589 param_buf->num_reg_chan_priority + 16590 WMI_TLV_HDR_SIZE); 16591 16592 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 16593 param_buf->num_reg_fcc_rule, 16594 ext_wmi_fcc_rule); 16595 16596 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 16597 } else { 16598 wmi_err("Fcc rules not sent by fw"); 16599 } 16600 16601 if (reg_info->fcc_rules_ptr) { 16602 for (i = 0; i < reg_info->num_fcc_rules; i++) { 16603 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 16604 i, reg_info->fcc_rules_ptr[i].center_freq, 16605 reg_info->fcc_rules_ptr[i].tx_power); 16606 } 16607 } 16608 return QDF_STATUS_SUCCESS; 16609 } 16610 #else 16611 static QDF_STATUS extract_reg_fcc_rules_tlv( 16612 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16613 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16614 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16615 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16616 uint8_t *evt_buf, 16617 struct cur_regulatory_info *reg_info, 16618 uint32_t len) 16619 { 16620 return QDF_STATUS_SUCCESS; 16621 } 16622 #endif 16623 16624 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 16625 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16626 struct cur_regulatory_info *reg_info, uint32_t len) 16627 { 16628 uint32_t i, j, k; 16629 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 16630 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 16631 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 16632 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 16633 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16634 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 16635 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 16636 uint32_t total_reg_rules = 0; 16637 QDF_STATUS status; 16638 16639 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 16640 if (!param_buf) { 16641 wmi_err("invalid channel list event buf"); 16642 return QDF_STATUS_E_FAILURE; 16643 } 16644 16645 ext_chan_list_event_hdr = param_buf->fixed_param; 16646 ext_wmi_chan_priority = param_buf->reg_chan_priority; 16647 16648 if (ext_wmi_chan_priority) 16649 reg_info->reg_6g_thresh_priority_freq = 16650 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 16651 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 16652 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 16653 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 16654 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 16655 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 16656 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 16657 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 16658 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 16659 16660 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 16661 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16662 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16663 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16664 16665 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16666 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 16667 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 16668 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 16669 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 16670 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 16671 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 16672 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 16673 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 16674 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 16675 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 16676 } 16677 16678 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16679 total_reg_rules += num_2g_reg_rules; 16680 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16681 total_reg_rules += num_5g_reg_rules; 16682 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16683 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 16684 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 16685 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 16686 num_6g_reg_rules_ap[i]); 16687 return QDF_STATUS_E_FAILURE; 16688 } 16689 total_reg_rules += num_6g_reg_rules_ap[i]; 16690 num_6g_reg_rules_client[i] = 16691 reg_info->num_6g_reg_rules_client[i]; 16692 } 16693 16694 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16695 total_reg_rules += 16696 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 16697 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 16698 total_reg_rules += 16699 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 16700 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 16701 MAX_6G_REG_RULES) || 16702 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 16703 MAX_6G_REG_RULES) || 16704 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 16705 MAX_6G_REG_RULES)) { 16706 wmi_err_rl("Invalid num_6g_reg_rules_client_sp: %u, num_6g_reg_rules_client_lpi: %u, num_6g_reg_rules_client_vlp: %u, client %d", 16707 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 16708 num_6g_reg_rules_client[REG_INDOOR_AP][i], 16709 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 16710 i); 16711 return QDF_STATUS_E_FAILURE; 16712 } 16713 } 16714 16715 if (total_reg_rules != param_buf->num_reg_rule_array) { 16716 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 16717 total_reg_rules, param_buf->num_reg_rule_array); 16718 return QDF_STATUS_E_FAILURE; 16719 } 16720 16721 if ((num_2g_reg_rules > MAX_REG_RULES) || 16722 (num_5g_reg_rules > MAX_REG_RULES)) { 16723 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16724 num_2g_reg_rules, num_5g_reg_rules); 16725 return QDF_STATUS_E_FAILURE; 16726 } 16727 16728 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 16729 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 16730 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 16731 wmi_err_rl("Invalid num_6g_reg_rules_ap_sp: %u, num_6g_reg_rules_ap_lpi: %u, num_6g_reg_rules_ap_vlp: %u", 16732 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16733 num_6g_reg_rules_ap[REG_INDOOR_AP], 16734 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16735 return QDF_STATUS_E_FAILURE; 16736 } 16737 16738 if (param_buf->num_reg_rule_array > 16739 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 16740 sizeof(*ext_wmi_reg_rule)) { 16741 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 16742 param_buf->num_reg_rule_array); 16743 return QDF_STATUS_E_FAILURE; 16744 } 16745 16746 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 16747 REG_ALPHA2_LEN); 16748 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 16749 reg_info->phybitmap = convert_phybitmap_tlv( 16750 ext_chan_list_event_hdr->phybitmap); 16751 reg_info->offload_enabled = true; 16752 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 16753 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16754 wmi_handle, ext_chan_list_event_hdr->phy_id); 16755 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 16756 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 16757 16758 reg_info->status_code = 16759 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 16760 status_code); 16761 16762 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 16763 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 16764 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 16765 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 16766 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 16767 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 16768 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 16769 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 16770 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 16771 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 16772 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 16773 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 16774 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16775 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 16776 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16777 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 16778 16779 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16780 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16781 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 16782 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16783 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 16784 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 16785 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 16786 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 16787 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 16788 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16789 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 16790 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16791 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 16792 } 16793 16794 wmi_nofl_debug("num_phys = %u and phy_id = %u", 16795 reg_info->num_phy, reg_info->phy_id); 16796 16797 wmi_nofl_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 16798 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16799 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 16800 reg_info->max_bw_5g); 16801 16802 wmi_nofl_debug("min_bw_6g_ap_sp %d max_bw_6g_ap_sp %d min_bw_6g_ap_lpi %d max_bw_6g_ap_lpi %d min_bw_6g_ap_vlp %d max_bw_6g_ap_vlp %d", 16803 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 16804 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 16805 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 16806 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 16807 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 16808 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 16809 16810 wmi_nofl_debug("min_bw_6g_def_cli_sp %d max_bw_6g_def_cli_sp %d min_bw_6g_def_cli_lpi %d max_bw_6g_def_cli_lpi %d min_bw_6g_def_cli_vlp %d max_bw_6g_def_cli_vlp %d", 16811 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16812 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16813 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16814 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16815 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 16816 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16817 16818 wmi_nofl_debug("min_bw_6g_sub_client_sp %d max_bw_6g_sub_client_sp %d min_bw_6g_sub_client_lpi %d max_bw_6g_sub_client_lpi %d min_bw_6g_sub_client_vlp %d max_bw_6g_sub_client_vlp %d", 16819 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16820 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16821 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16822 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16823 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 16824 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16825 16826 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16827 num_2g_reg_rules, num_5g_reg_rules); 16828 16829 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 16830 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16831 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16832 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16833 16834 wmi_nofl_debug("num_6g_def_cli_sp_reg_rules %d num_6g_def_cli_lpi_reg_rules %d num_6g_def_cli_vlp_reg_rules %d", 16835 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16836 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16837 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16838 16839 wmi_nofl_debug("num_6g_sub_cli_sp_reg_rules %d num_6g_sub_cli_lpi_reg_rules %d num_6g_sub_cli_vlp_reg_rules %d", 16840 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16841 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16842 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16843 16844 ext_wmi_reg_rule = 16845 (wmi_regulatory_rule_ext_struct *) 16846 ((uint8_t *)ext_chan_list_event_hdr + 16847 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16848 WMI_TLV_HDR_SIZE); 16849 reg_info->reg_rules_2g_ptr = 16850 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 16851 ext_wmi_reg_rule); 16852 ext_wmi_reg_rule += num_2g_reg_rules; 16853 if (!num_2g_reg_rules) 16854 wmi_nofl_debug("No 2ghz reg rule"); 16855 for (i = 0; i < num_2g_reg_rules; i++) { 16856 if (!reg_info->reg_rules_2g_ptr) 16857 break; 16858 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16859 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16860 reg_info->reg_rules_2g_ptr[i].end_freq, 16861 reg_info->reg_rules_2g_ptr[i].max_bw, 16862 reg_info->reg_rules_2g_ptr[i].reg_power, 16863 reg_info->reg_rules_2g_ptr[i].ant_gain, 16864 reg_info->reg_rules_2g_ptr[i].flags, 16865 reg_info->reg_rules_2g_ptr[i].psd_flag, 16866 reg_info->reg_rules_2g_ptr[i].psd_eirp); 16867 } 16868 reg_info->reg_rules_5g_ptr = 16869 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 16870 ext_wmi_reg_rule); 16871 ext_wmi_reg_rule += num_5g_reg_rules; 16872 if (!num_5g_reg_rules) 16873 wmi_nofl_debug("No 5ghz reg rule"); 16874 for (i = 0; i < num_5g_reg_rules; i++) { 16875 if (!reg_info->reg_rules_5g_ptr) 16876 break; 16877 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16878 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16879 reg_info->reg_rules_5g_ptr[i].end_freq, 16880 reg_info->reg_rules_5g_ptr[i].max_bw, 16881 reg_info->reg_rules_5g_ptr[i].reg_power, 16882 reg_info->reg_rules_5g_ptr[i].ant_gain, 16883 reg_info->reg_rules_5g_ptr[i].flags, 16884 reg_info->reg_rules_5g_ptr[i].psd_flag, 16885 reg_info->reg_rules_5g_ptr[i].psd_eirp); 16886 } 16887 16888 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16889 reg_print_ap_power_type_6ghz(i); 16890 reg_info->reg_rules_6g_ap_ptr[i] = 16891 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 16892 ext_wmi_reg_rule); 16893 16894 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 16895 if (!num_6g_reg_rules_ap[i]) 16896 wmi_nofl_debug("No 6ghz reg rule"); 16897 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 16898 if (!reg_info->reg_rules_6g_ap_ptr[i]) 16899 break; 16900 wmi_nofl_debug("AP 6GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16901 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 16902 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 16903 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 16904 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 16905 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 16906 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 16907 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 16908 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 16909 } 16910 } 16911 16912 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 16913 reg_print_ap_power_type_6ghz(j); 16914 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16915 reg_print_6ghz_client_type(i); 16916 reg_info->reg_rules_6g_client_ptr[j][i] = 16917 create_ext_reg_rules_from_wmi( 16918 num_6g_reg_rules_client[j][i], 16919 ext_wmi_reg_rule); 16920 16921 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 16922 if (!num_6g_reg_rules_client[j][i]) 16923 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 16924 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 16925 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 16926 break; 16927 wmi_nofl_debug("CLI 6GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u psd_flag %u psd_eirp %u", 16928 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 16929 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 16930 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 16931 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 16932 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 16933 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 16934 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 16935 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 16936 } 16937 } 16938 } 16939 16940 reg_info->client_type = ext_chan_list_event_hdr->client_type; 16941 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 16942 reg_info->unspecified_ap_usable = 16943 ext_chan_list_event_hdr->unspecified_ap_usable; 16944 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 16945 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 16946 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 16947 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 16948 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 16949 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 16950 16951 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16952 reg_info->client_type, reg_info->rnr_tpe_usable, 16953 reg_info->unspecified_ap_usable, 16954 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16955 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16956 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16957 16958 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16959 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16960 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16961 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16962 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16963 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16964 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16965 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16966 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16967 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16968 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16969 } 16970 16971 reg_info->domain_code_6g_super_id = 16972 ext_chan_list_event_hdr->domain_code_6g_super_id; 16973 16974 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16975 ext_wmi_reg_rule, ext_wmi_chan_priority, 16976 evt_buf, reg_info, len); 16977 if (status != QDF_STATUS_SUCCESS) 16978 return status; 16979 16980 return QDF_STATUS_SUCCESS; 16981 } 16982 16983 #ifdef CONFIG_AFC_SUPPORT 16984 /** 16985 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16986 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16987 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16988 * an index pointer required to store the current index of 16989 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16990 * @chan_eirp_info: pointer to chan_eirp_info 16991 * @num_chans: Number of channels 16992 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16993 * @index: Pointer to index 16994 * 16995 * Return: void 16996 */ 16997 static void 16998 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 16999 uint8_t num_chans, 17000 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 17001 uint8_t *index) 17002 { 17003 uint8_t chan_idx; 17004 17005 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 17006 chan_eirp_info[chan_idx].cfi = 17007 chan_eirp_power_info_hdr[*index].channel_cfi; 17008 chan_eirp_info[chan_idx].eirp_power = 17009 chan_eirp_power_info_hdr[*index].eirp_pwr; 17010 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 17011 chan_idx, 17012 chan_eirp_info[chan_idx].cfi, 17013 chan_eirp_info[chan_idx].eirp_power); 17014 } 17015 } 17016 17017 /** 17018 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 17019 * to the internal buffer afc_chan_info. 17020 * @afc_chan_info: pointer to afc_chan_info 17021 * @num_chan_objs: Number of channel objects 17022 * @channel_info_hdr: Pointer to channel_info_hdr 17023 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 17024 * 17025 * Return: void 17026 */ 17027 static void 17028 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 17029 uint8_t num_chan_objs, 17030 wmi_6g_afc_channel_info *channel_info_hdr, 17031 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 17032 { 17033 uint8_t count; 17034 uint8_t src_pwr_index = 0; 17035 17036 for (count = 0; count < num_chan_objs; count++) { 17037 afc_chan_info[count].global_opclass = 17038 channel_info_hdr[count].global_operating_class; 17039 afc_chan_info[count].num_chans = 17040 channel_info_hdr[count].num_channels; 17041 wmi_debug("Chan object count = %d global opclasss = %d", 17042 count, 17043 afc_chan_info[count].global_opclass); 17044 wmi_debug("Number of Channel EIRP objects = %d", 17045 afc_chan_info[count].num_chans); 17046 17047 if (afc_chan_info[count].num_chans > 0) { 17048 struct chan_eirp_obj *chan_eirp_info; 17049 17050 chan_eirp_info = 17051 qdf_mem_malloc(afc_chan_info[count].num_chans * 17052 sizeof(*chan_eirp_info)); 17053 17054 if (!chan_eirp_info) 17055 return; 17056 17057 copy_afc_chan_eirp_info(chan_eirp_info, 17058 afc_chan_info[count].num_chans, 17059 chan_eirp_power_info_hdr, 17060 &src_pwr_index); 17061 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 17062 } else { 17063 wmi_err("Number of channels is zero in object idx %d", 17064 count); 17065 } 17066 } 17067 } 17068 17069 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 17070 uint8_t num_freq_objs, 17071 wmi_6g_afc_frequency_info *freq_info_hdr) 17072 { 17073 uint8_t count; 17074 17075 for (count = 0; count < num_freq_objs; count++) { 17076 afc_freq_info[count].low_freq = 17077 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 17078 afc_freq_info[count].high_freq = 17079 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 17080 afc_freq_info[count].max_psd = 17081 freq_info_hdr[count].psd_power_info; 17082 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 17083 count, 17084 afc_freq_info[count].low_freq, 17085 afc_freq_info[count].high_freq, 17086 afc_freq_info[count].max_psd); 17087 } 17088 } 17089 17090 /** 17091 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 17092 * the power event info from the WMI AFC event buffer to the internal buffer 17093 * power_info. 17094 * @power_info: pointer to power_info 17095 * @afc_power_event_hdr: pointer to afc_power_event_hdr 17096 * 17097 * Return: void 17098 */ 17099 static void 17100 copy_afc_event_fixed_hdr_power_info( 17101 struct reg_fw_afc_power_event *power_info, 17102 wmi_afc_power_event_param *afc_power_event_hdr) 17103 { 17104 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 17105 power_info->resp_id = afc_power_event_hdr->resp_id; 17106 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 17107 power_info->afc_wfa_version = 17108 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 17109 power_info->afc_wfa_version |= 17110 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 17111 17112 power_info->avail_exp_time_d = 17113 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 17114 power_info->avail_exp_time_d |= 17115 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 17116 power_info->avail_exp_time_d |= 17117 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 17118 17119 power_info->avail_exp_time_t = 17120 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 17121 power_info->avail_exp_time_t |= 17122 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 17123 power_info->avail_exp_time_t |= 17124 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 17125 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 17126 power_info->fw_status_code, 17127 power_info->resp_id, 17128 power_info->serv_resp_code); 17129 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 17130 power_info->afc_wfa_version, 17131 power_info->avail_exp_time_d, 17132 power_info->avail_exp_time_t); 17133 } 17134 17135 /** 17136 * copy_power_event() - Copy the power event parameters from the AFC event 17137 * buffer to the power_info within the afc_info. 17138 * @afc_info: pointer to afc_info 17139 * @param_buf: pointer to param_buf 17140 * 17141 * Return: void 17142 */ 17143 static void copy_power_event(struct afc_regulatory_info *afc_info, 17144 WMI_AFC_EVENTID_param_tlvs *param_buf) 17145 { 17146 struct reg_fw_afc_power_event *power_info; 17147 wmi_afc_power_event_param *afc_power_event_hdr; 17148 struct afc_freq_obj *afc_freq_info; 17149 17150 power_info = qdf_mem_malloc(sizeof(*power_info)); 17151 17152 if (!power_info) 17153 return; 17154 17155 afc_power_event_hdr = param_buf->afc_power_event_param; 17156 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 17157 afc_info->power_info = power_info; 17158 17159 power_info->num_freq_objs = param_buf->num_freq_info_array; 17160 wmi_debug("Number of frequency objects = %d", 17161 power_info->num_freq_objs); 17162 if (power_info->num_freq_objs > 0) { 17163 wmi_6g_afc_frequency_info *freq_info_hdr; 17164 17165 freq_info_hdr = param_buf->freq_info_array; 17166 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 17167 sizeof(*afc_freq_info)); 17168 17169 if (!afc_freq_info) 17170 return; 17171 17172 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 17173 freq_info_hdr); 17174 power_info->afc_freq_info = afc_freq_info; 17175 } else { 17176 wmi_err("Number of frequency objects is zero"); 17177 } 17178 17179 power_info->num_chan_objs = param_buf->num_channel_info_array; 17180 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 17181 if (power_info->num_chan_objs > 0) { 17182 struct afc_chan_obj *afc_chan_info; 17183 wmi_6g_afc_channel_info *channel_info_hdr; 17184 17185 channel_info_hdr = param_buf->channel_info_array; 17186 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 17187 sizeof(*afc_chan_info)); 17188 17189 if (!afc_chan_info) 17190 return; 17191 17192 copy_afc_chan_obj_info(afc_chan_info, 17193 power_info->num_chan_objs, 17194 channel_info_hdr, 17195 param_buf->chan_eirp_power_info_array); 17196 power_info->afc_chan_info = afc_chan_info; 17197 } else { 17198 wmi_err("Number of channel objects is zero"); 17199 } 17200 } 17201 17202 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 17203 WMI_AFC_EVENTID_param_tlvs *param_buf) 17204 { 17205 struct reg_afc_expiry_event *expiry_info; 17206 17207 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 17208 17209 if (!expiry_info) 17210 return; 17211 17212 expiry_info->request_id = 17213 param_buf->expiry_event_param->request_id; 17214 expiry_info->event_subtype = 17215 param_buf->expiry_event_param->event_subtype; 17216 wmi_debug("Event subtype %d request ID %d", 17217 expiry_info->event_subtype, 17218 expiry_info->request_id); 17219 afc_info->expiry_info = expiry_info; 17220 } 17221 17222 /** 17223 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 17224 * in the AFC event. 'Common' indicates that these parameters are common for 17225 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 17226 * @wmi_handle: wmi handle 17227 * @afc_info: pointer to afc_info 17228 * @event_fixed_hdr: pointer to event_fixed_hdr 17229 * 17230 * Return: void 17231 */ 17232 static void 17233 copy_afc_event_common_info(wmi_unified_t wmi_handle, 17234 struct afc_regulatory_info *afc_info, 17235 wmi_afc_event_fixed_param *event_fixed_hdr) 17236 { 17237 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17238 wmi_handle, event_fixed_hdr->phy_id); 17239 wmi_debug("phy_id %d", afc_info->phy_id); 17240 afc_info->event_type = event_fixed_hdr->event_type; 17241 } 17242 17243 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 17244 uint8_t *evt_buf, 17245 struct afc_regulatory_info *afc_info, 17246 uint32_t len) 17247 { 17248 WMI_AFC_EVENTID_param_tlvs *param_buf; 17249 wmi_afc_event_fixed_param *event_fixed_hdr; 17250 17251 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 17252 if (!param_buf) { 17253 wmi_err("Invalid AFC event buf"); 17254 return QDF_STATUS_E_FAILURE; 17255 } 17256 17257 event_fixed_hdr = param_buf->fixed_param; 17258 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 17259 wmi_debug("AFC event type %d received", afc_info->event_type); 17260 17261 switch (afc_info->event_type) { 17262 case WMI_AFC_EVENT_POWER_INFO: 17263 copy_power_event(afc_info, param_buf); 17264 break; 17265 case WMI_AFC_EVENT_TIMER_EXPIRY: 17266 copy_expiry_event(afc_info, param_buf); 17267 return QDF_STATUS_SUCCESS; 17268 default: 17269 wmi_err("Invalid event type"); 17270 return QDF_STATUS_E_FAILURE; 17271 } 17272 17273 return QDF_STATUS_SUCCESS; 17274 } 17275 #endif 17276 #endif 17277 17278 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 17279 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17280 struct cur_regulatory_info *reg_info, uint32_t len) 17281 { 17282 uint32_t i; 17283 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 17284 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 17285 wmi_regulatory_rule_struct *wmi_reg_rule; 17286 uint32_t num_2g_reg_rules, num_5g_reg_rules; 17287 17288 wmi_debug("processing regulatory channel list"); 17289 17290 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 17291 if (!param_buf) { 17292 wmi_err("invalid channel list event buf"); 17293 return QDF_STATUS_E_FAILURE; 17294 } 17295 17296 chan_list_event_hdr = param_buf->fixed_param; 17297 17298 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 17299 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 17300 num_2g_reg_rules = reg_info->num_2g_reg_rules; 17301 num_5g_reg_rules = reg_info->num_5g_reg_rules; 17302 if ((num_2g_reg_rules > MAX_REG_RULES) || 17303 (num_5g_reg_rules > MAX_REG_RULES) || 17304 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 17305 (num_2g_reg_rules + num_5g_reg_rules != 17306 param_buf->num_reg_rule_array)) { 17307 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 17308 num_2g_reg_rules, num_5g_reg_rules); 17309 return QDF_STATUS_E_FAILURE; 17310 } 17311 if (param_buf->num_reg_rule_array > 17312 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 17313 sizeof(*wmi_reg_rule)) { 17314 wmi_err_rl("Invalid num_reg_rule_array: %u", 17315 param_buf->num_reg_rule_array); 17316 return QDF_STATUS_E_FAILURE; 17317 } 17318 17319 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 17320 REG_ALPHA2_LEN); 17321 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 17322 reg_info->phybitmap = convert_phybitmap_tlv( 17323 chan_list_event_hdr->phybitmap); 17324 reg_info->offload_enabled = true; 17325 reg_info->num_phy = chan_list_event_hdr->num_phy; 17326 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17327 wmi_handle, chan_list_event_hdr->phy_id); 17328 reg_info->ctry_code = chan_list_event_hdr->country_id; 17329 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 17330 17331 reg_info->status_code = 17332 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 17333 17334 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 17335 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 17336 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 17337 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 17338 17339 wmi_debug("num_phys = %u and phy_id = %u", 17340 reg_info->num_phy, reg_info->phy_id); 17341 17342 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 17343 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 17344 reg_info->min_bw_2g, reg_info->max_bw_2g, 17345 reg_info->min_bw_5g, reg_info->max_bw_5g); 17346 17347 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 17348 num_2g_reg_rules, num_5g_reg_rules); 17349 wmi_reg_rule = 17350 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 17351 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 17352 + WMI_TLV_HDR_SIZE); 17353 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 17354 wmi_reg_rule); 17355 wmi_reg_rule += num_2g_reg_rules; 17356 if (!num_2g_reg_rules) 17357 wmi_nofl_debug("No 2ghz reg rule"); 17358 for (i = 0; i < num_2g_reg_rules; i++) { 17359 if (!reg_info->reg_rules_2g_ptr) 17360 break; 17361 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17362 i, reg_info->reg_rules_2g_ptr[i].start_freq, 17363 reg_info->reg_rules_2g_ptr[i].end_freq, 17364 reg_info->reg_rules_2g_ptr[i].max_bw, 17365 reg_info->reg_rules_2g_ptr[i].reg_power, 17366 reg_info->reg_rules_2g_ptr[i].ant_gain, 17367 reg_info->reg_rules_2g_ptr[i].flags); 17368 } 17369 17370 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 17371 wmi_reg_rule); 17372 if (!num_5g_reg_rules) 17373 wmi_nofl_debug("No 5ghz reg rule"); 17374 for (i = 0; i < num_5g_reg_rules; i++) { 17375 if (!reg_info->reg_rules_5g_ptr) 17376 break; 17377 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17378 i, reg_info->reg_rules_5g_ptr[i].start_freq, 17379 reg_info->reg_rules_5g_ptr[i].end_freq, 17380 reg_info->reg_rules_5g_ptr[i].max_bw, 17381 reg_info->reg_rules_5g_ptr[i].reg_power, 17382 reg_info->reg_rules_5g_ptr[i].ant_gain, 17383 reg_info->reg_rules_5g_ptr[i].flags); 17384 } 17385 17386 wmi_debug("processed regulatory channel list"); 17387 17388 return QDF_STATUS_SUCCESS; 17389 } 17390 17391 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 17392 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17393 struct reg_11d_new_country *reg_11d_country, uint32_t len) 17394 { 17395 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 17396 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 17397 17398 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 17399 if (!param_buf) { 17400 wmi_err("invalid 11d country event buf"); 17401 return QDF_STATUS_E_FAILURE; 17402 } 17403 17404 reg_11d_country_event = param_buf->fixed_param; 17405 17406 qdf_mem_copy(reg_11d_country->alpha2, 17407 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 17408 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 17409 17410 wmi_debug("processed 11d country event, new cc %s", 17411 reg_11d_country->alpha2); 17412 17413 return QDF_STATUS_SUCCESS; 17414 } 17415 17416 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 17417 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17418 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 17419 { 17420 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 17421 wmi_avoid_freq_range_desc *afr_desc; 17422 uint32_t num_freq_ranges, freq_range_idx; 17423 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 17424 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 17425 17426 if (!param_buf) { 17427 wmi_err("Invalid channel avoid event buffer"); 17428 return QDF_STATUS_E_INVAL; 17429 } 17430 17431 afr_fixed_param = param_buf->fixed_param; 17432 if (!afr_fixed_param) { 17433 wmi_err("Invalid channel avoid event fixed param buffer"); 17434 return QDF_STATUS_E_INVAL; 17435 } 17436 17437 if (!ch_avoid_ind) { 17438 wmi_err("Invalid channel avoid indication buffer"); 17439 return QDF_STATUS_E_INVAL; 17440 } 17441 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 17442 wmi_err("no.of freq ranges exceeded the limit"); 17443 return QDF_STATUS_E_INVAL; 17444 } 17445 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 17446 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 17447 afr_fixed_param->num_freq_ranges; 17448 17449 wmi_debug("Channel avoid event received with %d ranges", 17450 num_freq_ranges); 17451 17452 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 17453 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 17454 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 17455 freq_range_idx++) { 17456 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 17457 afr_desc->start_freq; 17458 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 17459 afr_desc->end_freq; 17460 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 17461 freq_range_idx, afr_desc->tlv_header, 17462 afr_desc->start_freq, afr_desc->end_freq); 17463 afr_desc++; 17464 } 17465 17466 return QDF_STATUS_SUCCESS; 17467 } 17468 17469 #ifdef DFS_COMPONENT_ENABLE 17470 /** 17471 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 17472 * @wmi_handle: wma handle 17473 * @evt_buf: event buffer 17474 * @vdev_id: vdev id 17475 * @len: length of buffer 17476 * 17477 * Return: QDF_STATUS_SUCCESS for success or error code 17478 */ 17479 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 17480 uint8_t *evt_buf, 17481 uint32_t *vdev_id, 17482 uint32_t len) 17483 { 17484 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17485 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 17486 17487 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 17488 if (!param_tlvs) { 17489 wmi_err("invalid cac complete event buf"); 17490 return QDF_STATUS_E_FAILURE; 17491 } 17492 17493 cac_event = param_tlvs->fixed_param; 17494 *vdev_id = cac_event->vdev_id; 17495 wmi_debug("processed cac complete event vdev %d", *vdev_id); 17496 17497 return QDF_STATUS_SUCCESS; 17498 } 17499 17500 /** 17501 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 17502 * @wmi_handle: wma handle 17503 * @evt_buf: event buffer 17504 * @param: extracted event 17505 * 17506 * Return: QDF_STATUS_SUCCESS for success or error code 17507 */ 17508 static QDF_STATUS 17509 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 17510 uint8_t *evt_buf, 17511 struct vdev_adfs_complete_status *param) 17512 { 17513 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17514 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 17515 17516 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17517 if (!param_tlvs) { 17518 wmi_err("invalid ocac complete event buf"); 17519 return QDF_STATUS_E_FAILURE; 17520 } 17521 17522 if (!param_tlvs->fixed_param) { 17523 wmi_err("invalid param_tlvs->fixed_param"); 17524 return QDF_STATUS_E_FAILURE; 17525 } 17526 17527 ocac_complete_status = param_tlvs->fixed_param; 17528 param->vdev_id = ocac_complete_status->vdev_id; 17529 param->chan_freq = ocac_complete_status->chan_freq; 17530 param->center_freq1 = ocac_complete_status->center_freq1; 17531 param->center_freq2 = ocac_complete_status->center_freq2; 17532 param->ocac_status = ocac_complete_status->status; 17533 param->chan_width = ocac_complete_status->chan_width; 17534 wmi_debug("processed ocac complete event vdev %d" 17535 " agile chan %d %d width %d status %d", 17536 param->vdev_id, 17537 param->center_freq1, 17538 param->center_freq2, 17539 param->chan_width, 17540 param->ocac_status); 17541 17542 return QDF_STATUS_SUCCESS; 17543 } 17544 17545 /** 17546 * extract_dfs_radar_detection_event_tlv() - extract radar found event 17547 * @wmi_handle: wma handle 17548 * @evt_buf: event buffer 17549 * @radar_found: radar found event info 17550 * @len: length of buffer 17551 * 17552 * Return: QDF_STATUS_SUCCESS for success or error code 17553 */ 17554 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 17555 wmi_unified_t wmi_handle, 17556 uint8_t *evt_buf, 17557 struct radar_found_info *radar_found, 17558 uint32_t len) 17559 { 17560 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 17561 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 17562 17563 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 17564 if (!param_tlv) { 17565 wmi_err("invalid radar detection event buf"); 17566 return QDF_STATUS_E_FAILURE; 17567 } 17568 17569 radar_event = param_tlv->fixed_param; 17570 17571 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17572 wmi_handle, 17573 radar_event->pdev_id); 17574 17575 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17576 return QDF_STATUS_E_FAILURE; 17577 17578 qdf_mem_zero(radar_found, sizeof(struct radar_found_info)); 17579 radar_found->detection_mode = radar_event->detection_mode; 17580 radar_found->chan_freq = radar_event->chan_freq; 17581 radar_found->chan_width = radar_event->chan_width; 17582 radar_found->detector_id = radar_event->detector_id; 17583 radar_found->segment_id = radar_event->segment_id; 17584 radar_found->timestamp = radar_event->timestamp; 17585 radar_found->is_chirp = radar_event->is_chirp; 17586 radar_found->freq_offset = radar_event->freq_offset; 17587 radar_found->sidx = radar_event->sidx; 17588 17589 if (is_service_enabled_tlv(wmi_handle, 17590 WMI_SERVICE_RADAR_FLAGS_SUPPORT)) { 17591 WMI_RADAR_FLAGS *radar_flags; 17592 17593 radar_flags = param_tlv->radar_flags; 17594 if (radar_flags) { 17595 radar_found->is_full_bw_nol = 17596 WMI_RADAR_FLAGS_FULL_BW_NOL_GET(radar_flags->flags); 17597 wmi_debug("Is full bw nol %d", 17598 radar_found->is_full_bw_nol); 17599 } 17600 } 17601 17602 wmi_debug("processed radar found event pdev %d," 17603 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 17604 "chan_width (RSSI) %d,detector_id (false_radar) %d," 17605 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 17606 "is_chirp %d,detection mode %d", 17607 radar_event->pdev_id, radar_found->pdev_id, 17608 radar_event->timestamp, radar_event->chan_freq, 17609 radar_event->chan_width, radar_event->detector_id, 17610 radar_event->freq_offset, radar_event->segment_id, 17611 radar_event->sidx, radar_event->is_chirp, 17612 radar_event->detection_mode); 17613 17614 return QDF_STATUS_SUCCESS; 17615 } 17616 17617 #ifdef MOBILE_DFS_SUPPORT 17618 /** 17619 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 17620 * @wmi_handle: wma handle 17621 * @evt_buf: event buffer 17622 * @wlan_radar_event: Pointer to struct radar_event_info 17623 * @len: length of buffer 17624 * 17625 * Return: QDF_STATUS 17626 */ 17627 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17628 wmi_unified_t wmi_handle, 17629 uint8_t *evt_buf, 17630 struct radar_event_info *wlan_radar_event, 17631 uint32_t len) 17632 { 17633 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 17634 wmi_dfs_radar_event_fixed_param *radar_event; 17635 17636 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 17637 if (!param_tlv) { 17638 wmi_err("invalid wlan radar event buf"); 17639 return QDF_STATUS_E_FAILURE; 17640 } 17641 17642 radar_event = param_tlv->fixed_param; 17643 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 17644 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 17645 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 17646 wlan_radar_event->rssi = radar_event->rssi; 17647 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 17648 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 17649 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 17650 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 17651 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 17652 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 17653 if (radar_event->pulse_flags & 17654 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 17655 wlan_radar_event->is_psidx_diff_valid = true; 17656 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 17657 } else { 17658 wlan_radar_event->is_psidx_diff_valid = false; 17659 } 17660 17661 wlan_radar_event->pdev_id = radar_event->pdev_id; 17662 17663 return QDF_STATUS_SUCCESS; 17664 } 17665 #else 17666 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17667 wmi_unified_t wmi_handle, 17668 uint8_t *evt_buf, 17669 struct radar_event_info *wlan_radar_event, 17670 uint32_t len) 17671 { 17672 return QDF_STATUS_SUCCESS; 17673 } 17674 #endif 17675 #endif 17676 17677 /** 17678 * send_get_rcpi_cmd_tlv() - send request for rcpi value 17679 * @wmi_handle: wmi handle 17680 * @get_rcpi_param: rcpi params 17681 * 17682 * Return: QDF status 17683 */ 17684 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 17685 struct rcpi_req *get_rcpi_param) 17686 { 17687 wmi_buf_t buf; 17688 wmi_request_rcpi_cmd_fixed_param *cmd; 17689 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 17690 17691 buf = wmi_buf_alloc(wmi_handle, len); 17692 if (!buf) 17693 return QDF_STATUS_E_NOMEM; 17694 17695 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 17696 WMITLV_SET_HDR(&cmd->tlv_header, 17697 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 17698 WMITLV_GET_STRUCT_TLVLEN 17699 (wmi_request_rcpi_cmd_fixed_param)); 17700 17701 cmd->vdev_id = get_rcpi_param->vdev_id; 17702 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 17703 &cmd->peer_macaddr); 17704 17705 switch (get_rcpi_param->measurement_type) { 17706 17707 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17708 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17709 break; 17710 17711 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 17712 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 17713 break; 17714 17715 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17716 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17717 break; 17718 17719 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 17720 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 17721 break; 17722 17723 default: 17724 /* 17725 * invalid rcpi measurement type, fall back to 17726 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 17727 */ 17728 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17729 break; 17730 } 17731 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 17732 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 17733 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17734 WMI_REQUEST_RCPI_CMDID)) { 17735 17736 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 17737 wmi_buf_free(buf); 17738 return QDF_STATUS_E_FAILURE; 17739 } 17740 17741 return QDF_STATUS_SUCCESS; 17742 } 17743 17744 /** 17745 * extract_rcpi_response_event_tlv() - Extract RCPI event params 17746 * @wmi_handle: wmi handle 17747 * @evt_buf: pointer to event buffer 17748 * @res: pointer to hold rcpi response from firmware 17749 * 17750 * Return: QDF_STATUS_SUCCESS for successful event parse 17751 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 17752 */ 17753 static QDF_STATUS 17754 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 17755 void *evt_buf, struct rcpi_res *res) 17756 { 17757 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 17758 wmi_update_rcpi_event_fixed_param *event; 17759 17760 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 17761 if (!param_buf) { 17762 wmi_err("Invalid rcpi event"); 17763 return QDF_STATUS_E_INVAL; 17764 } 17765 17766 event = param_buf->fixed_param; 17767 res->vdev_id = event->vdev_id; 17768 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 17769 17770 switch (event->measurement_type) { 17771 17772 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17773 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17774 break; 17775 17776 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 17777 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 17778 break; 17779 17780 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17781 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17782 break; 17783 17784 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 17785 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 17786 break; 17787 17788 default: 17789 wmi_err("Invalid rcpi measurement type from firmware"); 17790 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 17791 return QDF_STATUS_E_FAILURE; 17792 } 17793 17794 if (event->status) 17795 return QDF_STATUS_E_FAILURE; 17796 else 17797 return QDF_STATUS_SUCCESS; 17798 } 17799 17800 /** 17801 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 17802 * host to target defines. For legacy there is not conversion 17803 * required. Just return pdev_id as it is. 17804 * @wmi_handle: handle to WMI. 17805 * @pdev_id: host pdev_id to be converted. 17806 * Return: target pdev_id after conversion. 17807 */ 17808 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 17809 wmi_unified_t wmi_handle, 17810 uint32_t pdev_id) 17811 { 17812 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 17813 return WMI_PDEV_ID_SOC; 17814 17815 /*No conversion required*/ 17816 return pdev_id; 17817 } 17818 17819 /** 17820 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 17821 * target to host defines. For legacy there is not conversion 17822 * required. Just return pdev_id as it is. 17823 * @wmi_handle: handle to WMI. 17824 * @pdev_id: target pdev_id to be converted. 17825 * Return: host pdev_id after conversion. 17826 */ 17827 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 17828 wmi_unified_t wmi_handle, 17829 uint32_t pdev_id) 17830 { 17831 /*No conversion required*/ 17832 return pdev_id; 17833 } 17834 17835 /** 17836 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 17837 * host to target defines. For legacy there is not conversion 17838 * required. Just return phy_id as it is. 17839 * @wmi_handle: handle to WMI. 17840 * @phy_id: host phy_id to be converted. 17841 * 17842 * Return: target phy_id after conversion. 17843 */ 17844 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 17845 wmi_unified_t wmi_handle, 17846 uint32_t phy_id) 17847 { 17848 /*No conversion required*/ 17849 return phy_id; 17850 } 17851 17852 /** 17853 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 17854 * target to host defines. For legacy there is not conversion 17855 * required. Just return phy_id as it is. 17856 * @wmi_handle: handle to WMI. 17857 * @phy_id: target phy_id to be converted. 17858 * 17859 * Return: host phy_id after conversion. 17860 */ 17861 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 17862 wmi_unified_t wmi_handle, 17863 uint32_t phy_id) 17864 { 17865 /*No conversion required*/ 17866 return phy_id; 17867 } 17868 17869 /** 17870 * send_set_country_cmd_tlv() - WMI scan channel list function 17871 * @wmi_handle: handle to WMI. 17872 * @params: pointer to hold scan channel list parameter 17873 * 17874 * Return: QDF_STATUS_SUCCESS for success or error code 17875 */ 17876 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 17877 struct set_country *params) 17878 { 17879 wmi_buf_t buf; 17880 QDF_STATUS qdf_status; 17881 wmi_set_current_country_cmd_fixed_param *cmd; 17882 uint16_t len = sizeof(*cmd); 17883 uint8_t pdev_id = params->pdev_id; 17884 17885 buf = wmi_buf_alloc(wmi_handle, len); 17886 if (!buf) { 17887 qdf_status = QDF_STATUS_E_NOMEM; 17888 goto end; 17889 } 17890 17891 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 17892 WMITLV_SET_HDR(&cmd->tlv_header, 17893 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 17894 WMITLV_GET_STRUCT_TLVLEN 17895 (wmi_set_current_country_cmd_fixed_param)); 17896 17897 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 17898 wmi_handle, 17899 pdev_id); 17900 wmi_debug("setting current country to %s and target pdev_id = %u", 17901 params->country, cmd->pdev_id); 17902 17903 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 17904 17905 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 17906 qdf_status = wmi_unified_cmd_send(wmi_handle, 17907 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 17908 17909 if (QDF_IS_STATUS_ERROR(qdf_status)) { 17910 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 17911 wmi_buf_free(buf); 17912 } 17913 17914 end: 17915 return qdf_status; 17916 } 17917 17918 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 17919 WMI_SET_BITS(alpha, 0, 8, val0); \ 17920 WMI_SET_BITS(alpha, 8, 8, val1); \ 17921 WMI_SET_BITS(alpha, 16, 8, val2); \ 17922 } while (0) 17923 17924 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 17925 uint8_t pdev_id, struct cc_regdmn_s *rd) 17926 { 17927 wmi_set_init_country_cmd_fixed_param *cmd; 17928 uint16_t len; 17929 wmi_buf_t buf; 17930 int ret; 17931 17932 len = sizeof(wmi_set_init_country_cmd_fixed_param); 17933 buf = wmi_buf_alloc(wmi_handle, len); 17934 if (!buf) 17935 return QDF_STATUS_E_NOMEM; 17936 17937 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 17938 WMITLV_SET_HDR(&cmd->tlv_header, 17939 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 17940 WMITLV_GET_STRUCT_TLVLEN 17941 (wmi_set_init_country_cmd_fixed_param)); 17942 17943 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17944 wmi_handle, 17945 pdev_id); 17946 17947 if (rd->flags == CC_IS_SET) { 17948 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 17949 cmd->country_code.country_id = rd->cc.country_code; 17950 } else if (rd->flags == ALPHA_IS_SET) { 17951 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 17952 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 17953 rd->cc.alpha[0], 17954 rd->cc.alpha[1], 17955 rd->cc.alpha[2]); 17956 } else if (rd->flags == REGDMN_IS_SET) { 17957 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 17958 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 17959 rd->cc.regdmn.reg_2g_5g_pair_id); 17960 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 17961 rd->cc.regdmn.sixg_superdmn_id); 17962 } 17963 17964 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17965 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17966 WMI_SET_INIT_COUNTRY_CMDID); 17967 if (ret) { 17968 wmi_err("Failed to config wow wakeup event"); 17969 wmi_buf_free(buf); 17970 return QDF_STATUS_E_FAILURE; 17971 } 17972 17973 return QDF_STATUS_SUCCESS; 17974 } 17975 17976 /** 17977 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17978 * configurations to firmware. 17979 * @wmi_handle: wmi handle 17980 * @obss_cfg_param: obss detection configurations 17981 * 17982 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17983 * 17984 * Return: QDF_STATUS 17985 */ 17986 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17987 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17988 { 17989 wmi_buf_t buf; 17990 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17991 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17992 17993 buf = wmi_buf_alloc(wmi_handle, len); 17994 if (!buf) 17995 return QDF_STATUS_E_NOMEM; 17996 17997 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 17998 WMITLV_SET_HDR(&cmd->tlv_header, 17999 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 18000 WMITLV_GET_STRUCT_TLVLEN 18001 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 18002 18003 cmd->vdev_id = obss_cfg_param->vdev_id; 18004 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 18005 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 18006 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 18007 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 18008 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 18009 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 18010 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 18011 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 18012 18013 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 18014 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18015 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 18016 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 18017 wmi_buf_free(buf); 18018 return QDF_STATUS_E_FAILURE; 18019 } 18020 18021 return QDF_STATUS_SUCCESS; 18022 } 18023 18024 /** 18025 * extract_obss_detection_info_tlv() - Extract obss detection info 18026 * received from firmware. 18027 * @evt_buf: pointer to event buffer 18028 * @obss_detection: Pointer to hold obss detection info 18029 * 18030 * Return: QDF_STATUS 18031 */ 18032 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 18033 struct wmi_obss_detect_info 18034 *obss_detection) 18035 { 18036 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 18037 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 18038 18039 if (!obss_detection) { 18040 wmi_err("Invalid obss_detection event buffer"); 18041 return QDF_STATUS_E_INVAL; 18042 } 18043 18044 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 18045 if (!param_buf) { 18046 wmi_err("Invalid evt_buf"); 18047 return QDF_STATUS_E_INVAL; 18048 } 18049 18050 fix_param = param_buf->fixed_param; 18051 obss_detection->vdev_id = fix_param->vdev_id; 18052 obss_detection->matched_detection_masks = 18053 fix_param->matched_detection_masks; 18054 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 18055 &obss_detection->matched_bssid_addr[0]); 18056 switch (fix_param->reason) { 18057 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 18058 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 18059 break; 18060 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 18061 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 18062 break; 18063 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 18064 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 18065 break; 18066 default: 18067 wmi_err("Invalid reason: %d", fix_param->reason); 18068 return QDF_STATUS_E_INVAL; 18069 } 18070 18071 return QDF_STATUS_SUCCESS; 18072 } 18073 18074 /** 18075 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 18076 * @wmi_handle: wmi handle 18077 * @params: pointer to request structure 18078 * 18079 * Return: QDF_STATUS 18080 */ 18081 static QDF_STATUS 18082 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 18083 struct wmi_roam_scan_stats_req *params) 18084 { 18085 wmi_buf_t buf; 18086 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 18087 WMITLV_TAG_ID tag; 18088 uint32_t size; 18089 uint32_t len = sizeof(*cmd); 18090 18091 buf = wmi_buf_alloc(wmi_handle, len); 18092 if (!buf) 18093 return QDF_STATUS_E_FAILURE; 18094 18095 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 18096 18097 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 18098 size = WMITLV_GET_STRUCT_TLVLEN( 18099 wmi_request_roam_scan_stats_cmd_fixed_param); 18100 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 18101 18102 cmd->vdev_id = params->vdev_id; 18103 18104 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 18105 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18106 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 18107 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 18108 wmi_buf_free(buf); 18109 return QDF_STATUS_E_FAILURE; 18110 } 18111 18112 return QDF_STATUS_SUCCESS; 18113 } 18114 18115 /** 18116 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 18117 * channel list from firmware 18118 * @wmi_handle: wmi handler 18119 * @vdev_id: vdev id 18120 * 18121 * Return: QDF_STATUS 18122 */ 18123 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 18124 uint32_t vdev_id) 18125 { 18126 wmi_buf_t buf; 18127 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 18128 uint16_t len = sizeof(*cmd); 18129 int ret; 18130 18131 buf = wmi_buf_alloc(wmi_handle, len); 18132 if (!buf) { 18133 wmi_err("Failed to allocate wmi buffer"); 18134 return QDF_STATUS_E_NOMEM; 18135 } 18136 18137 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 18138 wmi_buf_data(buf); 18139 WMITLV_SET_HDR(&cmd->tlv_header, 18140 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 18141 WMITLV_GET_STRUCT_TLVLEN( 18142 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 18143 cmd->vdev_id = vdev_id; 18144 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 18145 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18146 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 18147 if (QDF_IS_STATUS_ERROR(ret)) { 18148 wmi_err("Failed to send get roam scan channels request = %d", 18149 ret); 18150 wmi_buf_free(buf); 18151 } 18152 return ret; 18153 } 18154 18155 /** 18156 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 18157 * @wmi_handle: wmi handle 18158 * @evt_buf: pointer to event buffer 18159 * @vdev_id: output pointer to hold vdev id 18160 * @res_param: output pointer to hold the allocated response 18161 * 18162 * Return: QDF_STATUS 18163 */ 18164 static QDF_STATUS 18165 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18166 uint32_t *vdev_id, 18167 struct wmi_roam_scan_stats_res **res_param) 18168 { 18169 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 18170 wmi_roam_scan_stats_event_fixed_param *fixed_param; 18171 uint32_t *client_id = NULL; 18172 wmi_roaming_timestamp *timestamp = NULL; 18173 uint32_t *num_channels = NULL; 18174 uint32_t *chan_info = NULL; 18175 wmi_mac_addr *old_bssid = NULL; 18176 uint32_t *is_roaming_success = NULL; 18177 wmi_mac_addr *new_bssid = NULL; 18178 uint32_t *num_roam_candidates = NULL; 18179 wmi_roam_scan_trigger_reason *roam_reason = NULL; 18180 wmi_mac_addr *bssid = NULL; 18181 uint32_t *score = NULL; 18182 uint32_t *channel = NULL; 18183 uint32_t *rssi = NULL; 18184 int chan_idx = 0, cand_idx = 0; 18185 uint32_t total_len; 18186 struct wmi_roam_scan_stats_res *res; 18187 uint32_t i, j; 18188 uint32_t num_scans, scan_param_size; 18189 18190 *res_param = NULL; 18191 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 18192 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 18193 if (!param_buf) { 18194 wmi_err("Invalid roam scan stats event"); 18195 return QDF_STATUS_E_INVAL; 18196 } 18197 18198 fixed_param = param_buf->fixed_param; 18199 18200 num_scans = fixed_param->num_roam_scans; 18201 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 18202 *vdev_id = fixed_param->vdev_id; 18203 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 18204 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 18205 num_scans, WMI_ROAM_SCAN_STATS_MAX); 18206 return QDF_STATUS_E_INVAL; 18207 } 18208 18209 total_len = sizeof(*res) + num_scans * scan_param_size; 18210 18211 res = qdf_mem_malloc(total_len); 18212 if (!res) 18213 return QDF_STATUS_E_NOMEM; 18214 18215 if (!num_scans) { 18216 *res_param = res; 18217 return QDF_STATUS_SUCCESS; 18218 } 18219 18220 if (param_buf->client_id && 18221 param_buf->num_client_id == num_scans) 18222 client_id = param_buf->client_id; 18223 18224 if (param_buf->timestamp && 18225 param_buf->num_timestamp == num_scans) 18226 timestamp = param_buf->timestamp; 18227 18228 if (param_buf->old_bssid && 18229 param_buf->num_old_bssid == num_scans) 18230 old_bssid = param_buf->old_bssid; 18231 18232 if (param_buf->new_bssid && 18233 param_buf->num_new_bssid == num_scans) 18234 new_bssid = param_buf->new_bssid; 18235 18236 if (param_buf->is_roaming_success && 18237 param_buf->num_is_roaming_success == num_scans) 18238 is_roaming_success = param_buf->is_roaming_success; 18239 18240 if (param_buf->roam_reason && 18241 param_buf->num_roam_reason == num_scans) 18242 roam_reason = param_buf->roam_reason; 18243 18244 if (param_buf->num_channels && 18245 param_buf->num_num_channels == num_scans) { 18246 uint32_t count, chan_info_sum = 0; 18247 18248 num_channels = param_buf->num_channels; 18249 for (count = 0; count < param_buf->num_num_channels; count++) { 18250 if (param_buf->num_channels[count] > 18251 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 18252 wmi_err_rl("%u exceeded max scan channels %u", 18253 param_buf->num_channels[count], 18254 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 18255 goto error; 18256 } 18257 chan_info_sum += param_buf->num_channels[count]; 18258 } 18259 18260 if (param_buf->chan_info && 18261 param_buf->num_chan_info == chan_info_sum) 18262 chan_info = param_buf->chan_info; 18263 } 18264 18265 if (param_buf->num_roam_candidates && 18266 param_buf->num_num_roam_candidates == num_scans) { 18267 uint32_t cnt, roam_cand_sum = 0; 18268 18269 num_roam_candidates = param_buf->num_roam_candidates; 18270 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 18271 if (param_buf->num_roam_candidates[cnt] > 18272 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 18273 wmi_err_rl("%u exceeded max scan cand %u", 18274 param_buf->num_roam_candidates[cnt], 18275 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 18276 goto error; 18277 } 18278 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 18279 } 18280 18281 if (param_buf->bssid && 18282 param_buf->num_bssid == roam_cand_sum) 18283 bssid = param_buf->bssid; 18284 18285 if (param_buf->score && 18286 param_buf->num_score == roam_cand_sum) 18287 score = param_buf->score; 18288 18289 if (param_buf->channel && 18290 param_buf->num_channel == roam_cand_sum) 18291 channel = param_buf->channel; 18292 18293 if (param_buf->rssi && 18294 param_buf->num_rssi == roam_cand_sum) 18295 rssi = param_buf->rssi; 18296 } 18297 18298 res->num_roam_scans = num_scans; 18299 for (i = 0; i < num_scans; i++) { 18300 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 18301 18302 if (timestamp) 18303 roam->time_stamp = timestamp[i].lower32bit | 18304 (timestamp[i].upper32bit << 31); 18305 18306 if (client_id) 18307 roam->client_id = client_id[i]; 18308 18309 if (num_channels) { 18310 roam->num_scan_chans = num_channels[i]; 18311 if (chan_info) { 18312 for (j = 0; j < num_channels[i]; j++) 18313 roam->scan_freqs[j] = 18314 chan_info[chan_idx++]; 18315 } 18316 } 18317 18318 if (is_roaming_success) 18319 roam->is_roam_successful = is_roaming_success[i]; 18320 18321 if (roam_reason) { 18322 roam->trigger_id = roam_reason[i].trigger_id; 18323 roam->trigger_value = roam_reason[i].trigger_value; 18324 } 18325 18326 if (num_roam_candidates) { 18327 roam->num_roam_candidates = num_roam_candidates[i]; 18328 18329 for (j = 0; j < num_roam_candidates[i]; j++) { 18330 if (score) 18331 roam->cand[j].score = score[cand_idx]; 18332 if (rssi) 18333 roam->cand[j].rssi = rssi[cand_idx]; 18334 if (channel) 18335 roam->cand[j].freq = 18336 channel[cand_idx]; 18337 18338 if (bssid) 18339 WMI_MAC_ADDR_TO_CHAR_ARRAY( 18340 &bssid[cand_idx], 18341 roam->cand[j].bssid); 18342 18343 cand_idx++; 18344 } 18345 } 18346 18347 if (old_bssid) 18348 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 18349 roam->old_bssid); 18350 18351 if (new_bssid) 18352 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 18353 roam->new_bssid); 18354 } 18355 18356 *res_param = res; 18357 18358 return QDF_STATUS_SUCCESS; 18359 error: 18360 qdf_mem_free(res); 18361 return QDF_STATUS_E_FAILURE; 18362 } 18363 18364 /** 18365 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 18366 * @wmi_handle: wmi handle 18367 * @evt_buf: pointer to event buffer 18368 * @vdev_id: output pointer to hold vdev id 18369 * @tx_status: output pointer to hold the tx_status 18370 * 18371 * Return: QDF_STATUS 18372 */ 18373 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 18374 void *evt_buf, 18375 uint32_t *vdev_id, 18376 uint32_t *tx_status) { 18377 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 18378 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 18379 18380 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 18381 if (!param_buf) { 18382 wmi_err("Invalid offload bcn tx status event buffer"); 18383 return QDF_STATUS_E_INVAL; 18384 } 18385 18386 bcn_tx_status_event = param_buf->fixed_param; 18387 *vdev_id = bcn_tx_status_event->vdev_id; 18388 *tx_status = bcn_tx_status_event->tx_status; 18389 18390 return QDF_STATUS_SUCCESS; 18391 } 18392 18393 #ifdef WLAN_SUPPORT_GREEN_AP 18394 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 18395 uint8_t *evt_buf, 18396 struct wlan_green_ap_egap_status_info *egap_status_info_params) 18397 { 18398 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 18399 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 18400 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 18401 18402 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 18403 if (!param_buf) { 18404 wmi_err("Invalid EGAP Info status event buffer"); 18405 return QDF_STATUS_E_INVAL; 18406 } 18407 18408 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 18409 param_buf->fixed_param; 18410 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 18411 param_buf->chainmask_list; 18412 18413 if (!egap_info_event || !chainmask_event) { 18414 wmi_err("Invalid EGAP Info event or chainmask event"); 18415 return QDF_STATUS_E_INVAL; 18416 } 18417 18418 egap_status_info_params->status = egap_info_event->status; 18419 egap_status_info_params->mac_id = chainmask_event->mac_id; 18420 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 18421 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 18422 18423 return QDF_STATUS_SUCCESS; 18424 } 18425 #endif 18426 18427 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 18428 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 18429 uint8_t *evt_buf, 18430 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 18431 { 18432 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 18433 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 18434 18435 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 18436 if (!param_buf) { 18437 wmi_err("Invalid XGAP SAP info status"); 18438 return QDF_STATUS_E_INVAL; 18439 } 18440 18441 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 18442 param_buf->fixed_param; 18443 if (!ll_ps_event) { 18444 wmi_err("Invalid low latency power save event buffer"); 18445 return QDF_STATUS_E_INVAL; 18446 } 18447 18448 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 18449 ll_ps_params->next_tsf = 18450 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 18451 ll_ps_event->next_tsf_low32; 18452 18453 wmi_debug("cookie : %u next_tsf %llu", ll_ps_params->dialog_token, 18454 ll_ps_params->next_tsf); 18455 18456 return QDF_STATUS_SUCCESS; 18457 } 18458 #endif 18459 18460 /* 18461 * extract_comb_phyerr_tlv() - extract comb phy error from event 18462 * @wmi_handle: wmi handle 18463 * @evt_buf: pointer to event buffer 18464 * @datalen: data length of event buffer 18465 * @buf_offset: Pointer to hold value of current event buffer offset 18466 * post extraction 18467 * @phyerr: Pointer to hold phyerr 18468 * 18469 * Return: QDF_STATUS 18470 */ 18471 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 18472 void *evt_buf, 18473 uint16_t datalen, 18474 uint16_t *buf_offset, 18475 wmi_host_phyerr_t *phyerr) 18476 { 18477 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 18478 wmi_comb_phyerr_rx_hdr *pe_hdr; 18479 18480 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 18481 if (!param_tlvs) { 18482 wmi_debug("Received null data from FW"); 18483 return QDF_STATUS_E_FAILURE; 18484 } 18485 18486 pe_hdr = param_tlvs->hdr; 18487 if (!pe_hdr) { 18488 wmi_debug("Received Data PE Header is NULL"); 18489 return QDF_STATUS_E_FAILURE; 18490 } 18491 18492 /* Ensure it's at least the size of the header */ 18493 if (datalen < sizeof(*pe_hdr)) { 18494 wmi_debug("Expected minimum size %zu, received %d", 18495 sizeof(*pe_hdr), datalen); 18496 return QDF_STATUS_E_FAILURE; 18497 } 18498 18499 phyerr->pdev_id = wmi_handle->ops-> 18500 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 18501 phyerr->tsf64 = pe_hdr->tsf_l32; 18502 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 18503 phyerr->bufp = param_tlvs->bufp; 18504 18505 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 18506 wmi_debug("Invalid buf_len %d, num_bufp %d", 18507 pe_hdr->buf_len, param_tlvs->num_bufp); 18508 return QDF_STATUS_E_FAILURE; 18509 } 18510 18511 phyerr->buf_len = pe_hdr->buf_len; 18512 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 18513 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 18514 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 18515 18516 return QDF_STATUS_SUCCESS; 18517 } 18518 18519 /** 18520 * extract_single_phyerr_tlv() - extract single phy error from event 18521 * @wmi_handle: wmi handle 18522 * @evt_buf: pointer to event buffer 18523 * @datalen: data length of event buffer 18524 * @buf_offset: Pointer to hold value of current event buffer offset 18525 * post extraction 18526 * @phyerr: Pointer to hold phyerr 18527 * 18528 * Return: QDF_STATUS 18529 */ 18530 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 18531 void *evt_buf, 18532 uint16_t datalen, 18533 uint16_t *buf_offset, 18534 wmi_host_phyerr_t *phyerr) 18535 { 18536 wmi_single_phyerr_rx_event *ev; 18537 uint16_t n = *buf_offset; 18538 uint8_t *data = (uint8_t *)evt_buf; 18539 18540 if (n < datalen) { 18541 if ((datalen - n) < sizeof(ev->hdr)) { 18542 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 18543 datalen, n, sizeof(ev->hdr)); 18544 return QDF_STATUS_E_FAILURE; 18545 } 18546 18547 /* 18548 * Obtain a pointer to the beginning of the current event. 18549 * data[0] is the beginning of the WMI payload. 18550 */ 18551 ev = (wmi_single_phyerr_rx_event *)&data[n]; 18552 18553 /* 18554 * Sanity check the buffer length of the event against 18555 * what we currently have. 18556 * 18557 * Since buf_len is 32 bits, we check if it overflows 18558 * a large 32 bit value. It's not 0x7fffffff because 18559 * we increase n by (buf_len + sizeof(hdr)), which would 18560 * in itself cause n to overflow. 18561 * 18562 * If "int" is 64 bits then this becomes a moot point. 18563 */ 18564 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 18565 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 18566 return QDF_STATUS_E_FAILURE; 18567 } 18568 18569 if ((n + ev->hdr.buf_len) > datalen) { 18570 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 18571 n, ev->hdr.buf_len, datalen); 18572 return QDF_STATUS_E_FAILURE; 18573 } 18574 18575 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 18576 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 18577 phyerr->bufp = &ev->bufp[0]; 18578 phyerr->buf_len = ev->hdr.buf_len; 18579 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 18580 18581 /* 18582 * Advance the buffer pointer to the next PHY error. 18583 * buflen is the length of this payload, so we need to 18584 * advance past the current header _AND_ the payload. 18585 */ 18586 n += sizeof(*ev) + ev->hdr.buf_len; 18587 } 18588 *buf_offset = n; 18589 18590 return QDF_STATUS_SUCCESS; 18591 } 18592 18593 /** 18594 * extract_esp_estimation_ev_param_tlv() - extract air time from event 18595 * @wmi_handle: wmi handle 18596 * @evt_buf: pointer to event buffer 18597 * @param: Pointer to hold esp event 18598 * 18599 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 18600 */ 18601 static QDF_STATUS 18602 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 18603 void *evt_buf, 18604 struct esp_estimation_event *param) 18605 { 18606 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 18607 wmi_esp_estimate_event_fixed_param *esp_event; 18608 18609 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 18610 if (!param_buf) { 18611 wmi_err("Invalid ESP Estimate Event buffer"); 18612 return QDF_STATUS_E_INVAL; 18613 } 18614 esp_event = param_buf->fixed_param; 18615 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 18616 18617 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 18618 wmi_handle, 18619 esp_event->pdev_id); 18620 18621 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 18622 return QDF_STATUS_E_FAILURE; 18623 18624 return QDF_STATUS_SUCCESS; 18625 } 18626 18627 /* 18628 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 18629 * updating bss color change within firmware when AP announces bss color change. 18630 * @wmi_handle: wmi handle 18631 * @vdev_id: vdev ID 18632 * @enable: enable bss color change within firmware 18633 * 18634 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 18635 * 18636 * Return: QDF_STATUS 18637 */ 18638 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 18639 uint32_t vdev_id, 18640 bool enable) 18641 { 18642 wmi_buf_t buf; 18643 wmi_bss_color_change_enable_fixed_param *cmd; 18644 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 18645 18646 buf = wmi_buf_alloc(wmi_handle, len); 18647 if (!buf) 18648 return QDF_STATUS_E_NOMEM; 18649 18650 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 18651 WMITLV_SET_HDR(&cmd->tlv_header, 18652 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 18653 WMITLV_GET_STRUCT_TLVLEN 18654 (wmi_bss_color_change_enable_fixed_param)); 18655 cmd->vdev_id = vdev_id; 18656 cmd->enable = enable; 18657 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 18658 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18659 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 18660 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 18661 wmi_buf_free(buf); 18662 return QDF_STATUS_E_FAILURE; 18663 } 18664 18665 return QDF_STATUS_SUCCESS; 18666 } 18667 18668 /** 18669 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 18670 * configurations to firmware. 18671 * @wmi_handle: wmi handle 18672 * @cfg_param: obss detection configurations 18673 * 18674 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 18675 * 18676 * Return: QDF_STATUS 18677 */ 18678 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 18679 wmi_unified_t wmi_handle, 18680 struct wmi_obss_color_collision_cfg_param *cfg_param) 18681 { 18682 wmi_buf_t buf; 18683 wmi_obss_color_collision_det_config_fixed_param *cmd; 18684 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 18685 18686 buf = wmi_buf_alloc(wmi_handle, len); 18687 if (!buf) 18688 return QDF_STATUS_E_NOMEM; 18689 18690 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 18691 buf); 18692 WMITLV_SET_HDR(&cmd->tlv_header, 18693 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 18694 WMITLV_GET_STRUCT_TLVLEN 18695 (wmi_obss_color_collision_det_config_fixed_param)); 18696 cmd->vdev_id = cfg_param->vdev_id; 18697 cmd->flags = cfg_param->flags; 18698 cmd->current_bss_color = cfg_param->current_bss_color; 18699 cmd->detection_period_ms = cfg_param->detection_period_ms; 18700 cmd->scan_period_ms = cfg_param->scan_period_ms; 18701 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 18702 18703 switch (cfg_param->evt_type) { 18704 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 18705 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 18706 break; 18707 case OBSS_COLOR_COLLISION_DETECTION: 18708 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 18709 break; 18710 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18711 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18712 break; 18713 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 18714 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 18715 break; 18716 default: 18717 wmi_err("Invalid event type: %d", cfg_param->evt_type); 18718 wmi_buf_free(buf); 18719 return QDF_STATUS_E_FAILURE; 18720 } 18721 18722 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 18723 "detection_period_ms: %d scan_period_ms: %d " 18724 "free_slot_expiry_timer_ms: %d", 18725 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 18726 cmd->detection_period_ms, cmd->scan_period_ms, 18727 cmd->free_slot_expiry_time_ms); 18728 18729 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 18730 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18731 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 18732 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 18733 cfg_param->vdev_id); 18734 wmi_buf_free(buf); 18735 return QDF_STATUS_E_FAILURE; 18736 } 18737 18738 return QDF_STATUS_SUCCESS; 18739 } 18740 18741 /** 18742 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 18743 * received from firmware. 18744 * @evt_buf: pointer to event buffer 18745 * @info: Pointer to hold bss collision info 18746 * 18747 * Return: QDF_STATUS 18748 */ 18749 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 18750 struct wmi_obss_color_collision_info *info) 18751 { 18752 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 18753 wmi_obss_color_collision_evt_fixed_param *fix_param; 18754 18755 if (!info) { 18756 wmi_err("Invalid obss color buffer"); 18757 return QDF_STATUS_E_INVAL; 18758 } 18759 18760 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 18761 evt_buf; 18762 if (!param_buf) { 18763 wmi_err("Invalid evt_buf"); 18764 return QDF_STATUS_E_INVAL; 18765 } 18766 18767 fix_param = param_buf->fixed_param; 18768 info->vdev_id = fix_param->vdev_id; 18769 info->obss_color_bitmap_bit0to31 = 18770 fix_param->bss_color_bitmap_bit0to31; 18771 info->obss_color_bitmap_bit32to63 = 18772 fix_param->bss_color_bitmap_bit32to63; 18773 18774 switch (fix_param->evt_type) { 18775 case WMI_BSS_COLOR_COLLISION_DISABLE: 18776 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 18777 break; 18778 case WMI_BSS_COLOR_COLLISION_DETECTION: 18779 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 18780 break; 18781 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18782 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18783 break; 18784 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 18785 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 18786 break; 18787 default: 18788 wmi_err("Invalid event type: %d, vdev_id: %d", 18789 fix_param->evt_type, fix_param->vdev_id); 18790 return QDF_STATUS_E_FAILURE; 18791 } 18792 18793 return QDF_STATUS_SUCCESS; 18794 } 18795 18796 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 18797 { 18798 struct wmi_ops *ops = wmi_handle->ops; 18799 18800 ops->send_obss_color_collision_cfg_cmd = 18801 send_obss_color_collision_cfg_cmd_tlv; 18802 ops->extract_obss_color_collision_info = 18803 extract_obss_color_collision_info_tlv; 18804 } 18805 18806 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18807 static QDF_STATUS 18808 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 18809 struct config_fils_params *param) 18810 { 18811 wmi_buf_t buf; 18812 wmi_enable_fils_cmd_fixed_param *cmd; 18813 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 18814 18815 buf = wmi_buf_alloc(wmi_handle, len); 18816 if (!buf) 18817 return QDF_STATUS_E_NOMEM; 18818 18819 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 18820 buf); 18821 WMITLV_SET_HDR(&cmd->tlv_header, 18822 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 18823 WMITLV_GET_STRUCT_TLVLEN 18824 (wmi_enable_fils_cmd_fixed_param)); 18825 cmd->vdev_id = param->vdev_id; 18826 cmd->fd_period = param->fd_period; 18827 if (param->send_prb_rsp_frame) 18828 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 18829 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 18830 cmd->vdev_id, cmd->fd_period, cmd->flags); 18831 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 18832 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18833 WMI_ENABLE_FILS_CMDID)) { 18834 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 18835 wmi_buf_free(buf); 18836 return QDF_STATUS_E_FAILURE; 18837 } 18838 18839 return QDF_STATUS_SUCCESS; 18840 } 18841 #endif 18842 18843 #ifdef WLAN_MWS_INFO_DEBUGFS 18844 /** 18845 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 18846 * 18847 * @wmi_handle: wmi handle 18848 * @vdev_id: vdev id 18849 * @cmd_id: Coex command id 18850 * 18851 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 18852 * 18853 * Return: QDF_STATUS 18854 */ 18855 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 18856 uint32_t vdev_id, 18857 uint32_t cmd_id) 18858 { 18859 wmi_buf_t buf; 18860 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 18861 uint16_t len = sizeof(*cmd); 18862 int ret; 18863 18864 buf = wmi_buf_alloc(wmi_handle, len); 18865 if (!buf) { 18866 wmi_err("Failed to allocate wmi buffer"); 18867 return QDF_STATUS_E_NOMEM; 18868 } 18869 18870 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 18871 WMITLV_SET_HDR(&cmd->tlv_header, 18872 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 18873 WMITLV_GET_STRUCT_TLVLEN 18874 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 18875 cmd->vdev_id = vdev_id; 18876 cmd->cmd_id = cmd_id; 18877 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 18878 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18879 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 18880 if (QDF_IS_STATUS_ERROR(ret)) { 18881 wmi_err("Failed to send set param command ret = %d", ret); 18882 wmi_buf_free(buf); 18883 } 18884 return ret; 18885 } 18886 #endif 18887 18888 #ifdef FEATURE_MEC_OFFLOAD 18889 static QDF_STATUS 18890 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 18891 struct set_mec_timer_params *param) 18892 { 18893 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 18894 wmi_buf_t buf; 18895 int32_t len = sizeof(*cmd); 18896 18897 buf = wmi_buf_alloc(wmi_handle, len); 18898 if (!buf) { 18899 wmi_err("wmi_buf_alloc failed"); 18900 return QDF_STATUS_E_FAILURE; 18901 } 18902 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 18903 wmi_buf_data(buf); 18904 WMITLV_SET_HDR(&cmd->tlv_header, 18905 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 18906 WMITLV_GET_STRUCT_TLVLEN( 18907 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 18908 cmd->pdev_id = param->pdev_id; 18909 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 18910 18911 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 18912 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18913 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 18914 wmi_err("Failed to set mec aging timer param"); 18915 wmi_buf_free(buf); 18916 return QDF_STATUS_E_FAILURE; 18917 } 18918 18919 return QDF_STATUS_SUCCESS; 18920 } 18921 #endif 18922 18923 #ifdef WIFI_POS_CONVERGED 18924 /** 18925 * extract_oem_response_param_tlv() - Extract oem response params 18926 * @wmi_handle: wmi handle 18927 * @resp_buf: response buffer 18928 * @oem_resp_param: pointer to hold oem response params 18929 * 18930 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18931 */ 18932 static QDF_STATUS 18933 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 18934 struct wmi_oem_response_param *oem_resp_param) 18935 { 18936 uint64_t temp_addr; 18937 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 18938 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 18939 18940 if (!param_buf) { 18941 wmi_err("Invalid OEM response"); 18942 return QDF_STATUS_E_INVAL; 18943 } 18944 18945 if (param_buf->num_data) { 18946 oem_resp_param->num_data1 = param_buf->num_data; 18947 oem_resp_param->data_1 = param_buf->data; 18948 } 18949 18950 if (param_buf->num_data2) { 18951 oem_resp_param->num_data2 = param_buf->num_data2; 18952 oem_resp_param->data_2 = param_buf->data2; 18953 } 18954 18955 if (param_buf->indirect_data) { 18956 oem_resp_param->indirect_data.pdev_id = 18957 param_buf->indirect_data->pdev_id; 18958 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 18959 oem_resp_param->indirect_data.addr = 18960 param_buf->indirect_data->addr_lo + 18961 ((uint64_t)temp_addr << 32); 18962 oem_resp_param->indirect_data.len = 18963 param_buf->indirect_data->len; 18964 } 18965 18966 return QDF_STATUS_SUCCESS; 18967 } 18968 #endif /* WIFI_POS_CONVERGED */ 18969 18970 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18971 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18972 18973 static QDF_STATUS 18974 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18975 struct wifi_pos_pasn_peer_data *dst) 18976 { 18977 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18978 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18979 wmi_rtt_pasn_peer_create_req_param *buf; 18980 uint8_t security_mode, i; 18981 18982 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18983 if (!param_buf) { 18984 wmi_err("Invalid peer_create req buffer"); 18985 return QDF_STATUS_E_INVAL; 18986 } 18987 18988 fixed_param = param_buf->fixed_param; 18989 18990 if (param_buf->num_rtt_pasn_peer_param > 18991 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18992 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18993 wmi_err("Invalid TLV size"); 18994 return QDF_STATUS_E_INVAL; 18995 } 18996 18997 if (!param_buf->num_rtt_pasn_peer_param || 18998 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 18999 wmi_err("Invalid num TLV:%d", 19000 param_buf->num_rtt_pasn_peer_param); 19001 return QDF_STATUS_E_INVAL; 19002 } 19003 19004 dst->vdev_id = fixed_param->vdev_id; 19005 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 19006 wmi_err("Invalid vdev id:%d", dst->vdev_id); 19007 return QDF_STATUS_E_INVAL; 19008 } 19009 19010 buf = param_buf->rtt_pasn_peer_param; 19011 if (!buf) { 19012 wmi_err("NULL peer param TLV"); 19013 return QDF_STATUS_E_INVAL; 19014 } 19015 19016 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 19017 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 19018 dst->peer_info[i].self_mac.bytes); 19019 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 19020 dst->peer_info[i].peer_mac.bytes); 19021 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 19022 buf->control_flag); 19023 if (security_mode) 19024 dst->peer_info[i].peer_type = 19025 WLAN_WIFI_POS_PASN_SECURE_PEER; 19026 else 19027 dst->peer_info[i].peer_type = 19028 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 19029 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 19030 dst->peer_info[i].is_ltf_keyseed_required = true; 19031 19032 dst->peer_info[i].force_self_mac_usage = 19033 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 19034 buf->control_flag); 19035 dst->num_peers++; 19036 buf++; 19037 } 19038 19039 return QDF_STATUS_SUCCESS; 19040 } 19041 19042 static QDF_STATUS 19043 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19044 struct wifi_pos_pasn_peer_data *dst) 19045 { 19046 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 19047 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 19048 wmi_rtt_pasn_peer_delete_param *buf; 19049 uint8_t i; 19050 19051 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 19052 if (!param_buf) { 19053 wmi_err("Invalid peer_delete evt buffer"); 19054 return QDF_STATUS_E_INVAL; 19055 } 19056 19057 fixed_param = param_buf->fixed_param; 19058 19059 if (param_buf->num_rtt_pasn_peer_param > 19060 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 19061 sizeof(wmi_rtt_pasn_peer_delete_param))) { 19062 wmi_err("Invalid TLV size"); 19063 return QDF_STATUS_E_INVAL; 19064 } 19065 19066 if (!param_buf->num_rtt_pasn_peer_param || 19067 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 19068 wmi_err("Invalid num TLV:%d", 19069 param_buf->num_rtt_pasn_peer_param); 19070 return QDF_STATUS_E_INVAL; 19071 } 19072 19073 dst->vdev_id = fixed_param->vdev_id; 19074 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 19075 wmi_err("Invalid vdev id:%d", dst->vdev_id); 19076 return QDF_STATUS_E_INVAL; 19077 } 19078 19079 buf = param_buf->rtt_pasn_peer_param; 19080 if (!buf) { 19081 wmi_err("NULL peer param TLV"); 19082 return QDF_STATUS_E_INVAL; 19083 } 19084 19085 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 19086 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 19087 dst->peer_info[i].peer_mac.bytes); 19088 dst->peer_info[i].control_flags = buf->control_flag; 19089 19090 dst->num_peers++; 19091 buf++; 19092 } 19093 19094 return QDF_STATUS_SUCCESS; 19095 } 19096 19097 static QDF_STATUS 19098 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 19099 struct wlan_pasn_auth_status *data) 19100 { 19101 QDF_STATUS status; 19102 wmi_buf_t buf; 19103 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 19104 uint8_t *buf_ptr; 19105 uint8_t i; 19106 size_t len = sizeof(*fixed_param) + 19107 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 19108 WMI_TLV_HDR_SIZE; 19109 19110 buf = wmi_buf_alloc(wmi_handle, len); 19111 if (!buf) { 19112 wmi_err("wmi_buf_alloc failed"); 19113 return QDF_STATUS_E_FAILURE; 19114 } 19115 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19116 fixed_param = 19117 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 19118 WMITLV_SET_HDR(&fixed_param->tlv_header, 19119 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 19120 WMITLV_GET_STRUCT_TLVLEN( 19121 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 19122 buf_ptr += sizeof(*fixed_param); 19123 19124 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19125 (data->num_peers * 19126 sizeof(wmi_rtt_pasn_auth_status_param))); 19127 buf_ptr += WMI_TLV_HDR_SIZE; 19128 19129 for (i = 0; i < data->num_peers; i++) { 19130 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 19131 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 19132 19133 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 19134 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 19135 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 19136 19137 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 19138 &auth_status_tlv->peer_mac_addr); 19139 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 19140 &auth_status_tlv->source_mac_addr); 19141 auth_status_tlv->status = data->auth_status[i].status; 19142 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 19143 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 19144 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 19145 auth_status_tlv->status); 19146 19147 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 19148 } 19149 19150 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 19151 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19152 WMI_RTT_PASN_AUTH_STATUS_CMD); 19153 if (QDF_IS_STATUS_ERROR(status)) { 19154 wmi_err("Failed to send Auth status command ret = %d", status); 19155 wmi_buf_free(buf); 19156 } 19157 19158 return status; 19159 } 19160 19161 static QDF_STATUS 19162 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 19163 struct qdf_mac_addr *peer_mac) 19164 { 19165 QDF_STATUS status; 19166 wmi_buf_t buf; 19167 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 19168 size_t len = sizeof(*fixed_param); 19169 19170 buf = wmi_buf_alloc(wmi_handle, len); 19171 if (!buf) { 19172 wmi_err("wmi_buf_alloc failed"); 19173 return QDF_STATUS_E_FAILURE; 19174 } 19175 fixed_param = 19176 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 19177 WMITLV_SET_HDR(&fixed_param->tlv_header, 19178 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 19179 WMITLV_GET_STRUCT_TLVLEN( 19180 wmi_rtt_pasn_deauth_cmd_fixed_param)); 19181 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 19182 &fixed_param->peer_mac_addr); 19183 19184 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 19185 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19186 WMI_RTT_PASN_DEAUTH_CMD); 19187 if (QDF_IS_STATUS_ERROR(status)) { 19188 wmi_err("Failed to send pasn deauth command ret = %d", status); 19189 wmi_buf_free(buf); 19190 } 19191 19192 return status; 19193 } 19194 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 19195 19196 static QDF_STATUS 19197 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 19198 struct wlan_crypto_ltf_keyseed_data *data) 19199 { 19200 QDF_STATUS status; 19201 wmi_buf_t buf; 19202 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 19203 uint8_t *buf_ptr; 19204 size_t len = sizeof(*fixed_param) + data->key_seed_len + 19205 WMI_TLV_HDR_SIZE; 19206 19207 buf = wmi_buf_alloc(wmi_handle, len); 19208 if (!buf) { 19209 wmi_err("wmi_buf_alloc failed"); 19210 return QDF_STATUS_E_FAILURE; 19211 } 19212 19213 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19214 fixed_param = 19215 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 19216 WMITLV_SET_HDR(&fixed_param->tlv_header, 19217 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 19218 WMITLV_GET_STRUCT_TLVLEN( 19219 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 19220 19221 fixed_param->vdev_id = data->vdev_id; 19222 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 19223 &fixed_param->peer_macaddr); 19224 fixed_param->key_seed_len = data->key_seed_len; 19225 fixed_param->rsn_authmode = data->rsn_authmode; 19226 19227 buf_ptr += sizeof(*fixed_param); 19228 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 19229 (fixed_param->key_seed_len * sizeof(A_UINT8))); 19230 buf_ptr += WMI_TLV_HDR_SIZE; 19231 19232 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 19233 19234 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 19235 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19236 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 19237 if (QDF_IS_STATUS_ERROR(status)) { 19238 wmi_err("Failed to send ltf keyseed command ret = %d", status); 19239 wmi_buf_free(buf); 19240 } 19241 19242 return status; 19243 } 19244 19245 /** 19246 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 19247 * @wmi_handle: wmi handle 19248 * @evt_buf: pointer to event buffer 19249 * @cmd_status: status of HW mode change command 19250 * 19251 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19252 */ 19253 static QDF_STATUS 19254 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19255 uint32_t *cmd_status) 19256 { 19257 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 19258 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 19259 19260 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 19261 if (!param_buf) { 19262 wmi_err("Invalid mode change event buffer"); 19263 return QDF_STATUS_E_INVAL; 19264 } 19265 19266 fixed_param = param_buf->fixed_param; 19267 if (!fixed_param) { 19268 wmi_err("Invalid fixed param"); 19269 return QDF_STATUS_E_INVAL; 19270 } 19271 19272 *cmd_status = fixed_param->status; 19273 return QDF_STATUS_SUCCESS; 19274 } 19275 19276 /** 19277 * extract_rf_path_resp_tlv() - Extract RF path change status 19278 * @wmi_handle: wmi handle 19279 * @evt_buf: pointer to event buffer 19280 * @cmd_status: status of RF path change request 19281 * 19282 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19283 */ 19284 static QDF_STATUS 19285 extract_rf_path_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19286 uint32_t *cmd_status) 19287 { 19288 WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *param_buf; 19289 wmi_pdev_set_rf_path_event_fixed_param *fixed_param; 19290 19291 param_buf = (WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *)evt_buf; 19292 if (!param_buf) { 19293 wmi_err("Invalid RF path event buffer"); 19294 return QDF_STATUS_E_INVAL; 19295 } 19296 19297 fixed_param = param_buf->fixed_param; 19298 if (!fixed_param) { 19299 wmi_err("Invalid fixed param"); 19300 return QDF_STATUS_E_INVAL; 19301 } 19302 19303 *cmd_status = fixed_param->status; 19304 return QDF_STATUS_SUCCESS; 19305 } 19306 19307 #ifdef FEATURE_ANI_LEVEL_REQUEST 19308 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 19309 uint32_t *freqs, 19310 uint8_t num_freqs) 19311 { 19312 wmi_buf_t buf; 19313 wmi_get_channel_ani_cmd_fixed_param *cmd; 19314 QDF_STATUS ret; 19315 uint32_t len; 19316 A_UINT32 *chan_list; 19317 uint8_t i, *buf_ptr; 19318 19319 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 19320 WMI_TLV_HDR_SIZE + 19321 num_freqs * sizeof(A_UINT32); 19322 19323 buf = wmi_buf_alloc(wmi_handle, len); 19324 if (!buf) 19325 return QDF_STATUS_E_FAILURE; 19326 19327 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19328 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 19329 WMITLV_SET_HDR(&cmd->tlv_header, 19330 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 19331 WMITLV_GET_STRUCT_TLVLEN( 19332 wmi_get_channel_ani_cmd_fixed_param)); 19333 19334 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 19335 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 19336 (num_freqs * sizeof(A_UINT32))); 19337 19338 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 19339 for (i = 0; i < num_freqs; i++) { 19340 chan_list[i] = freqs[i]; 19341 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 19342 } 19343 19344 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19345 WMI_GET_CHANNEL_ANI_CMDID); 19346 19347 if (QDF_IS_STATUS_ERROR(ret)) { 19348 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 19349 wmi_buf_free(buf); 19350 } 19351 19352 return ret; 19353 } 19354 19355 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 19356 struct wmi_host_ani_level_event **info, 19357 uint32_t *num_freqs) 19358 { 19359 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 19360 wmi_get_channel_ani_event_fixed_param *fixed_param; 19361 wmi_channel_ani_info_tlv_param *tlv_params; 19362 uint8_t *buf_ptr, i; 19363 19364 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 19365 if (!param_buf) { 19366 wmi_err("Invalid ani level event buffer"); 19367 return QDF_STATUS_E_INVAL; 19368 } 19369 19370 fixed_param = 19371 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 19372 if (!fixed_param) { 19373 wmi_err("Invalid fixed param"); 19374 return QDF_STATUS_E_INVAL; 19375 } 19376 19377 buf_ptr = (uint8_t *)fixed_param; 19378 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 19379 buf_ptr += WMI_TLV_HDR_SIZE; 19380 19381 *num_freqs = param_buf->num_ani_info; 19382 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 19383 wmi_err("Invalid number of freqs received"); 19384 return QDF_STATUS_E_INVAL; 19385 } 19386 19387 *info = qdf_mem_malloc(*num_freqs * 19388 sizeof(struct wmi_host_ani_level_event)); 19389 if (!(*info)) 19390 return QDF_STATUS_E_NOMEM; 19391 19392 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 19393 for (i = 0; i < param_buf->num_ani_info; i++) { 19394 (*info)[i].ani_level = tlv_params->ani_level; 19395 (*info)[i].chan_freq = tlv_params->chan_freq; 19396 tlv_params++; 19397 } 19398 19399 return QDF_STATUS_SUCCESS; 19400 } 19401 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19402 19403 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19404 /** 19405 * convert_wtc_scan_mode() - Function to convert TLV specific 19406 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 19407 * @scan_mode: scan freq scheme coming from firmware 19408 * 19409 * Return: ROAM_TRIGGER_SCAN_MODE 19410 */ 19411 static enum roam_scan_freq_scheme 19412 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 19413 { 19414 switch (scan_mode) { 19415 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 19416 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 19417 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 19418 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 19419 case ROAM_TRIGGER_SCAN_MODE_FULL: 19420 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 19421 default: 19422 return ROAM_SCAN_FREQ_SCHEME_NONE; 19423 } 19424 } 19425 19426 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 19427 { 19428 switch (fw_trig_reason) { 19429 case WMI_ROAM_TRIGGER_REASON_NONE: 19430 return ROAM_TRIGGER_REASON_NONE; 19431 case WMI_ROAM_TRIGGER_REASON_PER: 19432 return ROAM_TRIGGER_REASON_PER; 19433 case WMI_ROAM_TRIGGER_REASON_BMISS: 19434 return ROAM_TRIGGER_REASON_BMISS; 19435 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19436 return ROAM_TRIGGER_REASON_LOW_RSSI; 19437 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19438 return ROAM_TRIGGER_REASON_HIGH_RSSI; 19439 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19440 return ROAM_TRIGGER_REASON_PERIODIC; 19441 case WMI_ROAM_TRIGGER_REASON_MAWC: 19442 return ROAM_TRIGGER_REASON_MAWC; 19443 case WMI_ROAM_TRIGGER_REASON_DENSE: 19444 return ROAM_TRIGGER_REASON_DENSE; 19445 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19446 return ROAM_TRIGGER_REASON_BACKGROUND; 19447 case WMI_ROAM_TRIGGER_REASON_FORCED: 19448 return ROAM_TRIGGER_REASON_FORCED; 19449 case WMI_ROAM_TRIGGER_REASON_BTM: 19450 return ROAM_TRIGGER_REASON_BTM; 19451 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19452 return ROAM_TRIGGER_REASON_UNIT_TEST; 19453 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19454 return ROAM_TRIGGER_REASON_BSS_LOAD; 19455 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19456 return ROAM_TRIGGER_REASON_DEAUTH; 19457 case WMI_ROAM_TRIGGER_REASON_IDLE: 19458 return ROAM_TRIGGER_REASON_IDLE; 19459 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19460 return ROAM_TRIGGER_REASON_STA_KICKOUT; 19461 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 19462 return ROAM_TRIGGER_REASON_ESS_RSSI; 19463 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19464 return ROAM_TRIGGER_REASON_WTC_BTM; 19465 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 19466 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 19467 case WMI_ROAM_TRIGGER_REASON_BTC: 19468 return ROAM_TRIGGER_REASON_BTC; 19469 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 19470 return ROAM_TRIGGER_REASON_MAX; 19471 default: 19472 return ROAM_TRIGGER_REASON_NONE; 19473 } 19474 } 19475 19476 /** 19477 * extract_roam_11kv_candidate_info - Extract btm candidate info 19478 * @wmi_handle: wmi_handle 19479 * @evt_buf: Event buffer 19480 * @dst_info: Destination buffer 19481 * @btm_idx: BTM index 19482 * @num_cand: Number of candidates 19483 * 19484 * Return: QDF_STATUS 19485 */ 19486 static QDF_STATUS 19487 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 19488 struct wmi_btm_req_candidate_info *dst_info, 19489 uint8_t btm_idx, uint16_t num_cand) 19490 { 19491 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19492 wmi_roam_btm_request_candidate_info *src_data; 19493 uint8_t i; 19494 19495 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19496 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 19497 !param_buf->num_roam_btm_request_candidate_info || 19498 (btm_idx + 19499 num_cand) > param_buf->num_roam_btm_request_candidate_info) 19500 return QDF_STATUS_SUCCESS; 19501 19502 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 19503 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 19504 num_cand = WLAN_MAX_BTM_CANDIDATE; 19505 for (i = 0; i < num_cand; i++) { 19506 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 19507 dst_info->candidate_bssid.bytes); 19508 dst_info->preference = src_data->preference; 19509 src_data++; 19510 dst_info++; 19511 } 19512 19513 return QDF_STATUS_SUCCESS; 19514 } 19515 19516 static enum roam_trigger_sub_reason 19517 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 19518 { 19519 switch (subreason) { 19520 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 19521 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 19522 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 19523 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 19524 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 19525 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 19526 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 19527 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 19528 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 19529 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 19530 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 19531 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 19532 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 19533 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 19534 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 19535 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 19536 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 19537 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 19538 default: 19539 break; 19540 } 19541 19542 return 0; 19543 } 19544 19545 /** 19546 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 19547 * @wmi_roam_fail_reason: roam fail enum 19548 * 19549 * Return: Roaming failure reason codes 19550 */ 19551 static enum wlan_roam_failure_reason_code 19552 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 19553 { 19554 switch (wmi_roam_fail_reason) { 19555 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 19556 return ROAM_FAIL_REASON_NO_SCAN_START; 19557 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 19558 return ROAM_FAIL_REASON_NO_AP_FOUND; 19559 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 19560 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 19561 case WMI_ROAM_FAIL_REASON_HOST: 19562 return ROAM_FAIL_REASON_HOST; 19563 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 19564 return ROAM_FAIL_REASON_AUTH_SEND; 19565 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 19566 return ROAM_FAIL_REASON_AUTH_RECV; 19567 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 19568 return ROAM_FAIL_REASON_NO_AUTH_RESP; 19569 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 19570 return ROAM_FAIL_REASON_REASSOC_SEND; 19571 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 19572 return ROAM_FAIL_REASON_REASSOC_RECV; 19573 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 19574 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 19575 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 19576 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 19577 case WMI_ROAM_FAIL_REASON_MLME: 19578 return ROAM_FAIL_REASON_MLME; 19579 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 19580 return ROAM_FAIL_REASON_INTERNAL_ABORT; 19581 case WMI_ROAM_FAIL_REASON_SCAN_START: 19582 return ROAM_FAIL_REASON_SCAN_START; 19583 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 19584 return ROAM_FAIL_REASON_AUTH_NO_ACK; 19585 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 19586 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 19587 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 19588 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 19589 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 19590 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 19591 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 19592 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 19593 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 19594 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 19595 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 19596 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 19597 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 19598 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 19599 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 19600 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 19601 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 19602 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 19603 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 19604 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 19605 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 19606 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 19607 case WMI_ROAM_FAIL_REASON_DISCONNECT: 19608 return ROAM_FAIL_REASON_DISCONNECT; 19609 case WMI_ROAM_FAIL_REASON_SYNC: 19610 return ROAM_FAIL_REASON_SYNC; 19611 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 19612 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 19613 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 19614 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 19615 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 19616 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 19617 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 19618 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 19619 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT: 19620 return ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT; 19621 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT: 19622 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT; 19623 case WMI_ROAM_FAIL_REASON_CURR_AP_STILL_OK: 19624 return ROAM_FAIL_REASON_CURR_AP_STILL_OK; 19625 case WMI_ROAM_FAIL_REASON_SCAN_CANCEL: 19626 return ROAM_FAIL_REASON_SCAN_CANCEL; 19627 default: 19628 return ROAM_FAIL_REASON_UNKNOWN; 19629 } 19630 } 19631 19632 /** 19633 * wmi_convert_to_cm_roam_invoke_reason() - Convert FW enum to Host enum 19634 * @reason: roam invoke reason from fw 19635 * 19636 * Return: Roam invoke reason code defined in host driver 19637 */ 19638 static enum roam_invoke_reason 19639 wmi_convert_to_cm_roam_invoke_reason(enum wlan_roam_invoke_reason reason) 19640 { 19641 switch (reason) { 19642 case ROAM_INVOKE_REASON_UNDEFINED: 19643 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19644 case ROAM_INVOKE_REASON_NUD_FAILURE: 19645 return WLAN_ROAM_STATS_INVOKE_REASON_NUD_FAILURE; 19646 case ROAM_INVOKE_REASON_USER_SPACE: 19647 return WLAN_ROAM_STATS_INVOKE_REASON_USER_SPACE; 19648 default: 19649 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19650 } 19651 } 19652 19653 /** 19654 * wmi_convert_to_cm_roam_tx_fail_reason() - Convert FW enum to Host enum 19655 * @tx_fail_reason: roam tx fail reason from fw 19656 * 19657 * Return: Roam tx fail reason code defined in host driver 19658 */ 19659 static enum roam_tx_failures_reason 19660 wmi_convert_to_cm_roam_tx_fail_reason(PEER_KICKOUT_REASON tx_fail_reason) 19661 { 19662 switch (tx_fail_reason) { 19663 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: 19664 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19665 case WMI_PEER_STA_KICKOUT_REASON_XRETRY: 19666 return WLAN_ROAM_STATS_KICKOUT_REASON_XRETRY; 19667 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: 19668 return WLAN_ROAM_STATS_KICKOUT_REASON_INACTIVITY; 19669 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: 19670 return WLAN_ROAM_STATS_KICKOUT_REASON_IBSS_DISCONNECT; 19671 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: 19672 return WLAN_ROAM_STATS_KICKOUT_REASON_TDLS_DISCONNECT; 19673 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT: 19674 return WLAN_ROAM_STATS_KICKOUT_REASON_SA_QUERY_TIMEOUT; 19675 case WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT: 19676 return WLAN_ROAM_STATS_KICKOUT_REASON_ROAMING_EVENT; 19677 default: 19678 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19679 } 19680 } 19681 19682 /** 19683 * wmi_convert_roam_abort_reason() - Convert FW enum to Host enum 19684 * @abort_reason: roam abort reason from fw 19685 * 19686 * Return: Roam abort reason code defined in host driver 19687 */ 19688 static enum roam_abort_reason 19689 wmi_convert_roam_abort_reason(WMI_ROAM_FAIL_SUB_REASON_ID abort_reason) 19690 { 19691 switch (abort_reason) { 19692 case WMI_ROAM_ABORT_UNSPECIFIED: 19693 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19694 case WMI_ROAM_ABORT_LOWRSSI_DATA_RSSI_HIGH: 19695 return WLAN_ROAM_STATS_ABORT_LOWRSSI_DATA_RSSI_HIGH; 19696 case WMI_ROAM_ABORT_LOWRSSI_LINK_SPEED_GOOD: 19697 return WLAN_ROAM_STATS_ABORT_LOWRSSI_LINK_SPEED_GOOD; 19698 case WMI_ROAM_ABORT_BG_DATA_RSSI_HIGH: 19699 return WLAN_ROAM_STATS_ABORT_BG_DATA_RSSI_HIGH; 19700 case WMI_ROAM_ABORT_BG_RSSI_ABOVE_THRESHOLD: 19701 return WLAN_ROAM_STATS_ABORT_BG_RSSI_ABOVE_THRESHOLD; 19702 default: 19703 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19704 } 19705 } 19706 19707 /** 19708 * wlan_roam_scan_type() - Convert FW enum to Host enum 19709 * @scan_type: roam scan type from fw 19710 * 19711 * Return: Roam scan type defined in host driver 19712 */ 19713 static enum roam_stats_scan_type 19714 wlan_roam_scan_type(uint32_t scan_type) 19715 { 19716 switch (scan_type) { 19717 case 0: 19718 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19719 case 1: 19720 return ROAM_STATS_SCAN_TYPE_FULL; 19721 case 2: 19722 return ROAM_STATS_SCAN_TYPE_NO_SCAN; 19723 case 3: 19724 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ; 19725 case 4: 19726 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ; 19727 default: 19728 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19729 } 19730 } 19731 19732 /** 19733 * wlan_roam_dwell_type() - Convert FW enum to Host enum 19734 * @dwell_type: roam channel scan dwell type from fw 19735 * 19736 * Return: Roam channel scan dwell type defined in host driver 19737 */ 19738 static enum roam_scan_dwell_type 19739 wlan_roam_dwell_type(uint32_t dwell_type) 19740 { 19741 switch (dwell_type) { 19742 case 0: 19743 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19744 case 1: 19745 return WLAN_ROAM_DWELL_ACTIVE_TYPE; 19746 case 2: 19747 return WLAN_ROAM_DWELL_PASSIVE_TYPE; 19748 default: 19749 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19750 } 19751 } 19752 19753 #define WLAN_ROAM_PER_TX_RATE_OFFSET 0 19754 #define WLAN_ROAM_PER_RX_RATE_OFFSET 16 19755 #define WLAN_ROAM_BMISS_FINNAL_OFFSET 0 19756 #define WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET 7 19757 #define WLAN_ROAM_BMISS_QOSNULL_OFFSET 24 19758 #define WLAN_ROAM_DENSE_ROAMABLE_OFFSET 0 19759 19760 /** 19761 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 19762 * from the WMI_ROAM_STATS_EVENTID 19763 * @wmi_handle: wmi handle 19764 * @evt_buf: Pointer to the event buffer 19765 * @trig: Pointer to destination structure to fill data 19766 * @idx: TLV id 19767 * @btm_idx: BTM index 19768 */ 19769 static QDF_STATUS 19770 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19771 struct wmi_roam_trigger_info *trig, uint8_t idx, 19772 uint8_t btm_idx) 19773 { 19774 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19775 wmi_roam_trigger_reason *src_data = NULL; 19776 uint32_t trig_reason = 0; 19777 uint32_t fail_reason = 0; 19778 uint32_t abort = 0; 19779 uint32_t invoke = 0; 19780 uint32_t tx_fail = 0; 19781 wmi_roam_trigger_reason_cmm *cmn_data = NULL; 19782 wmi_roam_trigger_per *per_data = NULL; 19783 wmi_roam_trigger_bmiss *bmiss_data = NULL; 19784 wmi_roam_trigger_hi_rssi *hi_rssi_data = NULL; 19785 wmi_roam_trigger_dense *dense_data = NULL; 19786 wmi_roam_trigger_force *force_data = NULL; 19787 wmi_roam_trigger_btm *btm_data = NULL; 19788 wmi_roam_trigger_bss_load *bss_load_data = NULL; 19789 wmi_roam_trigger_deauth *deauth_data = NULL; 19790 wmi_roam_trigger_periodic *periodic_data = NULL; 19791 wmi_roam_trigger_rssi *rssi_data = NULL; 19792 wmi_roam_trigger_kickout *kickout_data = NULL; 19793 wmi_roam_result *roam_result = NULL; 19794 wmi_roam_scan_info *scan_info = NULL; 19795 19796 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19797 if (!param_buf) { 19798 wmi_err("Param buf is NULL"); 19799 return QDF_STATUS_E_FAILURE; 19800 } 19801 19802 if (!param_buf->roam_result || idx >= param_buf->num_roam_result) 19803 wmi_err("roam_result or idx error.%u", idx); 19804 19805 if (!param_buf->roam_scan_info || idx >= param_buf->num_roam_scan_info) 19806 wmi_err("roam_scan_info or idx error.%u", idx); 19807 19808 trig->present = true; 19809 19810 if (param_buf->roam_scan_info) 19811 scan_info = ¶m_buf->roam_scan_info[idx]; 19812 19813 if (param_buf->roam_trigger_reason_cmm) 19814 cmn_data = ¶m_buf->roam_trigger_reason_cmm[idx]; 19815 19816 if (param_buf->roam_trigger_reason) 19817 src_data = ¶m_buf->roam_trigger_reason[idx]; 19818 19819 if (cmn_data) { 19820 trig_reason = cmn_data->trigger_reason; 19821 trig->trigger_reason = 19822 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19823 trig->trigger_sub_reason = 19824 wmi_convert_roam_sub_reason(cmn_data->trigger_sub_reason); 19825 trig->timestamp = cmn_data->timestamp; 19826 trig->common_roam = true; 19827 } else if (src_data) { 19828 trig_reason = src_data->trigger_reason; 19829 trig->trigger_reason = 19830 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19831 trig->trigger_sub_reason = 19832 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 19833 trig->current_rssi = src_data->current_rssi; 19834 trig->timestamp = src_data->timestamp; 19835 trig->common_roam = false; 19836 } 19837 19838 if (param_buf->roam_trigger_rssi) 19839 rssi_data = ¶m_buf->roam_trigger_rssi[idx]; 19840 19841 if (param_buf->roam_result) { 19842 roam_result = ¶m_buf->roam_result[idx]; 19843 19844 if (roam_result) { 19845 trig->roam_status = roam_result->roam_status; 19846 if (trig->roam_status) { 19847 fail_reason = roam_result->roam_fail_reason; 19848 trig->fail_reason = 19849 wlan_roam_fail_reason_code(fail_reason); 19850 19851 if (rssi_data) { 19852 abort = roam_result->roam_abort_reason; 19853 trig->abort_reason.abort_reason_code = 19854 wmi_convert_roam_abort_reason(abort); 19855 trig->abort_reason.data_rssi = 19856 rssi_data->data_rssi; 19857 trig->abort_reason.data_rssi_threshold = 19858 rssi_data->data_rssi_threshold; 19859 trig->abort_reason.rx_linkspeed_status = 19860 rssi_data->rx_linkspeed_status; 19861 } 19862 } 19863 } 19864 } 19865 19866 if (scan_info) 19867 trig->scan_type = 19868 wlan_roam_scan_type(scan_info->roam_scan_type); 19869 19870 switch (trig_reason) { 19871 case WMI_ROAM_TRIGGER_REASON_PER: 19872 if (param_buf->roam_trigger_per) 19873 per_data = ¶m_buf->roam_trigger_per[idx]; 19874 if (per_data) { 19875 trig->per_trig_data.tx_rate_thresh_percent = 19876 WMI_GET_BITS(per_data->rate_thresh_percnt, 19877 WLAN_ROAM_PER_RX_RATE_OFFSET, 8); 19878 trig->per_trig_data.rx_rate_thresh_percent = 19879 WMI_GET_BITS(per_data->rate_thresh_percnt, 19880 WLAN_ROAM_PER_TX_RATE_OFFSET, 8); 19881 } 19882 return QDF_STATUS_SUCCESS; 19883 19884 case WMI_ROAM_TRIGGER_REASON_BMISS: 19885 if (param_buf->roam_trigger_bmiss) 19886 bmiss_data = ¶m_buf->roam_trigger_bmiss[idx]; 19887 if (bmiss_data) { 19888 trig->bmiss_trig_data.final_bmiss_cnt = 19889 WMI_GET_BITS(bmiss_data->bmiss_status, 19890 WLAN_ROAM_BMISS_FINNAL_OFFSET, 7); 19891 trig->bmiss_trig_data.consecutive_bmiss_cnt = 19892 WMI_GET_BITS(bmiss_data->bmiss_status, 19893 WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET, 19894 17); 19895 trig->bmiss_trig_data.qos_null_success = 19896 WMI_GET_BITS(bmiss_data->bmiss_status, 19897 WLAN_ROAM_BMISS_QOSNULL_OFFSET, 1); 19898 } 19899 return QDF_STATUS_SUCCESS; 19900 19901 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19902 if (param_buf->roam_trigger_hi_rssi) 19903 hi_rssi_data = ¶m_buf->roam_trigger_hi_rssi[idx]; 19904 19905 if (hi_rssi_data && cmn_data) { 19906 trig->hi_rssi_trig_data.current_rssi = 19907 (uint8_t)cmn_data->current_rssi; 19908 trig->hi_rssi_trig_data.hirssi_threshold = 19909 (uint8_t)hi_rssi_data->hi_rssi_threshold; 19910 } 19911 return QDF_STATUS_SUCCESS; 19912 19913 case WMI_ROAM_TRIGGER_REASON_MAWC: 19914 case WMI_ROAM_TRIGGER_REASON_DENSE: 19915 if (param_buf->roam_trigger_dense) 19916 dense_data = ¶m_buf->roam_trigger_dense[idx]; 19917 if (dense_data) { 19918 trig->congestion_trig_data.rx_tput = 19919 dense_data->rx_tput; 19920 trig->congestion_trig_data.tx_tput = 19921 dense_data->tx_tput; 19922 trig->congestion_trig_data.roamable_count = 19923 WMI_GET_BITS(dense_data->dense_status, 19924 WLAN_ROAM_DENSE_ROAMABLE_OFFSET, 19925 8); 19926 } 19927 return QDF_STATUS_SUCCESS; 19928 19929 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19930 if (cmn_data && rssi_data) { 19931 trig->background_trig_data.current_rssi = 19932 (uint8_t)cmn_data->current_rssi; 19933 trig->background_trig_data.data_rssi = 19934 (uint8_t)rssi_data->data_rssi; 19935 trig->background_trig_data.data_rssi_threshold = 19936 (uint8_t)rssi_data->data_rssi_threshold; 19937 } 19938 return QDF_STATUS_SUCCESS; 19939 19940 case WMI_ROAM_TRIGGER_REASON_IDLE: 19941 case WMI_ROAM_TRIGGER_REASON_FORCED: 19942 if (param_buf->roam_trigger_force) 19943 force_data = ¶m_buf->roam_trigger_force[idx]; 19944 if (force_data) { 19945 invoke = force_data->invoke_reason; 19946 trig->user_trig_data.invoke_reason = 19947 wmi_convert_to_cm_roam_invoke_reason(invoke); 19948 } 19949 return QDF_STATUS_SUCCESS; 19950 19951 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19952 case WMI_ROAM_TRIGGER_REASON_BTC: 19953 return QDF_STATUS_SUCCESS; 19954 19955 case WMI_ROAM_TRIGGER_REASON_BTM: 19956 if (param_buf->roam_trigger_btm) 19957 btm_data = ¶m_buf->roam_trigger_btm[idx]; 19958 if (btm_data) { 19959 trig->btm_trig_data.btm_request_mode = 19960 btm_data->btm_request_mode; 19961 trig->btm_trig_data.disassoc_timer = 19962 btm_data->disassoc_imminent_timer; 19963 trig->btm_trig_data.validity_interval = 19964 btm_data->validity_internal; 19965 trig->btm_trig_data.candidate_list_count = 19966 btm_data->candidate_list_count; 19967 trig->btm_trig_data.btm_resp_status = 19968 btm_data->btm_response_status_code; 19969 trig->btm_trig_data.btm_bss_termination_timeout = 19970 btm_data->btm_bss_termination_timeout; 19971 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19972 btm_data->btm_mbo_assoc_retry_timeout; 19973 trig->btm_trig_data.token = 19974 (uint16_t)btm_data->btm_req_dialog_token; 19975 if (scan_info) { 19976 trig->btm_trig_data.band = 19977 WMI_GET_MLO_BAND(scan_info->flags); 19978 if (trig->btm_trig_data.band != 19979 WMI_MLO_BAND_NO_MLO) 19980 trig->btm_trig_data.is_mlo = true; 19981 } 19982 } else if (src_data) { 19983 trig->btm_trig_data.btm_request_mode = 19984 src_data->btm_request_mode; 19985 trig->btm_trig_data.disassoc_timer = 19986 src_data->disassoc_imminent_timer; 19987 trig->btm_trig_data.validity_interval = 19988 src_data->validity_internal; 19989 trig->btm_trig_data.candidate_list_count = 19990 src_data->candidate_list_count; 19991 trig->btm_trig_data.btm_resp_status = 19992 src_data->btm_response_status_code; 19993 trig->btm_trig_data.btm_bss_termination_timeout = 19994 src_data->btm_bss_termination_timeout; 19995 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19996 src_data->btm_mbo_assoc_retry_timeout; 19997 trig->btm_trig_data.token = 19998 src_data->btm_req_dialog_token; 19999 if (scan_info) { 20000 trig->btm_trig_data.band = 20001 WMI_GET_MLO_BAND(scan_info->flags); 20002 if (trig->btm_trig_data.band != 20003 WMI_MLO_BAND_NO_MLO) 20004 trig->btm_trig_data.is_mlo = true; 20005 } 20006 if ((btm_idx + 20007 trig->btm_trig_data.candidate_list_count) <= 20008 param_buf->num_roam_btm_request_candidate_info) 20009 extract_roam_11kv_candidate_info( 20010 wmi_handle, evt_buf, 20011 trig->btm_trig_data.btm_cand, 20012 btm_idx, 20013 src_data->candidate_list_count); 20014 } 20015 20016 return QDF_STATUS_SUCCESS; 20017 20018 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 20019 if (param_buf->roam_trigger_bss_load) 20020 bss_load_data = ¶m_buf->roam_trigger_bss_load[idx]; 20021 if (bss_load_data) 20022 trig->cu_trig_data.cu_load = bss_load_data->cu_load; 20023 else if (src_data) 20024 trig->cu_trig_data.cu_load = src_data->cu_load; 20025 return QDF_STATUS_SUCCESS; 20026 20027 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 20028 if (param_buf->roam_trigger_deauth) 20029 deauth_data = ¶m_buf->roam_trigger_deauth[idx]; 20030 if (deauth_data) { 20031 trig->deauth_trig_data.type = deauth_data->deauth_type; 20032 trig->deauth_trig_data.reason = 20033 deauth_data->deauth_reason; 20034 } else if (src_data) { 20035 trig->deauth_trig_data.type = src_data->deauth_type; 20036 trig->deauth_trig_data.reason = src_data->deauth_reason; 20037 } 20038 return QDF_STATUS_SUCCESS; 20039 20040 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 20041 if (param_buf->roam_trigger_periodic) 20042 periodic_data = ¶m_buf->roam_trigger_periodic[idx]; 20043 if (periodic_data) { 20044 trig->periodic_trig_data.periodic_timer_ms = 20045 periodic_data->periodic_timer_ms; 20046 } else if (src_data) 20047 trig->rssi_trig_data.threshold = 20048 src_data->roam_rssi_threshold; 20049 return QDF_STATUS_SUCCESS; 20050 20051 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 20052 if (cmn_data && rssi_data) { 20053 trig->low_rssi_trig_data.current_rssi = 20054 (uint8_t)cmn_data->current_rssi; 20055 trig->low_rssi_trig_data.roam_rssi_threshold = 20056 (uint8_t)rssi_data->roam_rssi_threshold; 20057 trig->low_rssi_trig_data.rx_linkspeed_status = 20058 (uint8_t)rssi_data->rx_linkspeed_status; 20059 } else if (src_data) 20060 trig->rssi_trig_data.threshold = 20061 src_data->roam_rssi_threshold; 20062 20063 return QDF_STATUS_SUCCESS; 20064 20065 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 20066 if (param_buf->roam_trigger_kickout) 20067 kickout_data = ¶m_buf->roam_trigger_kickout[idx]; 20068 if (kickout_data) { 20069 tx_fail = kickout_data->kickout_reason; 20070 trig->tx_failures_trig_data.kickout_threshold = 20071 kickout_data->kickout_th; 20072 trig->tx_failures_trig_data.kickout_reason = 20073 wmi_convert_to_cm_roam_tx_fail_reason(tx_fail); 20074 } 20075 return QDF_STATUS_SUCCESS; 20076 20077 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 20078 if (src_data) { 20079 trig->wtc_btm_trig_data.roaming_mode = 20080 src_data->vendor_specific1[0]; 20081 trig->wtc_btm_trig_data.vsie_trigger_reason = 20082 src_data->vendor_specific1[1]; 20083 trig->wtc_btm_trig_data.sub_code = 20084 src_data->vendor_specific1[2]; 20085 trig->wtc_btm_trig_data.wtc_mode = 20086 src_data->vendor_specific1[3]; 20087 trig->wtc_btm_trig_data.wtc_scan_mode = 20088 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 20089 trig->wtc_btm_trig_data.wtc_rssi_th = 20090 src_data->vendor_specific1[5]; 20091 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 20092 src_data->vendor_specific1[6]; 20093 20094 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 20095 src_data->vendor_specific2[0]; 20096 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 20097 src_data->vendor_specific2[1]; 20098 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 20099 src_data->vendor_specific2[2]; 20100 trig->wtc_btm_trig_data.duration = 20101 src_data->vendor_specific2[3]; 20102 } 20103 return QDF_STATUS_SUCCESS; 20104 default: 20105 return QDF_STATUS_SUCCESS; 20106 } 20107 20108 return QDF_STATUS_SUCCESS; 20109 } 20110 20111 /** 20112 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 20113 * from the WMI_ROAM_STATS_EVENTID 20114 * @wmi_handle: wmi handle 20115 * @evt_buf: Pointer to the event buffer 20116 * @dst: Pointer to destination structure to fill data 20117 * @ap_idx: TLV index for this roam scan 20118 * @num_cand: number of candidates list in the roam scan 20119 */ 20120 static QDF_STATUS 20121 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20122 struct wmi_roam_candidate_info *dst, 20123 uint8_t ap_idx, uint16_t num_cand) 20124 { 20125 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20126 wmi_roam_ap_info *src = NULL; 20127 uint8_t i; 20128 20129 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20130 if (!param_buf) { 20131 wmi_err("Param buf is NULL"); 20132 return QDF_STATUS_E_FAILURE; 20133 } 20134 20135 if (ap_idx >= param_buf->num_roam_ap_info) { 20136 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 20137 ap_idx, param_buf->num_roam_ap_info); 20138 return QDF_STATUS_E_FAILURE; 20139 } 20140 20141 src = ¶m_buf->roam_ap_info[ap_idx]; 20142 20143 for (i = 0; i < num_cand; i++) { 20144 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 20145 dst->type = src->candidate_type; 20146 dst->freq = src->channel; 20147 dst->etp = src->etp; 20148 dst->rssi = src->rssi; 20149 dst->rssi_score = src->rssi_score; 20150 dst->cu_load = src->cu_load; 20151 dst->cu_score = src->cu_score; 20152 dst->total_score = src->total_score; 20153 dst->timestamp = src->timestamp; 20154 dst->dl_reason = src->bl_reason; 20155 dst->dl_source = src->bl_source; 20156 dst->dl_timestamp = src->bl_timestamp; 20157 dst->dl_original_timeout = src->bl_original_timeout; 20158 dst->is_mlo = WMI_GET_AP_INFO_MLO_STATUS(src->flags); 20159 20160 src++; 20161 dst++; 20162 } 20163 20164 return QDF_STATUS_SUCCESS; 20165 } 20166 20167 #define ROAM_SUCCESS 0 20168 20169 /** 20170 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 20171 * from the WMI_ROAM_STATS_EVENTID 20172 * @wmi_handle: wmi handle 20173 * @evt_buf: Pointer to the event buffer 20174 * @dst: Pointer to destination structure to fill data 20175 * @idx: TLV id 20176 * @chan_idx: Index of the channel tlv for the current roam trigger 20177 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 20178 */ 20179 static QDF_STATUS 20180 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20181 struct wmi_roam_scan_data *dst, uint8_t idx, 20182 uint8_t chan_idx, uint8_t ap_idx) 20183 { 20184 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20185 wmi_roam_scan_info *src_data = NULL; 20186 wmi_roam_scan_channel_info *src_chan = NULL; 20187 QDF_STATUS status; 20188 uint8_t i; 20189 20190 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20191 if (!param_buf || !param_buf->roam_scan_info || 20192 idx >= param_buf->num_roam_scan_info) 20193 return QDF_STATUS_E_FAILURE; 20194 20195 src_data = ¶m_buf->roam_scan_info[idx]; 20196 20197 dst->present = true; 20198 dst->type = src_data->roam_scan_type; 20199 dst->num_chan = src_data->roam_scan_channel_count; 20200 dst->scan_complete_timestamp = src_data->scan_complete_timestamp; 20201 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 20202 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 20203 dst->frame_info_count = src_data->frame_info_count; 20204 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 20205 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 20206 20207 dst->band = WMI_GET_MLO_BAND(src_data->flags); 20208 if (dst->band != WMI_MLO_BAND_NO_MLO) 20209 dst->is_mlo = true; 20210 20211 /* Read the channel data only for dst->type is 0 (partial scan) */ 20212 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 20213 chan_idx < param_buf->num_roam_scan_chan_info) { 20214 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 20215 dst->num_chan = MAX_ROAM_SCAN_CHAN; 20216 20217 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 20218 20219 if ((dst->num_chan + chan_idx) > 20220 param_buf->num_roam_scan_chan_info) { 20221 wmi_err("Invalid TLV. num_chan %d chan_idx %d num_roam_scan_chan_info %d", 20222 dst->num_chan, chan_idx, 20223 param_buf->num_roam_scan_chan_info); 20224 return QDF_STATUS_SUCCESS; 20225 } 20226 20227 for (i = 0; i < dst->num_chan; i++) { 20228 dst->chan_freq[i] = src_chan->channel; 20229 dst->dwell_type[i] = 20230 (uint8_t)wlan_roam_dwell_type(src_chan->ch_dwell_type); 20231 src_chan++; 20232 } 20233 } 20234 20235 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 20236 return QDF_STATUS_SUCCESS; 20237 20238 dst->num_ap = src_data->roam_ap_count; 20239 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 20240 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 20241 20242 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 20243 ap_idx, dst->num_ap); 20244 if (QDF_IS_STATUS_ERROR(status)) { 20245 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 20246 return status; 20247 } 20248 20249 return QDF_STATUS_SUCCESS; 20250 } 20251 20252 /** 20253 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 20254 * from the WMI_ROAM_STATS_EVENTID 20255 * @wmi_handle: wmi handle 20256 * @evt_buf: Pointer to the event buffer 20257 * @dst: Pointer to destination structure to fill data 20258 * @idx: TLV id 20259 */ 20260 static QDF_STATUS 20261 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20262 struct wmi_roam_result *dst, uint8_t idx) 20263 { 20264 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20265 wmi_roam_result *src_data = NULL; 20266 20267 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20268 if (!param_buf || !param_buf->roam_result || 20269 idx >= param_buf->num_roam_result) 20270 return QDF_STATUS_E_FAILURE; 20271 20272 src_data = ¶m_buf->roam_result[idx]; 20273 20274 dst->present = true; 20275 dst->status = src_data->roam_status; 20276 dst->timestamp = src_data->timestamp; 20277 dst->roam_abort_reason = src_data->roam_abort_reason; 20278 if (src_data->roam_fail_reason != ROAM_SUCCESS) 20279 dst->fail_reason = 20280 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 20281 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 20282 20283 return QDF_STATUS_SUCCESS; 20284 } 20285 20286 /** 20287 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 20288 * from the WMI_ROAM_STATS_EVENTID 20289 * @wmi_handle: wmi handle 20290 * @evt_buf: Pointer to the event buffer 20291 * @dst: Pointer to destination structure to fill data 20292 * @idx: TLV id 20293 * @rpt_idx: Neighbor report Channel index 20294 */ 20295 static QDF_STATUS 20296 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20297 struct wmi_neighbor_report_data *dst, 20298 uint8_t idx, uint8_t rpt_idx) 20299 { 20300 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20301 wmi_roam_neighbor_report_info *src_data = NULL; 20302 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 20303 uint8_t i; 20304 20305 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20306 if (!param_buf || !param_buf->roam_neighbor_report_info || 20307 !param_buf->num_roam_neighbor_report_info || 20308 idx >= param_buf->num_roam_neighbor_report_info) { 20309 wmi_debug("Invalid 1kv param buf"); 20310 return QDF_STATUS_E_FAILURE; 20311 } 20312 20313 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 20314 20315 dst->present = true; 20316 dst->req_type = src_data->request_type; 20317 dst->num_freq = src_data->neighbor_report_channel_count; 20318 dst->req_time = src_data->neighbor_report_request_timestamp; 20319 dst->resp_time = src_data->neighbor_report_response_timestamp; 20320 dst->btm_query_token = src_data->btm_query_token; 20321 dst->btm_query_reason = src_data->btm_query_reason_code; 20322 dst->req_token = 20323 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 20324 dst->resp_token = 20325 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 20326 dst->num_rpt = 20327 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 20328 20329 dst->band = 20330 WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET(src_data->neighbor_report_detail); 20331 20332 if (dst->band != WMI_MLO_BAND_NO_MLO) 20333 dst->is_mlo = true; 20334 20335 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 20336 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 20337 return QDF_STATUS_SUCCESS; 20338 20339 if (!param_buf->roam_neighbor_report_chan_info) { 20340 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 20341 dst->num_freq); 20342 dst->num_freq = 0; 20343 /* return success as its optional tlv and we can print neighbor 20344 * report received info 20345 */ 20346 return QDF_STATUS_SUCCESS; 20347 } 20348 20349 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 20350 20351 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 20352 dst->num_freq = MAX_ROAM_SCAN_CHAN; 20353 20354 if ((dst->num_freq + rpt_idx) > 20355 param_buf->num_roam_neighbor_report_chan_info) { 20356 wmi_err("Invalid TLV. num_freq %d rpt_idx %d num_roam_neighbor_report_chan_info %d", 20357 dst->num_freq, rpt_idx, 20358 param_buf->num_roam_scan_chan_info); 20359 return QDF_STATUS_SUCCESS; 20360 } 20361 20362 for (i = 0; i < dst->num_freq; i++) { 20363 dst->freq[i] = src_freq->channel; 20364 src_freq++; 20365 } 20366 20367 return QDF_STATUS_SUCCESS; 20368 } 20369 20370 /** 20371 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 20372 * @wmi_handle: handle to WMI. 20373 * @roam_param: pointer to hold roam set parameter 20374 * 20375 * Return: QDF_STATUS_SUCCESS for success or error code 20376 */ 20377 static QDF_STATUS 20378 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 20379 struct vdev_set_params *roam_param) 20380 { 20381 QDF_STATUS ret; 20382 wmi_roam_set_param_cmd_fixed_param *cmd; 20383 wmi_buf_t buf; 20384 uint16_t len = sizeof(*cmd); 20385 20386 buf = wmi_buf_alloc(wmi_handle, len); 20387 if (!buf) 20388 return QDF_STATUS_E_NOMEM; 20389 20390 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20391 WMITLV_SET_HDR(&cmd->tlv_header, 20392 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 20393 WMITLV_GET_STRUCT_TLVLEN 20394 (wmi_roam_set_param_cmd_fixed_param)); 20395 cmd->vdev_id = roam_param->vdev_id; 20396 cmd->param_id = roam_param->param_id; 20397 cmd->param_value = roam_param->param_value; 20398 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 20399 cmd->vdev_id, cmd->param_id, cmd->param_value); 20400 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 20401 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20402 WMI_ROAM_SET_PARAM_CMDID); 20403 if (QDF_IS_STATUS_ERROR(ret)) { 20404 wmi_err("Failed to send roam set param command, ret = %d", ret); 20405 wmi_buf_free(buf); 20406 } 20407 20408 return ret; 20409 } 20410 #else 20411 static inline QDF_STATUS 20412 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20413 struct wmi_roam_trigger_info *trig, uint8_t idx, 20414 uint8_t btm_idx) 20415 { 20416 return QDF_STATUS_E_NOSUPPORT; 20417 } 20418 20419 static inline QDF_STATUS 20420 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20421 struct wmi_roam_result *dst, uint8_t idx) 20422 { 20423 return QDF_STATUS_E_NOSUPPORT; 20424 } 20425 20426 static QDF_STATUS 20427 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20428 struct wmi_neighbor_report_data *dst, 20429 uint8_t idx, uint8_t rpt_idx) 20430 { 20431 return QDF_STATUS_E_NOSUPPORT; 20432 } 20433 20434 static QDF_STATUS 20435 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20436 struct wmi_roam_scan_data *dst, uint8_t idx, 20437 uint8_t chan_idx, uint8_t ap_idx) 20438 { 20439 return QDF_STATUS_E_NOSUPPORT; 20440 } 20441 #endif 20442 20443 #ifdef WLAN_FEATURE_PKT_CAPTURE 20444 static QDF_STATUS 20445 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 20446 struct mgmt_offload_event_params *params) 20447 { 20448 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 20449 wmi_mgmt_hdr *hdr; 20450 20451 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 20452 if (!param_tlvs) 20453 return QDF_STATUS_E_INVAL; 20454 20455 hdr = param_tlvs->fixed_param; 20456 if (!hdr) 20457 return QDF_STATUS_E_INVAL; 20458 20459 if (hdr->buf_len > param_tlvs->num_bufp) 20460 return QDF_STATUS_E_INVAL; 20461 20462 params->tsf_l32 = hdr->tsf_l32; 20463 params->chan_freq = hdr->chan_freq; 20464 params->rate_kbps = hdr->rate_kbps; 20465 params->rssi = hdr->rssi; 20466 params->buf_len = hdr->buf_len; 20467 params->tx_status = hdr->tx_status; 20468 params->buf = param_tlvs->bufp; 20469 params->tx_retry_cnt = hdr->tx_retry_cnt; 20470 return QDF_STATUS_SUCCESS; 20471 } 20472 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 20473 20474 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20475 static QDF_STATUS 20476 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 20477 struct smu_event_params *params) 20478 { 20479 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 20480 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 20481 20482 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 20483 if (!param_buf) { 20484 wmi_err("Invalid smart monitor event"); 20485 return QDF_STATUS_E_INVAL; 20486 } 20487 20488 smu_event = param_buf->fixed_param; 20489 if (!smu_event) { 20490 wmi_err("smart monitor event fixed param is NULL"); 20491 return QDF_STATUS_E_INVAL; 20492 } 20493 20494 params->vdev_id = smu_event->vdev_id; 20495 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 20496 return QDF_STATUS_E_INVAL; 20497 20498 params->rx_vht_sgi = smu_event->rx_vht_sgi; 20499 20500 return QDF_STATUS_SUCCESS; 20501 } 20502 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 20503 20504 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20505 /** 20506 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 20507 * 20508 * @wmi: wmi handle 20509 * @vdev_id: vdev id 20510 * @burst_mode: Indicates whether relation derived using FTM is needed for 20511 * each FTM frame or only aggregated result is required. 20512 * 20513 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 20514 * 20515 * Return: QDF_STATUS 20516 */ 20517 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 20518 uint32_t vdev_id, 20519 bool burst_mode) 20520 { 20521 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 20522 wmi_buf_t buf; 20523 int32_t len = sizeof(*cmd); 20524 20525 buf = wmi_buf_alloc(wmi, len); 20526 if (!buf) { 20527 wmi_err("wmi_buf_alloc failed"); 20528 return QDF_STATUS_E_NOMEM; 20529 } 20530 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 20531 WMITLV_SET_HDR(&cmd->tlv_header, 20532 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 20533 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 20534 cmd->vdev_id = vdev_id; 20535 cmd->agg_relation = burst_mode ? false : true; 20536 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 20537 wmi_err("Failed to send audio sync trigger cmd"); 20538 wmi_buf_free(buf); 20539 return QDF_STATUS_E_FAILURE; 20540 } 20541 20542 return QDF_STATUS_SUCCESS; 20543 } 20544 20545 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 20546 uint32_t vdev_id, 20547 uint64_t lpass_ts) 20548 { 20549 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 20550 wmi_buf_t buf; 20551 int32_t len = sizeof(*cmd); 20552 20553 buf = wmi_buf_alloc(wmi, len); 20554 if (!buf) { 20555 wmi_err("wmi_buf_alloc failed"); 20556 return QDF_STATUS_E_NOMEM; 20557 } 20558 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 20559 WMITLV_SET_HDR(&cmd->tlv_header, 20560 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 20561 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 20562 cmd->vdev_id = vdev_id; 20563 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 20564 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 20565 20566 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 20567 wmi_err("Failed to send audio qtime command"); 20568 wmi_buf_free(buf); 20569 return QDF_STATUS_E_FAILURE; 20570 } 20571 20572 return QDF_STATUS_SUCCESS; 20573 } 20574 20575 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 20576 wmi_unified_t wmi, void *buf, 20577 struct ftm_time_sync_start_stop_params *param) 20578 { 20579 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 20580 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 20581 20582 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 20583 if (!param_buf) { 20584 wmi_err("Invalid audio sync start stop event buffer"); 20585 return QDF_STATUS_E_FAILURE; 20586 } 20587 20588 resp_event = param_buf->fixed_param; 20589 if (!resp_event) { 20590 wmi_err("Invalid audio sync start stop fixed param buffer"); 20591 return QDF_STATUS_E_FAILURE; 20592 } 20593 20594 param->vdev_id = resp_event->vdev_id; 20595 param->timer_interval = resp_event->periodicity; 20596 param->num_reads = resp_event->reads_needed; 20597 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 20598 resp_event->qtimer_l32; 20599 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 20600 resp_event->mac_timer_l32; 20601 20602 wmi_debug("FTM time sync time_interval %d, num_reads %d", 20603 param->timer_interval, param->num_reads); 20604 20605 return QDF_STATUS_SUCCESS; 20606 } 20607 20608 static QDF_STATUS 20609 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 20610 struct ftm_time_sync_offset *param) 20611 { 20612 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 20613 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 20614 wmi_audio_sync_q_master_slave_times *q_pair; 20615 int iter; 20616 20617 param_buf = 20618 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 20619 if (!param_buf) { 20620 wmi_err("Invalid timesync ftm offset event buffer"); 20621 return QDF_STATUS_E_FAILURE; 20622 } 20623 20624 resp_event = param_buf->fixed_param; 20625 if (!resp_event) { 20626 wmi_err("Invalid timesync ftm offset fixed param buffer"); 20627 return QDF_STATUS_E_FAILURE; 20628 } 20629 20630 param->vdev_id = resp_event->vdev_id; 20631 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 20632 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 20633 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 20634 20635 q_pair = param_buf->audio_sync_q_master_slave_times; 20636 if (!q_pair) { 20637 wmi_err("Invalid q_master_slave_times buffer"); 20638 return QDF_STATUS_E_FAILURE; 20639 } 20640 20641 for (iter = 0; iter < param->num_qtime; iter++) { 20642 param->pairs[iter].qtime_initiator = ( 20643 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 20644 q_pair[iter].qmaster_l32; 20645 param->pairs[iter].qtime_target = ( 20646 (uint64_t)q_pair[iter].qslave_u32 << 32) | 20647 q_pair[iter].qslave_l32; 20648 } 20649 return QDF_STATUS_SUCCESS; 20650 } 20651 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20652 20653 /** 20654 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 20655 * @wmi: wmi handle 20656 * @vdev_id: vdev id 20657 * 20658 * TSF_TSTAMP_READ_VALUE is the only operation supported 20659 * Return: QDF_STATUS_SUCCESS for success or error code 20660 */ 20661 static QDF_STATUS 20662 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 20663 { 20664 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 20665 wmi_buf_t buf; 20666 int32_t len = sizeof(*cmd); 20667 20668 buf = wmi_buf_alloc(wmi, len); 20669 if (!buf) 20670 return QDF_STATUS_E_NOMEM; 20671 20672 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 20673 WMITLV_SET_HDR(&cmd->tlv_header, 20674 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 20675 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 20676 cmd->vdev_id = vdev_id; 20677 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 20678 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 20679 if (wmi_unified_cmd_send(wmi, buf, len, 20680 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 20681 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 20682 __func__); 20683 wmi_buf_free(buf); 20684 return QDF_STATUS_E_FAILURE; 20685 } 20686 20687 return QDF_STATUS_SUCCESS; 20688 } 20689 20690 /** 20691 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 20692 * @wmi_handle: wmi handle 20693 * @evt_buf: pointer to event buffer 20694 * @param: Pointer to struct to hold event info 20695 * 20696 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 20697 */ 20698 static QDF_STATUS 20699 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20700 struct wmi_host_tsf_event *param) 20701 { 20702 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 20703 wmi_vdev_tsf_report_event_fixed_param *evt; 20704 20705 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 20706 if (!param_buf) { 20707 wmi_err("Invalid tsf report event buffer"); 20708 return QDF_STATUS_E_INVAL; 20709 } 20710 20711 evt = param_buf->fixed_param; 20712 param->vdev_id = evt->vdev_id; 20713 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 20714 param->tsf_low = evt->tsf_low; 20715 param->tsf_high = evt->tsf_high; 20716 param->qtimer_low = evt->qtimer_low; 20717 param->qtimer_high = evt->qtimer_high; 20718 param->tsf_id = evt->tsf_id; 20719 param->tsf_id_valid = evt->tsf_id_valid; 20720 param->mac_id = evt->mac_id; 20721 param->mac_id_valid = evt->mac_id_valid; 20722 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 20723 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 20724 param->tqm_timer_low = evt->tqm_timer_low; 20725 param->tqm_timer_high = evt->tqm_timer_high; 20726 param->use_tqm_timer = evt->use_tqm_timer; 20727 20728 return QDF_STATUS_SUCCESS; 20729 } 20730 20731 /** 20732 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 20733 * status tlv 20734 * @wmi_handle: wmi handle 20735 * @evt_buf: pointer to event buffer 20736 * @param: Pointer to hold csa switch count status event param 20737 * 20738 * Return: QDF_STATUS_SUCCESS for success or error code 20739 */ 20740 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 20741 wmi_unified_t wmi_handle, 20742 void *evt_buf, 20743 struct pdev_csa_switch_count_status *param) 20744 { 20745 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 20746 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 20747 20748 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 20749 evt_buf; 20750 if (!param_buf) { 20751 wmi_err("Invalid CSA status event"); 20752 return QDF_STATUS_E_INVAL; 20753 } 20754 20755 csa_status = param_buf->fixed_param; 20756 20757 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20758 wmi_handle, 20759 csa_status->pdev_id); 20760 param->current_switch_count = csa_status->current_switch_count; 20761 param->num_vdevs = csa_status->num_vdevs; 20762 param->vdev_ids = param_buf->vdev_ids; 20763 20764 return QDF_STATUS_SUCCESS; 20765 } 20766 20767 #ifdef CONFIG_AFC_SUPPORT 20768 /** 20769 * send_afc_cmd_tlv() - Sends the AFC indication to FW 20770 * @wmi_handle: wmi handle 20771 * @pdev_id: Pdev id 20772 * @param: Pointer to hold AFC indication. 20773 * 20774 * Return: QDF_STATUS_SUCCESS for success or error code 20775 */ 20776 static 20777 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 20778 uint8_t pdev_id, 20779 struct reg_afc_resp_rx_ind_info *param) 20780 { 20781 wmi_buf_t buf; 20782 wmi_afc_cmd_fixed_param *cmd; 20783 uint32_t len; 20784 uint8_t *buf_ptr; 20785 QDF_STATUS ret; 20786 20787 len = sizeof(wmi_afc_cmd_fixed_param); 20788 buf = wmi_buf_alloc(wmi_handle, len); 20789 if (!buf) 20790 return QDF_STATUS_E_NOMEM; 20791 20792 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20793 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 20794 20795 WMITLV_SET_HDR(&cmd->tlv_header, 20796 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 20797 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 20798 20799 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 20800 wmi_handle, 20801 pdev_id); 20802 cmd->cmd_type = param->cmd_type; 20803 cmd->serv_resp_format = param->serv_resp_format; 20804 20805 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 20806 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 20807 if (QDF_IS_STATUS_ERROR(ret)) { 20808 wmi_err("Failed to send WMI_AFC_CMDID"); 20809 wmi_buf_free(buf); 20810 return QDF_STATUS_E_FAILURE; 20811 } 20812 20813 return QDF_STATUS_SUCCESS; 20814 } 20815 #endif 20816 20817 /** 20818 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 20819 * @wmi_handle: wmi handle 20820 * @vdev_id: vdev id 20821 * @param: Pointer to hold TX power info 20822 * 20823 * Return: QDF_STATUS_SUCCESS for success or error code 20824 */ 20825 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 20826 uint8_t vdev_id, 20827 struct reg_tpc_power_info *param) 20828 { 20829 wmi_buf_t buf; 20830 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 20831 wmi_vdev_ch_power_info *ch_power_info; 20832 uint8_t *buf_ptr; 20833 uint16_t idx; 20834 uint32_t len; 20835 QDF_STATUS ret; 20836 20837 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 20838 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 20839 20840 buf = wmi_buf_alloc(wmi_handle, len); 20841 if (!buf) 20842 return QDF_STATUS_E_NOMEM; 20843 20844 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20845 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 20846 20847 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 20848 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 20849 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 20850 20851 tpc_power_info_param->vdev_id = vdev_id; 20852 tpc_power_info_param->psd_power = param->is_psd_power; 20853 tpc_power_info_param->eirp_power = param->eirp_power; 20854 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 20855 wmi_debug("eirp_power = %d is_psd_power = %d", 20856 tpc_power_info_param->eirp_power, 20857 tpc_power_info_param->psd_power); 20858 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 20859 20860 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 20861 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 20862 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 20863 20864 buf_ptr += WMI_TLV_HDR_SIZE; 20865 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 20866 20867 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 20868 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 20869 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 20870 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 20871 ch_power_info[idx].chan_cfreq = 20872 param->chan_power_info[idx].chan_cfreq; 20873 ch_power_info[idx].tx_power = 20874 param->chan_power_info[idx].tx_power; 20875 wmi_debug("chan_cfreq = %d tx_power = %d", 20876 ch_power_info[idx].chan_cfreq, 20877 ch_power_info[idx].tx_power); 20878 buf_ptr += sizeof(wmi_vdev_ch_power_info); 20879 } 20880 20881 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 20882 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20883 WMI_VDEV_SET_TPC_POWER_CMDID); 20884 if (QDF_IS_STATUS_ERROR(ret)) 20885 wmi_buf_free(buf); 20886 20887 20888 return ret; 20889 } 20890 20891 /** 20892 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 20893 * @wmi_handle: wmi handle 20894 * @evt_buf: event buffer 20895 * @param: dpd status info 20896 * 20897 * Return: QDF_STATUS_SUCCESS for success or error code 20898 */ 20899 static QDF_STATUS 20900 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 20901 void *evt_buf, 20902 struct wmi_host_pdev_get_dpd_status_event *param) 20903 { 20904 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 20905 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 20906 20907 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 20908 if (!param_buf) { 20909 wmi_err("Invalid get dpd_status event"); 20910 return QDF_STATUS_E_INVAL; 20911 } 20912 20913 dpd_status = param_buf->fixed_param; 20914 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20915 (wmi_handle, dpd_status->pdev_id); 20916 param->dpd_status = dpd_status->dpd_status; 20917 20918 return QDF_STATUS_SUCCESS; 20919 } 20920 20921 static int 20922 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 20923 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 20924 { 20925 if (status->halphy_cal_valid_bmap && valid_bit) 20926 return (status->halphy_cal_status && valid_bit); 20927 20928 return 0; 20929 } 20930 20931 static QDF_STATUS 20932 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 20933 void *evt_buf, 20934 struct wmi_host_pdev_get_halphy_cal_status_event *param) 20935 { 20936 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 20937 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 20938 20939 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 20940 if (!param_buf) { 20941 wmi_err("Invalid get halphy cal status event"); 20942 return QDF_STATUS_E_INVAL; 20943 } 20944 20945 halphy_cal_status = param_buf->fixed_param; 20946 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20947 (wmi_handle, halphy_cal_status->pdev_id); 20948 param->halphy_cal_adc_status = 20949 convert_halphy_status(halphy_cal_status, 20950 WMI_HALPHY_CAL_ADC_BMAP); 20951 param->halphy_cal_bwfilter_status = 20952 convert_halphy_status(halphy_cal_status, 20953 WMI_HALPHY_CAL_BWFILTER_BMAP); 20954 param->halphy_cal_pdet_and_pal_status = 20955 convert_halphy_status(halphy_cal_status, 20956 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 20957 param->halphy_cal_rxdco_status = 20958 convert_halphy_status(halphy_cal_status, 20959 WMI_HALPHY_CAL_RXDCO_BMAP); 20960 param->halphy_cal_comb_txiq_rxiq_status = 20961 convert_halphy_status(halphy_cal_status, 20962 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 20963 param->halphy_cal_ibf_status = 20964 convert_halphy_status(halphy_cal_status, 20965 WMI_HALPHY_CAL_IBF_BMAP); 20966 param->halphy_cal_pa_droop_status = 20967 convert_halphy_status(halphy_cal_status, 20968 WMI_HALPHY_CAL_PA_DROOP_BMAP); 20969 param->halphy_cal_dac_status = 20970 convert_halphy_status(halphy_cal_status, 20971 WMI_HALPHY_CAL_DAC_BMAP); 20972 param->halphy_cal_ani_status = 20973 convert_halphy_status(halphy_cal_status, 20974 WMI_HALPHY_CAL_ANI_BMAP); 20975 param->halphy_cal_noise_floor_status = 20976 convert_halphy_status(halphy_cal_status, 20977 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 20978 20979 return QDF_STATUS_SUCCESS; 20980 } 20981 20982 /** 20983 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 20984 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 20985 * 20986 * Return: host_set_halphy_cal_status 20987 */ 20988 static enum wmi_host_set_halphy_cal_status 20989 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 20990 { 20991 if (fw_status == 0) 20992 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 20993 else if (fw_status == 1) 20994 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20995 20996 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 20997 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 20998 } 20999 21000 /** 21001 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 21002 * @wmi_handle: wmi handle 21003 * @evt_buf: event buffer 21004 * @param: set halphy cal status info 21005 * 21006 * Return: QDF_STATUS_SUCCESS for success or error code 21007 */ 21008 static QDF_STATUS 21009 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 21010 void *evt_buf, 21011 struct wmi_host_pdev_set_halphy_cal_event *param) 21012 { 21013 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 21014 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 21015 21016 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 21017 if (!param_buf) { 21018 wmi_err("Invalid set halphy_status event"); 21019 return QDF_STATUS_E_INVAL; 21020 } 21021 21022 set_halphy_status = param_buf->fixed_param; 21023 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 21024 (wmi_handle, set_halphy_status->pdev_id); 21025 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 21026 21027 return QDF_STATUS_SUCCESS; 21028 } 21029 21030 /** 21031 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 21032 * @wmi_handle: wmi handle 21033 * @evt_buf: pointer to event buffer 21034 * @len: length of the event buffer 21035 * @param: Pointer to hold install key complete event param 21036 * 21037 * Return: QDF_STATUS_SUCCESS for success or error code 21038 */ 21039 static QDF_STATUS 21040 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 21041 void *evt_buf, uint32_t len, 21042 struct wmi_install_key_comp_event *param) 21043 { 21044 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 21045 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 21046 21047 if (len < sizeof(*param_buf)) { 21048 wmi_err("invalid event buf len %d", len); 21049 return QDF_STATUS_E_INVAL; 21050 } 21051 21052 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 21053 if (!param_buf) { 21054 wmi_err("received null buf from target"); 21055 return QDF_STATUS_E_INVAL; 21056 } 21057 21058 key_fp = param_buf->fixed_param; 21059 if (!key_fp) { 21060 wmi_err("received null event data from target"); 21061 return QDF_STATUS_E_INVAL; 21062 } 21063 21064 param->vdev_id = key_fp->vdev_id; 21065 param->key_ix = key_fp->key_ix; 21066 param->key_flags = key_fp->key_flags; 21067 param->status = key_fp->status; 21068 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 21069 param->peer_macaddr); 21070 21071 return QDF_STATUS_SUCCESS; 21072 } 21073 21074 static QDF_STATUS 21075 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 21076 struct wmi_host_send_set_halphy_cal_info *param) 21077 { 21078 wmi_buf_t buf; 21079 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 21080 QDF_STATUS ret; 21081 uint32_t len; 21082 21083 len = sizeof(*cmd); 21084 21085 buf = wmi_buf_alloc(wmi_handle, len); 21086 if (!buf) 21087 return QDF_STATUS_E_FAILURE; 21088 21089 cmd = (void *)wmi_buf_data(buf); 21090 21091 WMITLV_SET_HDR(&cmd->tlv_header, 21092 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 21093 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 21094 21095 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 21096 param->pdev_id); 21097 cmd->online_halphy_cals_bmap = param->value; 21098 cmd->home_scan_channel = param->chan_sel; 21099 21100 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21101 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 21102 if (QDF_IS_STATUS_ERROR(ret)) { 21103 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 21104 wmi_buf_free(buf); 21105 } 21106 21107 return ret; 21108 } 21109 21110 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21111 /** 21112 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 21113 * @wmi: wmi handle 21114 * @params: set MAC address command params 21115 * 21116 * Return: QDF_STATUS_SUCCESS for success or error code 21117 */ 21118 static QDF_STATUS 21119 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 21120 struct set_mac_addr_params *params) 21121 { 21122 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 21123 wmi_buf_t buf; 21124 int32_t len = sizeof(*cmd); 21125 21126 buf = wmi_buf_alloc(wmi, len); 21127 if (!buf) 21128 return QDF_STATUS_E_NOMEM; 21129 21130 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 21131 WMITLV_SET_HDR( 21132 &cmd->tlv_header, 21133 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 21134 WMITLV_GET_STRUCT_TLVLEN 21135 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 21136 cmd->vdev_id = params->vdev_id; 21137 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 21138 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 21139 21140 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 21141 QDF_MAC_ADDR_FMT, cmd->vdev_id, 21142 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 21143 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 21144 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 21145 if (wmi_unified_cmd_send(wmi, buf, len, 21146 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 21147 wmi_buf_free(buf); 21148 return QDF_STATUS_E_FAILURE; 21149 } 21150 21151 return QDF_STATUS_SUCCESS; 21152 } 21153 21154 /** 21155 * extract_update_mac_address_event_tlv() - extract update MAC address event 21156 * @wmi_handle: WMI handle 21157 * @evt_buf: event buffer 21158 * @vdev_id: VDEV ID 21159 * @status: FW status of the set MAC address operation 21160 * 21161 * Return: QDF_STATUS 21162 */ 21163 static QDF_STATUS extract_update_mac_address_event_tlv( 21164 wmi_unified_t wmi_handle, void *evt_buf, 21165 uint8_t *vdev_id, uint8_t *status) 21166 { 21167 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 21168 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 21169 21170 param_buf = 21171 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 21172 21173 event = param_buf->fixed_param; 21174 21175 *vdev_id = event->vdev_id; 21176 *status = event->status; 21177 21178 return QDF_STATUS_SUCCESS; 21179 } 21180 #endif 21181 21182 #ifdef WLAN_FEATURE_11BE_MLO 21183 /** 21184 * extract_quiet_offload_event_tlv() - extract quiet offload event 21185 * @wmi_handle: WMI handle 21186 * @evt_buf: event buffer 21187 * @quiet_event: quiet event extracted from the buffer 21188 * 21189 * Return: QDF_STATUS 21190 */ 21191 static QDF_STATUS extract_quiet_offload_event_tlv( 21192 wmi_unified_t wmi_handle, void *evt_buf, 21193 struct vdev_sta_quiet_event *quiet_event) 21194 { 21195 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 21196 wmi_quiet_event_fixed_param *event; 21197 21198 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 21199 21200 event = param_buf->fixed_param; 21201 21202 if (!(event->mld_mac_address_present && event->linkid_present) && 21203 !event->link_mac_address_present) { 21204 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 21205 event->mld_mac_address_present, 21206 event->linkid_present, 21207 event->link_mac_address_present); 21208 return QDF_STATUS_E_INVAL; 21209 } 21210 21211 if (event->mld_mac_address_present) 21212 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 21213 quiet_event->mld_mac.bytes); 21214 if (event->link_mac_address_present) 21215 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 21216 quiet_event->link_mac.bytes); 21217 if (event->linkid_present) 21218 quiet_event->link_id = event->linkid; 21219 quiet_event->quiet_status = (event->quiet_status == 21220 WMI_QUIET_EVENT_START); 21221 21222 return QDF_STATUS_SUCCESS; 21223 } 21224 #endif 21225 21226 /** 21227 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 21228 * @wmi_handle: wmi handle 21229 * @params: RxFilter params 21230 * 21231 * Return: QDF_STATUS_SUCCESS for success or error code 21232 */ 21233 static QDF_STATUS 21234 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 21235 struct vdev_pn_mgmt_rxfilter_params *params) 21236 { 21237 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 21238 wmi_buf_t buf; 21239 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 21240 21241 if (!is_service_enabled_tlv(wmi_handle, 21242 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 21243 wmi_err("Rx PN Replay Check not supported by target"); 21244 return QDF_STATUS_E_NOSUPPORT; 21245 } 21246 21247 buf = wmi_buf_alloc(wmi_handle, len); 21248 if (!buf) { 21249 wmi_err("wmi buf alloc failed"); 21250 return QDF_STATUS_E_NOMEM; 21251 } 21252 21253 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 21254 WMITLV_SET_HDR( 21255 &cmd->tlv_header, 21256 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 21257 WMITLV_GET_STRUCT_TLVLEN 21258 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 21259 21260 cmd->vdev_id = params->vdev_id; 21261 cmd->pn_rx_filter = params->pn_rxfilter; 21262 21263 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21264 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 21265 wmi_err("Failed to send WMI command"); 21266 wmi_buf_free(buf); 21267 return QDF_STATUS_E_FAILURE; 21268 } 21269 21270 return QDF_STATUS_SUCCESS; 21271 } 21272 21273 static QDF_STATUS 21274 send_egid_info_cmd_tlv(wmi_unified_t wmi_handle, 21275 struct esl_egid_params *param) 21276 { 21277 wmi_esl_egid_cmd_fixed_param *cmd; 21278 wmi_buf_t buf; 21279 21280 uint32_t len = sizeof(*cmd); 21281 21282 buf = wmi_buf_alloc(wmi_handle, len); 21283 if (!buf) { 21284 wmi_err("wmi_buf_alloc failed"); 21285 return QDF_STATUS_E_NOMEM; 21286 } 21287 21288 cmd = (wmi_esl_egid_cmd_fixed_param *)wmi_buf_data(buf); 21289 WMITLV_SET_HDR( 21290 &cmd->tlv_header, 21291 WMITLV_TAG_STRUC_wmi_esl_egid_cmd_fixed_param, 21292 WMITLV_GET_STRUCT_TLVLEN(wmi_esl_egid_cmd_fixed_param)); 21293 qdf_mem_copy(cmd->egid_info, 21294 param->egid_info, 21295 sizeof(param->egid_info)); 21296 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ESL_EGID_CMDID)) { 21297 wmi_err("Failed to send WMI command"); 21298 wmi_buf_free(buf); 21299 return QDF_STATUS_E_FAILURE; 21300 } 21301 21302 return QDF_STATUS_SUCCESS; 21303 } 21304 21305 static QDF_STATUS 21306 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 21307 uint8_t *pdev_id, uint8_t *software_image, 21308 uint8_t *chip_info, 21309 uint32_t *pktlog_json_version) 21310 { 21311 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 21312 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 21313 21314 param_buf = 21315 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 21316 21317 event = param_buf->fixed_param; 21318 21319 if ((event->software_image[0] == '\0') || 21320 (event->chip_info[0] == '\0')) { 21321 *pdev_id = event->pdev_id; 21322 return QDF_STATUS_E_INVAL; 21323 } 21324 21325 qdf_mem_copy(software_image, event->software_image, 40); 21326 qdf_mem_copy(chip_info, event->chip_info, 40); 21327 *pktlog_json_version = event->pktlog_defs_json_version; 21328 *pdev_id = event->pdev_id; 21329 return QDF_STATUS_SUCCESS; 21330 } 21331 21332 #ifdef HEALTH_MON_SUPPORT 21333 /** 21334 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 21335 * fw 21336 * @wmi_handle: wmi handle 21337 * @evt_buf: pointer to event buffer 21338 * @param: health monitor params 21339 * 21340 * Return: QDF_STATUS_SUCCESS for success or error code 21341 */ 21342 static QDF_STATUS 21343 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 21344 void *evt_buf, 21345 struct wmi_health_mon_params *param) 21346 { 21347 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 21348 wmi_health_mon_init_done_fixed_param *event; 21349 21350 param_buf = 21351 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 21352 21353 event = param_buf->fixed_param; 21354 21355 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 21356 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 21357 param->initial_upload_period_ms = event->initial_upload_period_ms; 21358 param->read_index = 0; 21359 21360 return QDF_STATUS_SUCCESS; 21361 } 21362 #endif /* HEALTH_MON_SUPPORT */ 21363 21364 /** 21365 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 21366 * @wmi_handle: wmi handle 21367 * @evt_buf: pointer to event buffer 21368 * @pdev_stats: Pointer to hold pdev telemetry stats 21369 * 21370 * Return: QDF_STATUS_SUCCESS for success or error code 21371 */ 21372 static QDF_STATUS 21373 extract_pdev_telemetry_stats_tlv( 21374 wmi_unified_t wmi_handle, void *evt_buf, 21375 struct wmi_host_pdev_telemetry_stats *pdev_stats) 21376 { 21377 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 21378 wmi_pdev_telemetry_stats *ev; 21379 21380 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 21381 21382 if (param_buf->pdev_telemetry_stats) { 21383 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 21384 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 21385 ev->avg_chan_lat_per_ac, 21386 sizeof(ev->avg_chan_lat_per_ac)); 21387 pdev_stats->estimated_air_time_per_ac = 21388 ev->estimated_air_time_per_ac; 21389 } 21390 21391 return QDF_STATUS_SUCCESS; 21392 } 21393 21394 static QDF_STATUS 21395 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 21396 struct set_rx_mac_filter *param) 21397 { 21398 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 21399 uint32_t len; 21400 wmi_buf_t buf; 21401 int ret; 21402 21403 if (!wmi_handle) { 21404 wmi_err("WMA context is invalid!"); 21405 return QDF_STATUS_E_INVAL; 21406 } 21407 21408 len = sizeof(*cmd); 21409 buf = wmi_buf_alloc(wmi_handle, len); 21410 if (!buf) { 21411 wmi_err("Failed allocate wmi buffer"); 21412 return QDF_STATUS_E_NOMEM; 21413 } 21414 21415 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 21416 wmi_buf_data(buf); 21417 21418 WMITLV_SET_HDR( 21419 &cmd->tlv_header, 21420 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 21421 WMITLV_GET_STRUCT_TLVLEN( 21422 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 21423 21424 cmd->vdev_id = param->vdev_id; 21425 cmd->freq = param->freq; 21426 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 21427 if (param->set) 21428 cmd->enable = 1; 21429 else 21430 cmd->enable = 0; 21431 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 21432 param->vdev_id, param->freq, param->set, 21433 QDF_MAC_ADDR_REF(param->mac)); 21434 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21435 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 21436 if (ret) { 21437 wmi_err("Failed to send action frame random mac cmd"); 21438 wmi_buf_free(buf); 21439 return QDF_STATUS_E_FAILURE; 21440 } 21441 21442 return QDF_STATUS_SUCCESS; 21443 } 21444 21445 static QDF_STATUS 21446 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 21447 uint8_t *event, 21448 struct wmi_host_coex_fix_chan_cap *cap) 21449 { 21450 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 21451 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 21452 21453 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 21454 if (!param_buf) 21455 return QDF_STATUS_E_INVAL; 21456 21457 fw_cap = param_buf->coex_fix_channel_caps; 21458 if (!fw_cap) 21459 return QDF_STATUS_E_INVAL; 21460 21461 cap->fix_chan_priority = fw_cap->fix_channel_priority; 21462 21463 return QDF_STATUS_SUCCESS; 21464 } 21465 21466 static QDF_STATUS extract_tgtr2p_table_event_tlv(wmi_unified_t wmi_handle, 21467 uint8_t *evt_buf, 21468 struct r2p_table_update_status_obj *update_status, 21469 uint32_t len) 21470 { 21471 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *param_buf; 21472 wmi_pdev_set_tgtr2p_table_event_fixed_param *event_fixed_hdr; 21473 21474 param_buf = (WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *)evt_buf; 21475 if (!param_buf) { 21476 wmi_err("Invalid TGTR2P event buf"); 21477 return QDF_STATUS_E_FAILURE; 21478 } 21479 21480 event_fixed_hdr = param_buf->fixed_param; 21481 update_status->pdev_id = event_fixed_hdr->pdev_id; 21482 update_status->status = event_fixed_hdr->status; 21483 21484 if (update_status->status != WMI_PDEV_TGTR2P_SUCCESS && 21485 update_status->status != 21486 WMI_PDEV_TGTR2P_SUCCESS_WAITING_FOR_END_OF_UPDATE) { 21487 wmi_err("Rate2Power table update failed. Status = %d", 21488 update_status->status); 21489 } 21490 21491 return QDF_STATUS_SUCCESS; 21492 } 21493 21494 struct wmi_ops tlv_ops = { 21495 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21496 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21497 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 21498 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21499 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21500 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21501 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21502 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21503 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21504 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21505 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21506 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 21507 .send_peer_rx_reorder_queue_setup_cmd = 21508 send_peer_rx_reorder_queue_setup_cmd_tlv, 21509 .send_peer_multi_rx_reorder_queue_setup_cmd = 21510 send_peer_multi_rx_reorder_queue_setup_cmd_tlv, 21511 .send_peer_rx_reorder_queue_remove_cmd = 21512 send_peer_rx_reorder_queue_remove_cmd_tlv, 21513 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21514 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21515 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 21516 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 21517 .send_pdev_set_rf_path_cmd = send_pdev_set_rf_path_cmd_tlv, 21518 .send_suspend_cmd = send_suspend_cmd_tlv, 21519 .send_resume_cmd = send_resume_cmd_tlv, 21520 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21521 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21522 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21523 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21524 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21525 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21526 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 21527 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21528 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 21529 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21530 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21531 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21532 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 21533 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21534 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21535 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21536 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21537 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21538 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21539 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21540 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21541 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 21542 .send_set_sta_uapsd_auto_trig_cmd = 21543 send_set_sta_uapsd_auto_trig_cmd_tlv, 21544 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21545 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21546 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21547 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21548 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21549 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21550 .send_probe_rsp_tmpl_send_cmd = 21551 send_probe_rsp_tmpl_send_cmd_tlv, 21552 .send_p2p_go_set_beacon_ie_cmd = 21553 send_p2p_go_set_beacon_ie_cmd_tlv, 21554 .send_setup_install_key_cmd = 21555 send_setup_install_key_cmd_tlv, 21556 .send_scan_probe_setoui_cmd = 21557 send_scan_probe_setoui_cmd_tlv, 21558 #ifdef IPA_OFFLOAD 21559 .send_ipa_offload_control_cmd = 21560 send_ipa_offload_control_cmd_tlv, 21561 #endif 21562 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21563 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21564 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 21565 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21566 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21567 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21568 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21569 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21570 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21571 .send_unified_ll_stats_get_sta_cmd = 21572 send_unified_ll_stats_get_sta_cmd_tlv, 21573 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21574 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21575 .send_congestion_cmd = send_congestion_cmd_tlv, 21576 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21577 .send_snr_cmd = send_snr_cmd_tlv, 21578 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21579 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 21580 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21581 #endif 21582 #ifdef WLAN_SUPPORT_GREEN_AP 21583 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21584 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21585 .extract_green_ap_egap_status_info = 21586 extract_green_ap_egap_status_info_tlv, 21587 #endif 21588 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21589 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 21590 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 21591 #endif 21592 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21593 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21594 #ifdef FEATURE_OEM_DATA 21595 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 21596 #endif 21597 #ifdef WLAN_FEATURE_CIF_CFR 21598 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21599 #endif 21600 .send_dfs_phyerr_filter_offload_en_cmd = 21601 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21602 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21603 .send_process_dhcpserver_offload_cmd = 21604 send_process_dhcpserver_offload_cmd_tlv, 21605 .send_pdev_set_regdomain_cmd = 21606 send_pdev_set_regdomain_cmd_tlv, 21607 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 21608 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 21609 .save_fw_version_cmd = save_fw_version_cmd_tlv, 21610 .check_and_update_fw_version = 21611 check_and_update_fw_version_cmd_tlv, 21612 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 21613 .send_enable_specific_fw_logs_cmd = 21614 send_enable_specific_fw_logs_cmd_tlv, 21615 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 21616 .send_unit_test_cmd = send_unit_test_cmd_tlv, 21617 #ifdef FEATURE_WLAN_APF 21618 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 21619 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 21620 .send_apf_write_work_memory_cmd = 21621 wmi_send_apf_write_work_memory_cmd_tlv, 21622 .send_apf_read_work_memory_cmd = 21623 wmi_send_apf_read_work_memory_cmd_tlv, 21624 .extract_apf_read_memory_resp_event = 21625 wmi_extract_apf_read_memory_resp_event_tlv, 21626 #endif /* FEATURE_WLAN_APF */ 21627 .init_cmd_send = init_cmd_send_tlv, 21628 .send_vdev_set_custom_aggr_size_cmd = 21629 send_vdev_set_custom_aggr_size_cmd_tlv, 21630 .send_vdev_set_qdepth_thresh_cmd = 21631 send_vdev_set_qdepth_thresh_cmd_tlv, 21632 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 21633 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 21634 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 21635 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 21636 .send_periodic_chan_stats_config_cmd = 21637 send_periodic_chan_stats_config_cmd_tlv, 21638 #ifdef WLAN_IOT_SIM_SUPPORT 21639 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 21640 #endif 21641 .send_vdev_spectral_configure_cmd = 21642 send_vdev_spectral_configure_cmd_tlv, 21643 .send_vdev_spectral_enable_cmd = 21644 send_vdev_spectral_enable_cmd_tlv, 21645 #ifdef WLAN_CONV_SPECTRAL_ENABLE 21646 .extract_pdev_sscan_fw_cmd_fixed_param = 21647 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 21648 .extract_pdev_sscan_fft_bin_index = 21649 extract_pdev_sscan_fft_bin_index_tlv, 21650 .extract_pdev_spectral_session_chan_info = 21651 extract_pdev_spectral_session_chan_info_tlv, 21652 .extract_pdev_spectral_session_detector_info = 21653 extract_pdev_spectral_session_detector_info_tlv, 21654 .extract_spectral_caps_fixed_param = 21655 extract_spectral_caps_fixed_param_tlv, 21656 .extract_spectral_scan_bw_caps = 21657 extract_spectral_scan_bw_caps_tlv, 21658 .extract_spectral_fft_size_caps = 21659 extract_spectral_fft_size_caps_tlv, 21660 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 21661 .send_thermal_mitigation_param_cmd = 21662 send_thermal_mitigation_param_cmd_tlv, 21663 .send_process_update_edca_param_cmd = 21664 send_process_update_edca_param_cmd_tlv, 21665 .send_bss_color_change_enable_cmd = 21666 send_bss_color_change_enable_cmd_tlv, 21667 .send_coex_config_cmd = send_coex_config_cmd_tlv, 21668 .send_coex_multi_config_cmd = send_coex_multi_config_cmd_tlv, 21669 .send_set_country_cmd = send_set_country_cmd_tlv, 21670 .send_addba_send_cmd = send_addba_send_cmd_tlv, 21671 .send_delba_send_cmd = send_delba_send_cmd_tlv, 21672 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 21673 .get_target_cap_from_service_ready = extract_service_ready_tlv, 21674 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 21675 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 21676 .extract_host_mem_req = extract_host_mem_req_tlv, 21677 .save_service_bitmap = save_service_bitmap_tlv, 21678 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 21679 .is_service_enabled = is_service_enabled_tlv, 21680 .save_fw_version = save_fw_version_in_service_ready_tlv, 21681 .ready_extract_init_status = ready_extract_init_status_tlv, 21682 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 21683 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 21684 .extract_ready_event_params = extract_ready_event_params_tlv, 21685 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 21686 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 21687 .extract_frame_pn_params = extract_frame_pn_params_tlv, 21688 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 21689 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 21690 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 21691 #ifdef FEATURE_WLAN_SCAN_PNO 21692 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 21693 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 21694 #endif 21695 .extract_unit_test = extract_unit_test_tlv, 21696 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 21697 .extract_bcn_stats = extract_bcn_stats_tlv, 21698 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 21699 .extract_chan_stats = extract_chan_stats_tlv, 21700 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 21701 .extract_profile_ctx = extract_profile_ctx_tlv, 21702 .extract_profile_data = extract_profile_data_tlv, 21703 .send_fw_test_cmd = send_fw_test_cmd_tlv, 21704 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 21705 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 21706 .extract_service_ready_ext = extract_service_ready_ext_tlv, 21707 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 21708 .extract_dbs_or_sbs_service_ready_ext2 = 21709 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 21710 .extract_hw_mode_cap_service_ready_ext = 21711 extract_hw_mode_cap_service_ready_ext_tlv, 21712 .extract_mac_phy_cap_service_ready_ext = 21713 extract_mac_phy_cap_service_ready_ext_tlv, 21714 .extract_mac_phy_cap_service_ready_ext2 = 21715 extract_mac_phy_cap_service_ready_ext2_tlv, 21716 .extract_reg_cap_service_ready_ext = 21717 extract_reg_cap_service_ready_ext_tlv, 21718 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 21719 .extract_dbr_ring_cap_service_ready_ext = 21720 extract_dbr_ring_cap_service_ready_ext_tlv, 21721 .extract_dbr_ring_cap_service_ready_ext2 = 21722 extract_dbr_ring_cap_service_ready_ext2_tlv, 21723 .extract_scan_radio_cap_service_ready_ext2 = 21724 extract_scan_radio_cap_service_ready_ext2_tlv, 21725 .extract_msdu_idx_qtype_map_service_ready_ext2 = 21726 extract_msdu_idx_qtype_map_service_ready_ext2_tlv, 21727 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 21728 .extract_aux_dev_cap_service_ready_ext2 = 21729 extract_aux_dev_cap_service_ready_ext2_tlv, 21730 .extract_sar_cap_service_ready_ext = 21731 extract_sar_cap_service_ready_ext_tlv, 21732 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 21733 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 21734 .extract_fips_event_data = extract_fips_event_data_tlv, 21735 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21736 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 21737 #endif 21738 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 21739 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 21740 #endif 21741 #ifdef WLAN_FEATURE_DISA 21742 .extract_encrypt_decrypt_resp_event = 21743 extract_encrypt_decrypt_resp_event_tlv, 21744 #endif 21745 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 21746 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21747 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 21748 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 21749 #endif 21750 .extract_get_pn_data = extract_get_pn_data_tlv, 21751 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 21752 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 21753 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 21754 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 21755 #ifdef WLAN_FEATURE_DISA 21756 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 21757 #endif 21758 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 21759 .send_wlan_profile_hist_intvl_cmd = 21760 send_wlan_profile_hist_intvl_cmd_tlv, 21761 .is_management_record = is_management_record_tlv, 21762 .is_diag_event = is_diag_event_tlv, 21763 .is_force_fw_hang_cmd = is_force_fw_hang_cmd_tlv, 21764 #ifdef WLAN_FEATURE_ACTION_OUI 21765 .send_action_oui_cmd = send_action_oui_cmd_tlv, 21766 #endif 21767 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 21768 #ifdef QCA_SUPPORT_AGILE_DFS 21769 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 21770 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 21771 #endif 21772 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 21773 .extract_reg_chan_list_update_event = 21774 extract_reg_chan_list_update_event_tlv, 21775 #ifdef CONFIG_BAND_6GHZ 21776 .extract_reg_chan_list_ext_update_event = 21777 extract_reg_chan_list_ext_update_event_tlv, 21778 #ifdef CONFIG_AFC_SUPPORT 21779 .extract_afc_event = extract_afc_event_tlv, 21780 #endif 21781 #endif 21782 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 21783 .extract_num_rf_characterization_entries = 21784 extract_num_rf_characterization_entries_tlv, 21785 .extract_rf_characterization_entries = 21786 extract_rf_characterization_entries_tlv, 21787 #endif 21788 .extract_chainmask_tables = 21789 extract_chainmask_tables_tlv, 21790 .extract_thermal_stats = extract_thermal_stats_tlv, 21791 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 21792 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 21793 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 21794 #ifdef DFS_COMPONENT_ENABLE 21795 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 21796 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 21797 .extract_dfs_radar_detection_event = 21798 extract_dfs_radar_detection_event_tlv, 21799 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 21800 #endif 21801 .convert_pdev_id_host_to_target = 21802 convert_host_pdev_id_to_target_pdev_id_legacy, 21803 .convert_pdev_id_target_to_host = 21804 convert_target_pdev_id_to_host_pdev_id_legacy, 21805 21806 .convert_host_pdev_id_to_target = 21807 convert_host_pdev_id_to_target_pdev_id, 21808 .convert_target_pdev_id_to_host = 21809 convert_target_pdev_id_to_host_pdev_id, 21810 21811 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 21812 21813 .convert_phy_id_host_to_target = 21814 convert_host_phy_id_to_target_phy_id_legacy, 21815 .convert_phy_id_target_to_host = 21816 convert_target_phy_id_to_host_phy_id_legacy, 21817 21818 .convert_host_phy_id_to_target = 21819 convert_host_phy_id_to_target_phy_id, 21820 .convert_target_phy_id_to_host = 21821 convert_target_phy_id_to_host_phy_id, 21822 21823 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 21824 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 21825 .extract_reg_11d_new_country_event = 21826 extract_reg_11d_new_country_event_tlv, 21827 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 21828 .extract_reg_ch_avoid_event = 21829 extract_reg_ch_avoid_event_tlv, 21830 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 21831 .extract_obss_detection_info = extract_obss_detection_info_tlv, 21832 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 21833 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 21834 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 21835 .wmi_check_command_params = wmitlv_check_command_tlv_params, 21836 .extract_comb_phyerr = extract_comb_phyerr_tlv, 21837 .extract_single_phyerr = extract_single_phyerr_tlv, 21838 #ifdef QCA_SUPPORT_CP_STATS 21839 .extract_cca_stats = extract_cca_stats_tlv, 21840 #endif 21841 .extract_esp_estimation_ev_param = 21842 extract_esp_estimation_ev_param_tlv, 21843 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 21844 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 21845 #ifdef OBSS_PD 21846 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 21847 .send_obss_spatial_reuse_set_def_thresh = 21848 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 21849 .send_self_srg_bss_color_bitmap_set = 21850 send_self_srg_bss_color_bitmap_set_cmd_tlv, 21851 .send_self_srg_partial_bssid_bitmap_set = 21852 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 21853 .send_self_srg_obss_color_enable_bitmap = 21854 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 21855 .send_self_srg_obss_bssid_enable_bitmap = 21856 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 21857 .send_self_non_srg_obss_color_enable_bitmap = 21858 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 21859 .send_self_non_srg_obss_bssid_enable_bitmap = 21860 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 21861 #endif 21862 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 21863 .extract_ctl_failsafe_check_ev_param = 21864 extract_ctl_failsafe_check_ev_param_tlv, 21865 #ifdef WIFI_POS_CONVERGED 21866 .extract_oem_response_param = extract_oem_response_param_tlv, 21867 #endif /* WIFI_POS_CONVERGED */ 21868 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21869 .extract_pasn_peer_create_req_event = 21870 extract_pasn_peer_create_req_event_tlv, 21871 .extract_pasn_peer_delete_req_event = 21872 extract_pasn_peer_delete_req_event_tlv, 21873 .send_rtt_pasn_auth_status_cmd = 21874 send_rtt_pasn_auth_status_cmd_tlv, 21875 .send_rtt_pasn_deauth_cmd = 21876 send_rtt_pasn_deauth_cmd_tlv, 21877 #endif 21878 #ifdef WLAN_MWS_INFO_DEBUGFS 21879 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 21880 #endif 21881 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 21882 #ifdef FEATURE_ANI_LEVEL_REQUEST 21883 .send_ani_level_cmd = send_ani_level_cmd_tlv, 21884 .extract_ani_level = extract_ani_level_tlv, 21885 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 21886 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 21887 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 21888 .extract_roam_result_stats = extract_roam_result_stats_tlv, 21889 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 21890 #ifdef WLAN_FEATURE_PKT_CAPTURE 21891 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 21892 #endif 21893 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 21894 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 21895 #endif 21896 21897 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 21898 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 21899 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 21900 .extract_time_sync_ftm_start_stop_event = 21901 extract_time_sync_ftm_start_stop_event_tlv, 21902 .extract_time_sync_ftm_offset_event = 21903 extract_time_sync_ftm_offset_event_tlv, 21904 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 21905 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 21906 .send_injector_config_cmd = send_injector_config_cmd_tlv, 21907 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 21908 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 21909 #ifdef FEATURE_MEC_OFFLOAD 21910 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 21911 #endif 21912 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_CONFIG_TELEMETRY_AGENT) 21913 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 21914 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 21915 .extract_cp_stats_more_pending = 21916 extract_cp_stats_more_pending_tlv, 21917 .extract_halphy_stats_end_of_event = 21918 extract_halphy_stats_end_of_event_tlv, 21919 .extract_halphy_stats_event_count = 21920 extract_halphy_stats_event_count_tlv, 21921 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 21922 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 21923 .extract_pdev_csa_switch_count_status = 21924 extract_pdev_csa_switch_count_status_tlv, 21925 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 21926 #ifdef CONFIG_AFC_SUPPORT 21927 .send_afc_cmd = send_afc_cmd_tlv, 21928 #endif 21929 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 21930 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 21931 .send_vdev_set_ltf_key_seed_cmd = 21932 send_vdev_set_ltf_key_seed_cmd_tlv, 21933 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 21934 .send_set_halphy_cal = send_set_halphy_cal_tlv, 21935 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 21936 #ifdef WLAN_MGMT_RX_REO_SUPPORT 21937 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 21938 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 21939 .send_mgmt_rx_reo_filter_config_cmd = 21940 send_mgmt_rx_reo_filter_config_cmd_tlv, 21941 #endif 21942 21943 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21944 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 21945 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 21946 21947 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21948 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 21949 .extract_update_mac_address_event = 21950 extract_update_mac_address_event_tlv, 21951 #endif 21952 21953 #ifdef WLAN_FEATURE_11BE_MLO 21954 .extract_quiet_offload_event = 21955 extract_quiet_offload_event_tlv, 21956 #endif 21957 21958 #ifdef WLAN_SUPPORT_PPEDS 21959 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 21960 #endif /* WLAN_SUPPORT_PPEDS */ 21961 21962 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 21963 .extract_pktlog_decode_info_event = 21964 extract_pktlog_decode_info_event_tlv, 21965 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 21966 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 21967 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 21968 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 21969 #endif 21970 #ifdef WLAN_FEATURE_DBAM_CONFIG 21971 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 21972 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 21973 #endif 21974 #ifdef FEATURE_SET 21975 .feature_set_cmd_send = feature_set_cmd_send_tlv, 21976 #endif 21977 #ifdef HEALTH_MON_SUPPORT 21978 .extract_health_mon_init_done_info_event = 21979 extract_health_mon_init_done_info_event_tlv, 21980 #endif /* HEALTH_MON_SUPPORT */ 21981 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 21982 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 21983 .send_update_edca_pifs_param_cmd = 21984 send_update_edca_pifs_param_cmd_tlv, 21985 .extract_sap_coex_cap_service_ready_ext2 = 21986 extract_sap_coex_fix_chan_caps, 21987 .extract_tgtr2p_table_event = extract_tgtr2p_table_event_tlv, 21988 .send_egid_info_cmd = send_egid_info_cmd_tlv, 21989 .extract_csa_ie_received_ev_params = 21990 extract_csa_ie_received_ev_params_tlv, 21991 .extract_rf_path_resp = extract_rf_path_resp_tlv, 21992 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 21993 .extract_aoa_caps_service_ready_ext2 = 21994 extract_aoa_caps_tlv, 21995 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 21996 }; 21997 21998 #ifdef WLAN_FEATURE_11BE_MLO 21999 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 22000 { 22001 event_ids[wmi_mlo_setup_complete_event_id] = 22002 WMI_MLO_SETUP_COMPLETE_EVENTID; 22003 event_ids[wmi_mlo_teardown_complete_event_id] = 22004 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 22005 event_ids[wmi_mlo_link_set_active_resp_eventid] = 22006 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 22007 event_ids[wmi_vdev_quiet_offload_eventid] = 22008 WMI_QUIET_HANDLING_EVENTID; 22009 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 22010 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 22011 event_ids[wmi_mlo_link_removal_eventid] = 22012 WMI_MLO_LINK_REMOVAL_EVENTID; 22013 event_ids[wmi_mlo_link_state_info_eventid] = 22014 WMI_MLO_VDEV_LINK_INFO_EVENTID; 22015 event_ids[wmi_mlo_link_disable_request_eventid] = 22016 WMI_MLO_LINK_DISABLE_REQUEST_EVENTID; 22017 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 22018 event_ids[wmi_mlo_link_switch_request_eventid] = 22019 WMI_MLO_LINK_SWITCH_REQUEST_EVENTID; 22020 event_ids[wmi_mlo_link_state_switch_eventid] = 22021 WMI_MLO_LINK_STATE_SWITCH_EVENTID; 22022 #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */ 22023 } 22024 #else /* WLAN_FEATURE_11BE_MLO */ 22025 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 22026 { 22027 } 22028 #endif /* WLAN_FEATURE_11BE_MLO */ 22029 22030 /** 22031 * populate_tlv_events_id() - populates wmi event ids 22032 * @event_ids: Pointer to hold event ids 22033 * 22034 * Return: None 22035 */ 22036 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 22037 { 22038 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22039 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22040 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22041 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22042 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22043 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22044 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22045 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22046 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22047 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22048 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22049 event_ids[wmi_service_ready_ext_event_id] = 22050 WMI_SERVICE_READY_EXT_EVENTID; 22051 event_ids[wmi_service_ready_ext2_event_id] = 22052 WMI_SERVICE_READY_EXT2_EVENTID; 22053 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22054 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22055 event_ids[wmi_vdev_install_key_complete_event_id] = 22056 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22057 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22058 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22059 22060 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22061 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22062 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22063 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22064 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22065 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22066 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22067 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22068 event_ids[wmi_peer_create_conf_event_id] = 22069 WMI_PEER_CREATE_CONF_EVENTID; 22070 event_ids[wmi_peer_delete_response_event_id] = 22071 WMI_PEER_DELETE_RESP_EVENTID; 22072 event_ids[wmi_peer_delete_all_response_event_id] = 22073 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 22074 event_ids[wmi_peer_oper_mode_change_event_id] = 22075 WMI_PEER_OPER_MODE_CHANGE_EVENTID; 22076 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22077 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22078 event_ids[wmi_tbttoffset_update_event_id] = 22079 WMI_TBTTOFFSET_UPDATE_EVENTID; 22080 event_ids[wmi_ext_tbttoffset_update_event_id] = 22081 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22082 event_ids[wmi_offload_bcn_tx_status_event_id] = 22083 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22084 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22085 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22086 event_ids[wmi_mgmt_tx_completion_event_id] = 22087 WMI_MGMT_TX_COMPLETION_EVENTID; 22088 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22089 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22090 event_ids[wmi_tx_delba_complete_event_id] = 22091 WMI_TX_DELBA_COMPLETE_EVENTID; 22092 event_ids[wmi_tx_addba_complete_event_id] = 22093 WMI_TX_ADDBA_COMPLETE_EVENTID; 22094 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22095 22096 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22097 22098 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22099 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22100 22101 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22102 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22103 22104 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22105 22106 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22107 event_ids[wmi_p2p_lo_stop_event_id] = 22108 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22109 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 22110 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 22111 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22112 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22113 event_ids[wmi_d0_wow_disable_ack_event_id] = 22114 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22115 event_ids[wmi_wow_initial_wakeup_event_id] = 22116 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22117 22118 event_ids[wmi_rtt_meas_report_event_id] = 22119 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22120 event_ids[wmi_tsf_meas_report_event_id] = 22121 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22122 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22123 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22124 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22125 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22126 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22127 event_ids[wmi_diag_event_id_log_supported_event_id] = 22128 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22129 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22130 event_ids[wmi_nlo_scan_complete_event_id] = 22131 WMI_NLO_SCAN_COMPLETE_EVENTID; 22132 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22133 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22134 22135 event_ids[wmi_gtk_offload_status_event_id] = 22136 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22137 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22138 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22139 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22140 22141 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22142 22143 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22144 22145 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22146 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22147 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22148 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22149 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22150 event_ids[wmi_wlan_profile_data_event_id] = 22151 WMI_WLAN_PROFILE_DATA_EVENTID; 22152 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22153 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22154 event_ids[wmi_vdev_get_keepalive_event_id] = 22155 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22156 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22157 22158 event_ids[wmi_diag_container_event_id] = 22159 WMI_DIAG_DATA_CONTAINER_EVENTID; 22160 22161 event_ids[wmi_host_auto_shutdown_event_id] = 22162 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22163 22164 event_ids[wmi_update_whal_mib_stats_event_id] = 22165 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22166 22167 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22168 event_ids[wmi_update_vdev_rate_stats_event_id] = 22169 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22170 22171 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22172 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22173 22174 /** Set OCB Sched Response, deprecated */ 22175 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22176 22177 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22178 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22179 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22180 22181 /* GPIO Event */ 22182 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22183 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22184 22185 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22186 event_ids[wmi_rfkill_state_change_event_id] = 22187 WMI_RFKILL_STATE_CHANGE_EVENTID; 22188 22189 /* TDLS Event */ 22190 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22191 22192 event_ids[wmi_batch_scan_enabled_event_id] = 22193 WMI_BATCH_SCAN_ENABLED_EVENTID; 22194 event_ids[wmi_batch_scan_result_event_id] = 22195 WMI_BATCH_SCAN_RESULT_EVENTID; 22196 /* OEM Event */ 22197 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22198 event_ids[wmi_oem_meas_report_event_id] = 22199 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22200 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22201 22202 /* NAN Event */ 22203 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22204 22205 /* LPI Event */ 22206 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22207 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22208 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22209 22210 /* ExtScan events */ 22211 event_ids[wmi_extscan_start_stop_event_id] = 22212 WMI_EXTSCAN_START_STOP_EVENTID; 22213 event_ids[wmi_extscan_operation_event_id] = 22214 WMI_EXTSCAN_OPERATION_EVENTID; 22215 event_ids[wmi_extscan_table_usage_event_id] = 22216 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22217 event_ids[wmi_extscan_cached_results_event_id] = 22218 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22219 event_ids[wmi_extscan_wlan_change_results_event_id] = 22220 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22221 event_ids[wmi_extscan_hotlist_match_event_id] = 22222 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22223 event_ids[wmi_extscan_capabilities_event_id] = 22224 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22225 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22226 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22227 22228 /* mDNS offload events */ 22229 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22230 22231 /* SAP Authentication offload events */ 22232 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22233 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22234 22235 /** Out-of-context-of-bss (OCB) events */ 22236 event_ids[wmi_ocb_set_config_resp_event_id] = 22237 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22238 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22239 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22240 event_ids[wmi_dcc_get_stats_resp_event_id] = 22241 WMI_DCC_GET_STATS_RESP_EVENTID; 22242 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22243 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22244 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22245 /* System-On-Chip events */ 22246 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22247 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22248 event_ids[wmi_soc_hw_mode_transition_event_id] = 22249 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22250 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22251 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22252 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22253 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 22254 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 22255 #endif 22256 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22257 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22258 event_ids[wmi_vdev_ocac_complete_event_id] = 22259 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 22260 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22261 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 22262 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 22263 #ifdef CONFIG_AFC_SUPPORT 22264 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 22265 #endif 22266 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22267 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22268 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22269 WMI_PEER_STA_PS_STATECHG_EVENTID; 22270 event_ids[wmi_pdev_channel_hopping_event_id] = 22271 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22272 event_ids[wmi_offchan_data_tx_completion_event] = 22273 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22274 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22275 event_ids[wmi_dfs_radar_detection_event_id] = 22276 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22277 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22278 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22279 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22280 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22281 event_ids[wmi_service_available_event_id] = 22282 WMI_SERVICE_AVAILABLE_EVENTID; 22283 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22284 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22285 /* NDP events */ 22286 event_ids[wmi_ndp_initiator_rsp_event_id] = 22287 WMI_NDP_INITIATOR_RSP_EVENTID; 22288 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22289 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22290 event_ids[wmi_ndp_responder_rsp_event_id] = 22291 WMI_NDP_RESPONDER_RSP_EVENTID; 22292 event_ids[wmi_ndp_end_indication_event_id] = 22293 WMI_NDP_END_INDICATION_EVENTID; 22294 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22295 event_ids[wmi_ndl_schedule_update_event_id] = 22296 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22297 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 22298 22299 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22300 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22301 event_ids[wmi_pdev_chip_power_stats_event_id] = 22302 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22303 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22304 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22305 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22306 event_ids[wmi_apf_capability_info_event_id] = 22307 WMI_BPF_CAPABILIY_INFO_EVENTID; 22308 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22309 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22310 event_ids[wmi_report_rx_aggr_failure_event_id] = 22311 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22312 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22313 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22314 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22315 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22316 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22317 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22318 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22319 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22320 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22321 event_ids[wmi_coex_bt_activity_event_id] = 22322 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22323 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22324 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22325 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22326 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22327 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22328 event_ids[wmi_dma_buf_release_event_id] = 22329 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22330 event_ids[wmi_sap_obss_detection_report_event_id] = 22331 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22332 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22333 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22334 event_ids[wmi_obss_color_collision_report_event_id] = 22335 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22336 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22337 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22338 #ifdef WLAN_SUPPORT_TWT 22339 event_ids[wmi_twt_enable_complete_event_id] = 22340 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22341 event_ids[wmi_twt_disable_complete_event_id] = 22342 WMI_TWT_DISABLE_COMPLETE_EVENTID; 22343 event_ids[wmi_twt_add_dialog_complete_event_id] = 22344 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 22345 event_ids[wmi_twt_del_dialog_complete_event_id] = 22346 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 22347 event_ids[wmi_twt_pause_dialog_complete_event_id] = 22348 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 22349 event_ids[wmi_twt_resume_dialog_complete_event_id] = 22350 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 22351 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 22352 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 22353 event_ids[wmi_twt_session_stats_event_id] = 22354 WMI_TWT_SESSION_STATS_EVENTID; 22355 event_ids[wmi_twt_notify_event_id] = 22356 WMI_TWT_NOTIFY_EVENTID; 22357 event_ids[wmi_twt_ack_complete_event_id] = 22358 WMI_TWT_ACK_EVENTID; 22359 #endif 22360 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22361 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22362 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22363 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 22364 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 22365 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 22366 event_ids[wmi_pdev_interop_issues_ap_event_id] = 22367 WMI_PDEV_RAP_INFO_EVENTID; 22368 #endif 22369 #ifdef AST_HKV1_WORKAROUND 22370 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 22371 #endif 22372 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 22373 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 22374 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 22375 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 22376 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 22377 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 22378 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 22379 event_ids[wmi_pdev_cold_boot_cal_event_id] = 22380 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 22381 #ifdef WLAN_MWS_INFO_DEBUGFS 22382 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 22383 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 22384 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 22385 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 22386 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 22387 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 22388 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 22389 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 22390 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 22391 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 22392 #endif 22393 event_ids[wmi_coex_report_antenna_isolation_event_id] = 22394 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 22395 event_ids[wmi_peer_ratecode_list_event_id] = 22396 WMI_PEER_RATECODE_LIST_EVENTID; 22397 event_ids[wmi_chan_rf_characterization_info_event_id] = 22398 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 22399 event_ids[wmi_roam_auth_offload_event_id] = 22400 WMI_ROAM_PREAUTH_START_EVENTID; 22401 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 22402 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 22403 event_ids[wmi_motion_det_base_line_host_eventid] = 22404 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 22405 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 22406 event_ids[wmi_peer_tx_pn_response_event_id] = 22407 WMI_PEER_TX_PN_RESPONSE_EVENTID; 22408 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 22409 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 22410 event_ids[wmi_mgmt_offload_data_event_id] = 22411 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 22412 event_ids[wmi_nan_dmesg_event_id] = 22413 WMI_NAN_DMESG_EVENTID; 22414 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 22415 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 22416 event_ids[wmi_roam_pmkid_request_event_id] = 22417 WMI_ROAM_PMKID_REQUEST_EVENTID; 22418 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 22419 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 22420 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 22421 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 22422 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 22423 #endif 22424 event_ids[wmi_roam_scan_chan_list_id] = 22425 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 22426 event_ids[wmi_muedca_params_config_eventid] = 22427 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 22428 event_ids[wmi_pdev_sscan_fw_param_eventid] = 22429 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 22430 event_ids[wmi_roam_cap_report_event_id] = 22431 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 22432 event_ids[wmi_vdev_bcn_latency_event_id] = 22433 WMI_VDEV_BCN_LATENCY_EVENTID; 22434 event_ids[wmi_vdev_disconnect_event_id] = 22435 WMI_VDEV_DISCONNECT_EVENTID; 22436 event_ids[wmi_peer_create_conf_event_id] = 22437 WMI_PEER_CREATE_CONF_EVENTID; 22438 event_ids[wmi_pdev_cp_fwstats_eventid] = 22439 WMI_CTRL_PATH_STATS_EVENTID; 22440 event_ids[wmi_pdev_halphy_fwstats_eventid] = 22441 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 22442 event_ids[wmi_vdev_send_big_data_p2_eventid] = 22443 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 22444 event_ids[wmi_pdev_get_dpd_status_event_id] = 22445 WMI_PDEV_GET_DPD_STATUS_EVENTID; 22446 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 22447 event_ids[wmi_vdev_smart_monitor_event_id] = 22448 WMI_VDEV_SMART_MONITOR_EVENTID; 22449 #endif 22450 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 22451 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 22452 event_ids[wmi_pdev_set_halphy_cal_event_id] = 22453 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 22454 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 22455 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 22456 #ifdef WLAN_MGMT_RX_REO_SUPPORT 22457 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 22458 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 22459 #endif 22460 populate_tlv_events_id_mlo(event_ids); 22461 event_ids[wmi_roam_frame_event_id] = 22462 WMI_ROAM_FRAME_EVENTID; 22463 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22464 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 22465 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 22466 #endif 22467 #ifdef WLAN_FEATURE_MCC_QUOTA 22468 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 22469 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 22470 #endif 22471 event_ids[wmi_peer_rx_pn_response_event_id] = 22472 WMI_PEER_RX_PN_RESPONSE_EVENTID; 22473 event_ids[wmi_extract_pktlog_decode_info_eventid] = 22474 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 22475 #ifdef QCA_RSSI_DB2DBM 22476 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 22477 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 22478 #endif 22479 #ifdef MULTI_CLIENT_LL_SUPPORT 22480 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 22481 #endif 22482 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22483 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 22484 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 22485 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 22486 WMI_RTT_PASN_PEER_DELETE_EVENTID; 22487 #endif 22488 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22489 event_ids[wmi_get_roam_vendor_control_param_event_id] = 22490 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 22491 #endif 22492 #ifdef WLAN_FEATURE_DBAM_CONFIG 22493 event_ids[wmi_coex_dbam_complete_event_id] = 22494 WMI_COEX_DBAM_COMPLETE_EVENTID; 22495 #endif 22496 event_ids[wmi_spectral_capabilities_eventid] = 22497 WMI_SPECTRAL_CAPABILITIES_EVENTID; 22498 #ifdef WLAN_FEATURE_COAP 22499 event_ids[wmi_wow_coap_buf_info_eventid] = 22500 WMI_WOW_COAP_BUF_INFO_EVENTID; 22501 #endif 22502 #ifdef HEALTH_MON_SUPPORT 22503 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 22504 WMI_HEALTH_MON_INIT_DONE_EVENTID; 22505 #endif /* HEALTH_MON_SUPPORT */ 22506 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 22507 event_ids[wmi_xgap_enable_complete_eventid] = 22508 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 22509 #endif 22510 event_ids[wmi_pdev_set_tgtr2p_table_eventid] = 22511 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID; 22512 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22513 event_ids[wmi_manual_ul_ofdma_trig_feedback_eventid] = 22514 WMI_MANUAL_UL_OFDMA_TRIG_FEEDBACK_EVENTID; 22515 event_ids[wmi_manual_ul_ofdma_trig_rx_peer_userinfo_eventid] = 22516 WMI_MANUAL_UL_OFDMA_TRIG_RX_PEER_USERINFO_EVENTID; 22517 #endif 22518 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22519 event_ids[wmi_vdev_standalone_sound_complete_eventid] = 22520 WMI_VDEV_STANDALONE_SOUND_COMPLETE_EVENTID; 22521 #endif 22522 event_ids[wmi_csa_ie_received_event_id] = WMI_CSA_IE_RECEIVED_EVENTID; 22523 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO) 22524 event_ids[wmi_roam_synch_key_event_id] = WMI_ROAM_SYNCH_KEY_EVENTID; 22525 #endif 22526 #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE 22527 event_ids[wmi_peer_ptqm_migration_response_eventid] = 22528 WMI_MLO_PRIMARY_LINK_PEER_MIGRATION_EVENTID; 22529 #endif 22530 event_ids[wmi_pdev_set_rf_path_resp_eventid] = 22531 WMI_PDEV_SET_RF_PATH_RESP_EVENTID; 22532 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 22533 event_ids[wmi_pdev_enhanced_aoa_phasedelta_eventid] = 22534 WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID; 22535 #endif 22536 #ifdef WLAN_FEATURE_LL_LT_SAP 22537 event_ids[wmi_audio_transport_switch_type_event_id] = 22538 WMI_AUDIO_TRANSPORT_SWITCH_TYPE_EVENTID; 22539 #endif 22540 22541 } 22542 22543 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 22544 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 22545 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22546 { 22547 wmi_service[wmi_service_get_station_in_ll_stats_req] = 22548 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 22549 } 22550 #else 22551 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22552 { 22553 } 22554 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 22555 #else 22556 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22557 { 22558 } 22559 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 22560 22561 #ifdef WLAN_FEATURE_11BE_MLO 22562 static void populate_tlv_service_mlo(uint32_t *wmi_service) 22563 { 22564 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 22565 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 22566 } 22567 #else /* WLAN_FEATURE_11BE_MLO */ 22568 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 22569 { 22570 } 22571 #endif /* WLAN_FEATURE_11BE_MLO */ 22572 22573 /** 22574 * populate_tlv_service() - populates wmi services 22575 * @wmi_service: Pointer to hold wmi_service 22576 * 22577 * Return: None 22578 */ 22579 static void populate_tlv_service(uint32_t *wmi_service) 22580 { 22581 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22582 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22583 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22584 wmi_service[wmi_service_roam_scan_offload] = 22585 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22586 wmi_service[wmi_service_bcn_miss_offload] = 22587 WMI_SERVICE_BCN_MISS_OFFLOAD; 22588 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22589 wmi_service[wmi_service_sta_advanced_pwrsave] = 22590 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22591 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22592 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22593 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22594 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22595 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22596 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22597 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22598 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22599 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22600 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22601 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22602 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22603 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22604 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22605 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22606 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22607 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22608 wmi_service[wmi_service_packet_power_save] = 22609 WMI_SERVICE_PACKET_POWER_SAVE; 22610 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22611 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22612 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22613 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22614 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22615 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22616 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22617 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22618 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22619 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22620 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22621 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22622 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22623 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22624 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22625 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22626 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22627 wmi_service[wmi_service_mcc_bcn_interval_change] = 22628 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22629 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22630 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22631 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22632 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22633 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22634 wmi_service[wmi_service_lte_ant_share_support] = 22635 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22636 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22637 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22638 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22639 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22640 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22641 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22642 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22643 wmi_service[wmi_service_bcn_txrate_override] = 22644 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22645 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22646 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22647 wmi_service[wmi_service_estimate_linkspeed] = 22648 WMI_SERVICE_ESTIMATE_LINKSPEED; 22649 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22650 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22651 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22652 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22653 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22654 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22655 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22656 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22657 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22658 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22659 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22660 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22661 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22662 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22663 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22664 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22665 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22666 wmi_service[wmi_service_sap_auth_offload] = 22667 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22668 wmi_service[wmi_service_dual_band_simultaneous_support] = 22669 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22670 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22671 wmi_service[wmi_service_ap_arpns_offload] = 22672 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22673 wmi_service[wmi_service_per_band_chainmask_support] = 22674 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22675 wmi_service[wmi_service_packet_filter_offload] = 22676 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22677 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22678 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22679 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22680 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 22681 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22682 wmi_service[wmi_service_multiple_vdev_restart] = 22683 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22684 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 22685 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 22686 wmi_service[wmi_service_smart_antenna_sw_support] = 22687 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 22688 wmi_service[wmi_service_smart_antenna_hw_support] = 22689 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 22690 22691 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22692 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22693 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22694 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22695 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22696 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22697 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22698 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22699 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22700 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22701 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22702 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22703 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22704 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22705 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22706 wmi_service[wmi_service_periodic_chan_stat_support] = 22707 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22708 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22709 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22710 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22711 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22712 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22713 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22714 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22715 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22716 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22717 wmi_service[wmi_service_unified_wow_capability] = 22718 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22719 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22720 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22721 wmi_service[wmi_service_sync_delete_cmds] = 22722 WMI_SERVICE_SYNC_DELETE_CMDS; 22723 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22724 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22725 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22726 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22727 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22728 wmi_service[wmi_service_deprecated_replace] = 22729 WMI_SERVICE_DEPRECATED_REPLACE; 22730 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22731 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22732 wmi_service[wmi_service_enhanced_mcast_filter] = 22733 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22734 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22735 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22736 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22737 wmi_service[wmi_service_p2p_listen_offload_support] = 22738 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22739 wmi_service[wmi_service_mark_first_wakeup_packet] = 22740 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22741 wmi_service[wmi_service_multiple_mcast_filter_set] = 22742 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22743 wmi_service[wmi_service_host_managed_rx_reorder] = 22744 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22745 wmi_service[wmi_service_flash_rdwr_support] = 22746 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22747 wmi_service[wmi_service_wlan_stats_report] = 22748 WMI_SERVICE_WLAN_STATS_REPORT; 22749 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22750 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22751 wmi_service[wmi_service_dfs_phyerr_offload] = 22752 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22753 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22754 wmi_service[wmi_service_fw_mem_dump_support] = 22755 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22756 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22757 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22758 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22759 wmi_service[wmi_service_hw_data_filtering] = 22760 WMI_SERVICE_HW_DATA_FILTERING; 22761 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22762 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22763 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22764 wmi_service[wmi_service_extended_nss_support] = 22765 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22766 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22767 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22768 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22769 wmi_service[wmi_service_offchan_data_tid_support] = 22770 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22771 wmi_service[wmi_service_support_dma] = 22772 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22773 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22774 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22775 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22776 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22777 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22778 wmi_service[wmi_service_11k_neighbour_report_support] = 22779 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22780 wmi_service[wmi_service_ap_obss_detection_offload] = 22781 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22782 wmi_service[wmi_service_bss_color_offload] = 22783 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22784 wmi_service[wmi_service_gmac_offload_support] = 22785 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22786 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22787 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22788 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22789 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22790 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22791 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22792 wmi_service[wmi_service_listen_interval_offload_support] = 22793 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22794 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 22795 wmi_service[wmi_service_obss_spatial_reuse] = 22796 WMI_SERVICE_OBSS_SPATIAL_REUSE; 22797 wmi_service[wmi_service_per_vdev_chain_support] = 22798 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 22799 wmi_service[wmi_service_new_htt_msg_format] = 22800 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 22801 wmi_service[wmi_service_peer_unmap_cnf_support] = 22802 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 22803 wmi_service[wmi_service_beacon_reception_stats] = 22804 WMI_SERVICE_BEACON_RECEPTION_STATS; 22805 wmi_service[wmi_service_vdev_latency_config] = 22806 WMI_SERVICE_VDEV_LATENCY_CONFIG; 22807 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 22808 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 22809 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 22810 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 22811 wmi_service[wmi_service_nan_disable_support] = 22812 WMI_SERVICE_NAN_DISABLE_SUPPORT; 22813 wmi_service[wmi_service_sta_plus_sta_support] = 22814 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 22815 wmi_service[wmi_service_hw_db2dbm_support] = 22816 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 22817 wmi_service[wmi_service_wlm_stats_support] = 22818 WMI_SERVICE_WLM_STATS_REQUEST; 22819 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 22820 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 22821 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 22822 wmi_service[wmi_service_cfr_capture_support] = 22823 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 22824 wmi_service[wmi_service_cfr_capture_pdev_id_soc] = 22825 WMI_SERVICE_CFR_CAPTURE_PDEV_ID_SOC; 22826 wmi_service[wmi_service_bcast_twt_support] = 22827 WMI_SERVICE_BROADCAST_TWT; 22828 wmi_service[wmi_service_wpa3_ft_sae_support] = 22829 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 22830 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 22831 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 22832 wmi_service[wmi_service_ft_fils] = 22833 WMI_SERVICE_WPA3_FT_FILS; 22834 wmi_service[wmi_service_adaptive_11r_support] = 22835 WMI_SERVICE_ADAPTIVE_11R_ROAM; 22836 wmi_service[wmi_service_tx_compl_tsf64] = 22837 WMI_SERVICE_TX_COMPL_TSF64; 22838 wmi_service[wmi_service_data_stall_recovery_support] = 22839 WMI_SERVICE_DSM_ROAM_FILTER; 22840 wmi_service[wmi_service_vdev_delete_all_peer] = 22841 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 22842 wmi_service[wmi_service_three_way_coex_config_legacy] = 22843 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 22844 wmi_service[wmi_service_multiple_coex_config_support] = 22845 WMI_SERVICE_MULTIPLE_COEX_CONFIG_SUPPORT; 22846 wmi_service[wmi_service_rx_fse_support] = 22847 WMI_SERVICE_RX_FSE_SUPPORT; 22848 wmi_service[wmi_service_sae_roam_support] = 22849 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 22850 wmi_service[wmi_service_owe_roam_support] = 22851 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 22852 wmi_service[wmi_service_6ghz_support] = 22853 WMI_SERVICE_6GHZ_SUPPORT; 22854 wmi_service[wmi_service_bw_165mhz_support] = 22855 WMI_SERVICE_BW_165MHZ_SUPPORT; 22856 wmi_service[wmi_service_bw_restricted_80p80_support] = 22857 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 22858 wmi_service[wmi_service_packet_capture_support] = 22859 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 22860 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 22861 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 22862 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 22863 wmi_service[wmi_service_multiple_vdev_restart_ext] = 22864 WMI_SERVICE_UNAVAILABLE; 22865 wmi_service[wmi_service_time_sync_ftm] = 22866 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 22867 wmi_service[wmi_service_nss_ratio_to_host_support] = 22868 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 22869 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 22870 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 22871 wmi_service[wmi_beacon_protection_support] = 22872 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 22873 wmi_service[wmi_service_sta_nan_ndi_four_port] = 22874 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 22875 wmi_service[wmi_service_host_scan_stop_vdev_all] = 22876 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 22877 wmi_service[wmi_support_extend_address] = 22878 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 22879 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 22880 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 22881 wmi_service[wmi_service_suiteb_roam_support] = 22882 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 22883 wmi_service[wmi_service_no_interband_mcc_support] = 22884 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 22885 wmi_service[wmi_service_dual_sta_roam_support] = 22886 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 22887 wmi_service[wmi_service_peer_create_conf] = 22888 WMI_SERVICE_PEER_CREATE_CONF; 22889 wmi_service[wmi_service_configure_roam_trigger_param_support] = 22890 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 22891 wmi_service[wmi_service_5dot9_ghz_support] = 22892 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 22893 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 22894 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 22895 wmi_service[wmi_service_cfr_capture_count_support] = 22896 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 22897 wmi_service[wmi_service_ocv_support] = 22898 WMI_SERVICE_OCV_SUPPORT; 22899 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 22900 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 22901 wmi_service[wmi_service_thermal_multi_client_support] = 22902 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 22903 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 22904 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 22905 wmi_service[wmi_service_fse_cmem_alloc_support] = 22906 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 22907 wmi_service[wmi_service_scan_conf_per_ch_support] = 22908 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 22909 wmi_service[wmi_service_csa_beacon_template] = 22910 WMI_SERVICE_CSA_BEACON_TEMPLATE; 22911 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22912 wmi_service[wmi_service_rtt_11az_ntb_support] = 22913 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 22914 wmi_service[wmi_service_rtt_11az_tb_support] = 22915 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 22916 wmi_service[wmi_service_rtt_11az_tb_rsta_support] = 22917 WMI_SERVICE_RTT_11AZ_TB_RSTA_SUPPORT; 22918 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 22919 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 22920 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 22921 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 22922 #endif 22923 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 22924 wmi_service[wmi_service_igmp_offload_support] = 22925 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 22926 #endif 22927 22928 #ifdef FEATURE_WLAN_TDLS 22929 #ifdef WLAN_FEATURE_11AX 22930 wmi_service[wmi_service_tdls_ax_support] = 22931 WMI_SERVICE_11AX_TDLS_SUPPORT; 22932 wmi_service[wmi_service_tdls_6g_support] = 22933 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 22934 #endif 22935 wmi_service[wmi_service_tdls_wideband_support] = 22936 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 22937 wmi_service[wmi_service_tdls_concurrency_support] = 22938 WMI_SERVICE_TDLS_CONCURRENCY_SUPPORT; 22939 #endif 22940 #ifdef FEATURE_WLAN_TDLS 22941 #ifdef WLAN_FEATURE_11BE 22942 wmi_service[wmi_service_tdls_mlo_support] = 22943 WMI_SERVICE_11BE_MLO_TDLS_SUPPORT; 22944 #endif 22945 #endif 22946 #ifdef WLAN_SUPPORT_TWT 22947 wmi_service[wmi_service_twt_bcast_req_support] = 22948 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 22949 wmi_service[wmi_service_twt_bcast_resp_support] = 22950 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 22951 wmi_service[wmi_service_twt_nudge] = 22952 WMI_SERVICE_TWT_NUDGE; 22953 wmi_service[wmi_service_all_twt] = 22954 WMI_SERVICE_TWT_ALL_DIALOG_ID; 22955 wmi_service[wmi_service_twt_statistics] = 22956 WMI_SERVICE_TWT_STATS; 22957 wmi_service[wmi_service_restricted_twt] = WMI_SERVICE_RESTRICTED_TWT; 22958 #endif 22959 wmi_service[wmi_service_spectral_scan_disabled] = 22960 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 22961 wmi_service[wmi_service_sae_eapol_offload_support] = 22962 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 22963 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 22964 22965 wmi_service[wmi_service_wapi_concurrency_supported] = 22966 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 22967 wmi_service[wmi_service_sap_connected_d3_wow] = 22968 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22969 wmi_service[wmi_service_go_connected_d3_wow] = 22970 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22971 wmi_service[wmi_service_ext_tpc_reg_support] = 22972 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 22973 wmi_service[wmi_service_eirp_preferred_support] = 22974 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 22975 wmi_service[wmi_service_ndi_txbf_support] = 22976 WMI_SERVICE_NDI_TXBF_SUPPORT; 22977 wmi_service[wmi_service_reg_cc_ext_event_support] = 22978 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 22979 wmi_service[wmi_service_bang_radar_320_support] = 22980 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 22981 #if defined(CONFIG_BAND_6GHZ) 22982 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 22983 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 22984 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 22985 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 22986 #ifdef CONFIG_AFC_SUPPORT 22987 wmi_service[wmi_service_afc_support] = 22988 WMI_SERVICE_AFC_SUPPORT; 22989 #endif 22990 #endif 22991 wmi_service[wmi_service_dcs_awgn_int_support] = 22992 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 22993 wmi_populate_service_11be(wmi_service); 22994 22995 #ifdef WLAN_FEATURE_BIG_DATA_STATS 22996 wmi_service[wmi_service_big_data_support] = 22997 WMI_SERVICE_BIG_DATA_SUPPORT; 22998 #endif 22999 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 23000 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 23001 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 23002 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 23003 wmi_service[wmi_service_halphy_cal_status] = 23004 WMI_SERVICE_HALPHY_CAL_STATUS; 23005 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 23006 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 23007 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 23008 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 23009 wmi_service[wmi_service_ema_multiple_group_supported] = 23010 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 23011 wmi_service[wmi_service_large_beacon_supported] = 23012 WMI_SERVICE_LARGE_BEACON_SUPPORT; 23013 wmi_service[wmi_service_aoa_for_rcc_supported] = 23014 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 23015 #ifdef WLAN_FEATURE_P2P_P2P_STA 23016 wmi_service[wmi_service_p2p_p2p_cc_support] = 23017 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 23018 #endif 23019 #ifdef THERMAL_STATS_SUPPORT 23020 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 23021 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 23022 #endif 23023 wmi_service[wmi_service_hw_mode_policy_offload_support] = 23024 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 23025 wmi_service[wmi_service_mgmt_rx_reo_supported] = 23026 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 23027 wmi_service[wmi_service_phy_dma_byte_swap_support] = 23028 WMI_SERVICE_UNAVAILABLE; 23029 wmi_service[wmi_service_spectral_session_info_support] = 23030 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 23031 wmi_service[wmi_service_umac_hang_recovery_support] = 23032 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 23033 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 23034 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 23035 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 23036 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 23037 #endif 23038 wmi_service[wmi_service_probe_all_bw_support] = 23039 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 23040 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 23041 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 23042 #ifdef QCA_UNDECODED_METADATA_SUPPORT 23043 wmi_service[wmi_service_fp_phy_err_filter_support] = 23044 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 23045 #endif 23046 populate_tlv_service_mlo(wmi_service); 23047 wmi_service[wmi_service_pdev_rate_config_support] = 23048 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 23049 wmi_service[wmi_service_multi_peer_group_cmd_support] = 23050 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 23051 #ifdef WLAN_FEATURE_11BE 23052 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 23053 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 23054 #endif 23055 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 23056 wmi_service[wmi_service_combined_set_param_support] = 23057 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 23058 #endif 23059 wmi_service[wmi_service_pn_replay_check_support] = 23060 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 23061 #ifdef QCA_RSSI_DB2DBM 23062 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 23063 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 23064 #endif 23065 wmi_service[wmi_service_pktlog_decode_info_support] = 23066 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 23067 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 23068 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 23069 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 23070 #endif 23071 #ifdef MULTI_CLIENT_LL_SUPPORT 23072 wmi_service[wmi_service_configure_multi_client_ll_support] = 23073 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 23074 #endif 23075 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 23076 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 23077 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 23078 #endif 23079 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 23080 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 23081 #ifdef FEATURE_SET 23082 wmi_service[wmi_service_feature_set_event_support] = 23083 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 23084 #endif 23085 #ifdef WLAN_FEATURE_SR 23086 wmi_service[wmi_service_obss_per_packet_sr_support] = 23087 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 23088 #endif 23089 wmi_service[wmi_service_wpa3_sha384_roam_support] = 23090 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 23091 wmi_service[wmi_service_self_mld_roam_between_dbs_and_hbs] = 23092 WMI_SERVICE_SELF_MLD_ROAM_BETWEEN_DBS_AND_HBS; 23093 /* TODO: Assign FW Enum after FW Shared header changes are merged */ 23094 wmi_service[wmi_service_v1a_v1b_supported] = 23095 WMI_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT; 23096 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 23097 wmi_service[wmi_service_manual_ulofdma_trigger_support] = 23098 WMI_SERVICE_MANUAL_ULOFDMA_TRIGGER_SUPPORT; 23099 #endif 23100 wmi_service[wmi_service_pre_rx_timeout] = 23101 WMI_SERVICE_PRE_RX_TO; 23102 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 23103 wmi_service[wmi_service_standalone_sound] = 23104 WMI_SERVICE_STANDALONE_SOUND; 23105 #endif 23106 wmi_service[wmi_service_cca_busy_info_for_each_20mhz] = 23107 WMI_SERVICE_CCA_BUSY_INFO_FOREACH_20MHZ; 23108 wmi_service[wmi_service_vdev_param_chwidth_with_notify_support] = 23109 WMI_SERVICE_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT; 23110 #ifdef WLAN_FEATURE_11BE_MLO 23111 wmi_service[wmi_service_mlo_tsf_sync] = WMI_SERVICE_MLO_TSF_SYNC; 23112 wmi_service[wmi_service_n_link_mlo_support] = 23113 WMI_SERVICE_N_LINK_MLO_SUPPORT; 23114 wmi_service[wmi_service_per_link_stats_support] = 23115 WMI_SERVICE_PER_LINK_STATS_SUPPORT; 23116 wmi_service[wmi_service_pdev_wsi_stats_info_support] = 23117 WMI_SERVICE_PDEV_WSI_STATS_INFO_SUPPORT; 23118 wmi_service[wmi_service_mlo_tid_to_link_mapping_support] = 23119 WMI_SERVICE_MLO_TID_TO_LINK_MAPPING_SUPPORT; 23120 #endif 23121 wmi_service[wmi_service_aux_mac_support] = WMI_SERVICE_AUX_MAC_SUPPORT; 23122 #ifdef WLAN_ATF_INCREASED_STA 23123 wmi_service[wmi_service_atf_max_client_512_support] = 23124 WMI_SERVICE_ATF_MAX_CLIENT_512_SUPPORT; 23125 #endif 23126 wmi_service[wmi_service_fisa_dynamic_msdu_aggr_size_support] = 23127 WMI_SERVICE_FISA_DYNAMIC_MSDU_AGGR_SIZE_SUPPORT; 23128 wmi_service[wmi_service_radar_flags_support] = 23129 WMI_SERVICE_RADAR_FLAGS_SUPPORT; 23130 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 23131 wmi_service[wmi_service_5ghz_hi_rssi_roam_support] = 23132 WMI_SERVICE_5GHZ_HI_RSSI_ROAM_SUPPORT; 23133 #endif 23134 wmi_service[wmi_service_pdev_param_in_utf_wmi] = 23135 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI; 23136 #ifdef WLAN_FEATURE_LL_LT_SAP 23137 wmi_service[wmi_service_xpan_support] = WMI_SERVICE_XPAN_SUPPORT; 23138 #endif 23139 wmi_service[wmi_service_multiple_reorder_queue_setup_support] = 23140 WMI_SERVICE_MULTIPLE_REORDER_QUEUE_SETUP_SUPPORT; 23141 wmi_service[wmi_service_p2p_device_update_mac_addr_support] = 23142 WMI_SERVICE_P2P_DEVICE_UPDATE_MAC_ADDR_SUPPORT; 23143 } 23144 23145 /** 23146 * wmi_ocb_ut_attach() - Attach OCB test framework 23147 * @wmi_handle: wmi handle 23148 * 23149 * Return: None 23150 */ 23151 #ifdef WLAN_OCB_UT 23152 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23153 #else 23154 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23155 { 23156 return; 23157 } 23158 #endif 23159 23160 /** 23161 * wmi_tlv_attach() - Attach TLV APIs 23162 * @wmi_handle: wmi handle 23163 * Return: None 23164 */ 23165 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23166 { 23167 wmi_handle->ops = &tlv_ops; 23168 wmi_ocb_ut_attach(wmi_handle); 23169 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23170 #ifdef WMI_INTERFACE_EVENT_LOGGING 23171 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23172 wmi_handle->soc->buf_offset_command = 8; 23173 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23174 wmi_handle->soc->buf_offset_event = 4; 23175 #endif 23176 populate_tlv_events_id(wmi_handle->wmi_events); 23177 populate_tlv_service(wmi_handle->services); 23178 wmi_wds_attach_tlv(wmi_handle); 23179 wmi_twt_attach_tlv(wmi_handle); 23180 wmi_extscan_attach_tlv(wmi_handle); 23181 wmi_smart_ant_attach_tlv(wmi_handle); 23182 wmi_dbr_attach_tlv(wmi_handle); 23183 wmi_atf_attach_tlv(wmi_handle); 23184 wmi_ap_attach_tlv(wmi_handle); 23185 wmi_bcn_attach_tlv(wmi_handle); 23186 wmi_ocb_attach_tlv(wmi_handle); 23187 wmi_nan_attach_tlv(wmi_handle); 23188 wmi_p2p_attach_tlv(wmi_handle); 23189 wmi_interop_issues_ap_attach_tlv(wmi_handle); 23190 wmi_dcs_attach_tlv(wmi_handle); 23191 wmi_roam_attach_tlv(wmi_handle); 23192 wmi_concurrency_attach_tlv(wmi_handle); 23193 wmi_pmo_attach_tlv(wmi_handle); 23194 wmi_sta_attach_tlv(wmi_handle); 23195 wmi_11ax_bss_color_attach_tlv(wmi_handle); 23196 wmi_fwol_attach_tlv(wmi_handle); 23197 wmi_vdev_attach_tlv(wmi_handle); 23198 wmi_cfr_attach_tlv(wmi_handle); 23199 wmi_cp_stats_attach_tlv(wmi_handle); 23200 wmi_gpio_attach_tlv(wmi_handle); 23201 wmi_11be_attach_tlv(wmi_handle); 23202 wmi_coap_attach_tlv(wmi_handle); 23203 wmi_mlme_attach_tlv(wmi_handle); 23204 } 23205 qdf_export_symbol(wmi_tlv_attach); 23206 23207 /** 23208 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23209 * 23210 * Return: None 23211 */ 23212 void wmi_tlv_init(void) 23213 { 23214 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23215 } 23216