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->flags = probe_rsp_info->go_ignore_non_p2p_probe_req; 5942 5943 cmd->buf_len = tmpl_len; 5944 buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); 5945 5946 bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr; 5947 WMITLV_SET_HDR(&bcn_prb_info->tlv_header, 5948 WMITLV_TAG_STRUC_wmi_bcn_prb_info, 5949 WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); 5950 bcn_prb_info->caps = 0; 5951 bcn_prb_info->erp = 0; 5952 buf_ptr += sizeof(wmi_bcn_prb_info); 5953 5954 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); 5955 buf_ptr += WMI_TLV_HDR_SIZE; 5956 qdf_mem_copy(buf_ptr, probe_rsp_info->prb_rsp_template_frm, tmpl_len); 5957 buf_ptr += tmpl_len_aligned; 5958 buf_ptr = prb_resp_tmpl_add_ml_info(buf_ptr, probe_rsp_info); 5959 5960 wmi_mtrace(WMI_PRB_TMPL_CMDID, cmd->vdev_id, 0); 5961 ret = wmi_unified_cmd_send(wmi_handle, 5962 wmi_buf, wmi_buf_len, WMI_PRB_TMPL_CMDID); 5963 if (QDF_IS_STATUS_ERROR(ret)) { 5964 wmi_err("Failed to send PRB RSP tmpl: %d", ret); 5965 wmi_buf_free(wmi_buf); 5966 } 5967 5968 return ret; 5969 } 5970 5971 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 5972 #define WPI_IV_LEN 16 5973 5974 /** 5975 * wmi_update_wpi_key_counter() - update WAPI tsc and rsc key counters 5976 * 5977 * @dest_tx: destination address of tsc key counter 5978 * @src_tx: source address of tsc key counter 5979 * @dest_rx: destination address of rsc key counter 5980 * @src_rx: source address of rsc key counter 5981 * 5982 * This function copies WAPI tsc and rsc key counters in the wmi buffer. 5983 * 5984 * Return: None 5985 * 5986 */ 5987 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5988 uint8_t *dest_rx, uint8_t *src_rx) 5989 { 5990 qdf_mem_copy(dest_tx, src_tx, WPI_IV_LEN); 5991 qdf_mem_copy(dest_rx, src_rx, WPI_IV_LEN); 5992 } 5993 #else 5994 static void wmi_update_wpi_key_counter(uint8_t *dest_tx, uint8_t *src_tx, 5995 uint8_t *dest_rx, uint8_t *src_rx) 5996 { 5997 return; 5998 } 5999 #endif 6000 6001 /** 6002 * send_setup_install_key_cmd_tlv() - set key parameters 6003 * @wmi_handle: wmi handle 6004 * @key_params: key parameters 6005 * 6006 * This function fills structure from information 6007 * passed in key_params. 6008 * 6009 * Return: QDF_STATUS_SUCCESS - success 6010 * QDF_STATUS_E_FAILURE - failure 6011 * QDF_STATUS_E_NOMEM - not able to allocate buffer 6012 */ 6013 static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle, 6014 struct set_key_params *key_params) 6015 { 6016 wmi_vdev_install_key_cmd_fixed_param *cmd; 6017 wmi_buf_t buf; 6018 uint8_t *buf_ptr; 6019 uint32_t len; 6020 uint8_t *key_data; 6021 QDF_STATUS status; 6022 6023 len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(uint32_t)) + 6024 WMI_TLV_HDR_SIZE; 6025 6026 buf = wmi_buf_alloc(wmi_handle, len); 6027 if (!buf) 6028 return QDF_STATUS_E_NOMEM; 6029 6030 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6031 cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; 6032 WMITLV_SET_HDR(&cmd->tlv_header, 6033 WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, 6034 WMITLV_GET_STRUCT_TLVLEN 6035 (wmi_vdev_install_key_cmd_fixed_param)); 6036 cmd->vdev_id = key_params->vdev_id; 6037 cmd->key_ix = key_params->key_idx; 6038 if (key_params->group_key_idx) { 6039 cmd->is_group_key_ix_valid = 1; 6040 cmd->group_key_ix = key_params->group_key_idx; 6041 } 6042 6043 WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, &cmd->peer_macaddr); 6044 cmd->key_flags |= key_params->key_flags; 6045 cmd->key_cipher = key_params->key_cipher; 6046 if ((key_params->key_txmic_len) && 6047 (key_params->key_rxmic_len)) { 6048 cmd->key_txmic_len = key_params->key_txmic_len; 6049 cmd->key_rxmic_len = key_params->key_rxmic_len; 6050 } 6051 #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) 6052 wmi_update_wpi_key_counter(cmd->wpi_key_tsc_counter, 6053 key_params->tx_iv, 6054 cmd->wpi_key_rsc_counter, 6055 key_params->rx_iv); 6056 #endif 6057 buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); 6058 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 6059 roundup(key_params->key_len, sizeof(uint32_t))); 6060 key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 6061 6062 /* for big endian host, copy engine byte_swap is enabled 6063 * But key_data is in network byte order 6064 * Need to byte swap the key_data - so when copy engine 6065 * does byte_swap - target gets key_data in the correct order 6066 */ 6067 WMI_HOST_IF_MSG_COPY_CHAR_ARRAY((void *)key_data, 6068 (const void *)key_params->key_data, 6069 key_params->key_len); 6070 qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_counter, 6071 sizeof(wmi_key_seq_counter)); 6072 cmd->key_len = key_params->key_len; 6073 6074 qdf_mem_copy(&cmd->key_tsc_counter, &key_params->key_tsc_counter, 6075 sizeof(wmi_key_seq_counter)); 6076 wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); 6077 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6078 WMI_VDEV_INSTALL_KEY_CMDID); 6079 if (QDF_IS_STATUS_ERROR(status)) { 6080 qdf_mem_zero(wmi_buf_data(buf), len); 6081 wmi_buf_free(buf); 6082 } 6083 return status; 6084 } 6085 6086 /** 6087 * send_p2p_go_set_beacon_ie_cmd_tlv() - set beacon IE for p2p go 6088 * @wmi_handle: wmi handle 6089 * @vdev_id: vdev id 6090 * @p2p_ie: p2p IE 6091 * 6092 * Return: QDF_STATUS_SUCCESS for success or error code 6093 */ 6094 static QDF_STATUS send_p2p_go_set_beacon_ie_cmd_tlv(wmi_unified_t wmi_handle, 6095 uint32_t vdev_id, uint8_t *p2p_ie) 6096 { 6097 QDF_STATUS ret; 6098 wmi_p2p_go_set_beacon_ie_fixed_param *cmd; 6099 wmi_buf_t wmi_buf; 6100 uint32_t ie_len, ie_len_aligned, wmi_buf_len; 6101 uint8_t *buf_ptr; 6102 6103 ie_len = (uint32_t) (p2p_ie[1] + 2); 6104 6105 /* More than one P2P IE may be included in a single frame. 6106 If multiple P2P IEs are present, the complete P2P attribute 6107 data consists of the concatenation of the P2P Attribute 6108 fields of the P2P IEs. The P2P Attributes field of each 6109 P2P IE may be any length up to the maximum (251 octets). 6110 In this case host sends one P2P IE to firmware so the length 6111 should not exceed more than 251 bytes 6112 */ 6113 if (ie_len > 251) { 6114 wmi_err("Invalid p2p ie length %u", ie_len); 6115 return QDF_STATUS_E_INVAL; 6116 } 6117 6118 ie_len_aligned = roundup(ie_len, sizeof(uint32_t)); 6119 6120 wmi_buf_len = 6121 sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + 6122 WMI_TLV_HDR_SIZE; 6123 6124 wmi_buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 6125 if (!wmi_buf) 6126 return QDF_STATUS_E_NOMEM; 6127 6128 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6129 6130 cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *) buf_ptr; 6131 WMITLV_SET_HDR(&cmd->tlv_header, 6132 WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, 6133 WMITLV_GET_STRUCT_TLVLEN 6134 (wmi_p2p_go_set_beacon_ie_fixed_param)); 6135 cmd->vdev_id = vdev_id; 6136 cmd->ie_buf_len = ie_len; 6137 6138 buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); 6139 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); 6140 buf_ptr += WMI_TLV_HDR_SIZE; 6141 qdf_mem_copy(buf_ptr, p2p_ie, ie_len); 6142 6143 wmi_debug("Sending WMI_P2P_GO_SET_BEACON_IE"); 6144 6145 wmi_mtrace(WMI_P2P_GO_SET_BEACON_IE, cmd->vdev_id, 0); 6146 ret = wmi_unified_cmd_send(wmi_handle, 6147 wmi_buf, wmi_buf_len, 6148 WMI_P2P_GO_SET_BEACON_IE); 6149 if (QDF_IS_STATUS_ERROR(ret)) { 6150 wmi_err("Failed to send bcn tmpl: %d", ret); 6151 wmi_buf_free(wmi_buf); 6152 } 6153 6154 wmi_debug("Successfully sent WMI_P2P_GO_SET_BEACON_IE"); 6155 return ret; 6156 } 6157 6158 /** 6159 * send_scan_probe_setoui_cmd_tlv() - set scan probe OUI 6160 * @wmi_handle: wmi handle 6161 * @psetoui: OUI parameters 6162 * 6163 * set scan probe OUI parameters in firmware 6164 * 6165 * Return: QDF status 6166 */ 6167 static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, 6168 struct scan_mac_oui *psetoui) 6169 { 6170 wmi_scan_prob_req_oui_cmd_fixed_param *cmd; 6171 wmi_buf_t wmi_buf; 6172 uint32_t len; 6173 uint8_t *buf_ptr; 6174 uint32_t *oui_buf; 6175 struct probe_req_allowlist_attr *ie_allowlist = &psetoui->ie_allowlist; 6176 6177 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 6178 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui); 6179 6180 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6181 if (!wmi_buf) 6182 return QDF_STATUS_E_NOMEM; 6183 6184 buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf); 6185 cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *) buf_ptr; 6186 WMITLV_SET_HDR(&cmd->tlv_header, 6187 WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, 6188 WMITLV_GET_STRUCT_TLVLEN 6189 (wmi_scan_prob_req_oui_cmd_fixed_param)); 6190 6191 oui_buf = &cmd->prob_req_oui; 6192 qdf_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); 6193 *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 6194 | psetoui->oui[2]; 6195 wmi_debug("wmi:oui received from hdd %08x", cmd->prob_req_oui); 6196 6197 cmd->vdev_id = psetoui->vdev_id; 6198 cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; 6199 if (psetoui->enb_probe_req_sno_randomization) 6200 cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; 6201 6202 if (ie_allowlist->allow_list) { 6203 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6204 &cmd->num_vendor_oui, 6205 ie_allowlist); 6206 cmd->flags |= 6207 WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6208 } 6209 6210 buf_ptr += sizeof(*cmd); 6211 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6212 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6213 buf_ptr += WMI_TLV_HDR_SIZE; 6214 6215 if (cmd->num_vendor_oui != 0) { 6216 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6217 ie_allowlist->voui); 6218 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6219 } 6220 6221 wmi_mtrace(WMI_SCAN_PROB_REQ_OUI_CMDID, cmd->vdev_id, 0); 6222 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6223 WMI_SCAN_PROB_REQ_OUI_CMDID)) { 6224 wmi_err("Failed to send command WMI_SCAN_PROB_REQ_OUI_CMDID"); 6225 wmi_buf_free(wmi_buf); 6226 return QDF_STATUS_E_FAILURE; 6227 } 6228 return QDF_STATUS_SUCCESS; 6229 } 6230 6231 #ifdef IPA_OFFLOAD 6232 /** send_ipa_offload_control_cmd_tlv() - ipa offload control parameter 6233 * @wmi_handle: wmi handle 6234 * @ipa_offload: ipa offload control parameter 6235 * 6236 * Returns: 0 on success, error number otherwise 6237 */ 6238 static QDF_STATUS send_ipa_offload_control_cmd_tlv(wmi_unified_t wmi_handle, 6239 struct ipa_uc_offload_control_params *ipa_offload) 6240 { 6241 wmi_ipa_offload_enable_disable_cmd_fixed_param *cmd; 6242 wmi_buf_t wmi_buf; 6243 uint32_t len; 6244 u_int8_t *buf_ptr; 6245 6246 len = sizeof(*cmd); 6247 wmi_buf = wmi_buf_alloc(wmi_handle, len); 6248 if (!wmi_buf) 6249 return QDF_STATUS_E_NOMEM; 6250 6251 wmi_debug("offload_type=%d, enable=%d", 6252 ipa_offload->offload_type, ipa_offload->enable); 6253 6254 buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); 6255 6256 cmd = (wmi_ipa_offload_enable_disable_cmd_fixed_param *)buf_ptr; 6257 WMITLV_SET_HDR(&cmd->tlv_header, 6258 WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, 6259 WMITLV_GET_STRUCT_TLVLEN( 6260 wmi_ipa_offload_enable_disable_cmd_fixed_param)); 6261 6262 cmd->offload_type = ipa_offload->offload_type; 6263 cmd->vdev_id = ipa_offload->vdev_id; 6264 cmd->enable = ipa_offload->enable; 6265 6266 wmi_mtrace(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID, cmd->vdev_id, 0); 6267 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 6268 WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)) { 6269 wmi_err("Failed to send WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID"); 6270 wmi_buf_free(wmi_buf); 6271 return QDF_STATUS_E_FAILURE; 6272 } 6273 6274 return QDF_STATUS_SUCCESS; 6275 } 6276 #endif 6277 6278 /** 6279 * send_pno_stop_cmd_tlv() - PNO stop request 6280 * @wmi_handle: wmi handle 6281 * @vdev_id: vdev id 6282 * 6283 * This function request FW to stop ongoing PNO operation. 6284 * 6285 * Return: QDF status 6286 */ 6287 static QDF_STATUS send_pno_stop_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 6288 { 6289 wmi_nlo_config_cmd_fixed_param *cmd; 6290 int32_t len = sizeof(*cmd); 6291 wmi_buf_t buf; 6292 uint8_t *buf_ptr; 6293 int ret; 6294 6295 /* 6296 * TLV place holder for array of structures nlo_configured_parameters 6297 * TLV place holder for array of uint32_t channel_list 6298 * TLV place holder for chnl prediction cfg 6299 */ 6300 len += WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6301 buf = wmi_buf_alloc(wmi_handle, len); 6302 if (!buf) 6303 return QDF_STATUS_E_NOMEM; 6304 6305 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6306 buf_ptr = (uint8_t *) cmd; 6307 6308 WMITLV_SET_HDR(&cmd->tlv_header, 6309 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6310 WMITLV_GET_STRUCT_TLVLEN 6311 (wmi_nlo_config_cmd_fixed_param)); 6312 6313 cmd->vdev_id = vdev_id; 6314 cmd->flags = WMI_NLO_CONFIG_STOP; 6315 buf_ptr += sizeof(*cmd); 6316 6317 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6318 buf_ptr += WMI_TLV_HDR_SIZE; 6319 6320 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); 6321 buf_ptr += WMI_TLV_HDR_SIZE; 6322 6323 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 6324 buf_ptr += WMI_TLV_HDR_SIZE; 6325 6326 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6327 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6328 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6329 if (ret) { 6330 wmi_err("Failed to send nlo wmi cmd"); 6331 wmi_buf_free(buf); 6332 return QDF_STATUS_E_FAILURE; 6333 } 6334 6335 return QDF_STATUS_SUCCESS; 6336 } 6337 6338 /** 6339 * send_obss_disable_cmd_tlv() - disable obss scan request 6340 * @wmi_handle: wmi handle 6341 * @vdev_id: vdev id 6342 * 6343 * This function request FW to disable ongoing obss scan operation. 6344 * 6345 * Return: QDF status 6346 */ 6347 static QDF_STATUS send_obss_disable_cmd_tlv(wmi_unified_t wmi_handle, 6348 uint8_t vdev_id) 6349 { 6350 QDF_STATUS status; 6351 wmi_buf_t buf; 6352 wmi_obss_scan_disable_cmd_fixed_param *cmd; 6353 int len = sizeof(*cmd); 6354 6355 buf = wmi_buf_alloc(wmi_handle, len); 6356 if (!buf) 6357 return QDF_STATUS_E_NOMEM; 6358 6359 wmi_debug("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); 6360 6361 cmd = (wmi_obss_scan_disable_cmd_fixed_param *)wmi_buf_data(buf); 6362 WMITLV_SET_HDR(&cmd->tlv_header, 6363 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, 6364 WMITLV_GET_STRUCT_TLVLEN( 6365 wmi_obss_scan_disable_cmd_fixed_param)); 6366 6367 cmd->vdev_id = vdev_id; 6368 status = wmi_unified_cmd_send(wmi_handle, buf, len, 6369 WMI_OBSS_SCAN_DISABLE_CMDID); 6370 if (QDF_IS_STATUS_ERROR(status)) 6371 wmi_buf_free(buf); 6372 6373 return status; 6374 } 6375 6376 /** 6377 * wmi_set_pno_channel_prediction() - Set PNO channel prediction 6378 * @buf_ptr: Buffer passed by upper layers 6379 * @pno: Buffer to be sent to the firmware 6380 * 6381 * Copy the PNO Channel prediction configuration parameters 6382 * passed by the upper layers to a WMI format TLV and send it 6383 * down to the firmware. 6384 * 6385 * Return: None 6386 */ 6387 static void wmi_set_pno_channel_prediction(uint8_t *buf_ptr, 6388 struct pno_scan_req_params *pno) 6389 { 6390 nlo_channel_prediction_cfg *channel_prediction_cfg = 6391 (nlo_channel_prediction_cfg *) buf_ptr; 6392 WMITLV_SET_HDR(&channel_prediction_cfg->tlv_header, 6393 WMITLV_TAG_ARRAY_BYTE, 6394 WMITLV_GET_STRUCT_TLVLEN(nlo_channel_prediction_cfg)); 6395 #ifdef FEATURE_WLAN_SCAN_PNO 6396 channel_prediction_cfg->enable = pno->pno_channel_prediction; 6397 channel_prediction_cfg->top_k_num = pno->top_k_num_of_channels; 6398 channel_prediction_cfg->stationary_threshold = pno->stationary_thresh; 6399 channel_prediction_cfg->full_scan_period_ms = 6400 pno->channel_prediction_full_scan; 6401 #endif 6402 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6403 wmi_debug("enable: %d, top_k_num: %d, stat_thresh: %d, full_scan: %d", 6404 channel_prediction_cfg->enable, 6405 channel_prediction_cfg->top_k_num, 6406 channel_prediction_cfg->stationary_threshold, 6407 channel_prediction_cfg->full_scan_period_ms); 6408 } 6409 6410 /** 6411 * send_cp_stats_cmd_tlv() - Send cp stats wmi command 6412 * @wmi_handle: wmi handle 6413 * @buf_ptr: Buffer passed by upper layers 6414 * @buf_len: Length of passed buffer by upper layer 6415 * 6416 * Copy the buffer passed by the upper layers and send it 6417 * down to the firmware. 6418 * 6419 * Return: None 6420 */ 6421 static QDF_STATUS send_cp_stats_cmd_tlv(wmi_unified_t wmi_handle, 6422 void *buf_ptr, uint32_t buf_len) 6423 { 6424 wmi_buf_t buf = NULL; 6425 QDF_STATUS status; 6426 int len; 6427 uint8_t *data_ptr; 6428 6429 len = buf_len; 6430 buf = wmi_buf_alloc(wmi_handle, len); 6431 if (!buf) 6432 return QDF_STATUS_E_NOMEM; 6433 6434 data_ptr = (uint8_t *)wmi_buf_data(buf); 6435 qdf_mem_copy(data_ptr, buf_ptr, len); 6436 6437 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6438 status = wmi_unified_cmd_send(wmi_handle, buf, 6439 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 6440 6441 if (QDF_IS_STATUS_ERROR(status)) { 6442 wmi_buf_free(buf); 6443 return QDF_STATUS_E_FAILURE; 6444 } 6445 return QDF_STATUS_SUCCESS; 6446 } 6447 6448 /** 6449 * send_halphy_stats_cmd_tlv() - Send halphy stats wmi command 6450 * @wmi_handle: wmi handle 6451 * @buf_ptr: Buffer passed by upper layers 6452 * @buf_len: Length of passed buffer by upper layer 6453 * 6454 * Copy the buffer passed by the upper layers and send it 6455 * down to the firmware. 6456 * 6457 * Return: None 6458 */ 6459 static QDF_STATUS send_halphy_stats_cmd_tlv(wmi_unified_t wmi_handle, 6460 void *buf_ptr, uint32_t buf_len) 6461 { 6462 wmi_buf_t buf = NULL; 6463 QDF_STATUS status; 6464 int len; 6465 uint8_t *data_ptr; 6466 6467 len = buf_len; 6468 buf = wmi_buf_alloc(wmi_handle, len); 6469 if (!buf) 6470 return QDF_STATUS_E_NOMEM; 6471 6472 data_ptr = (uint8_t *)wmi_buf_data(buf); 6473 qdf_mem_copy(data_ptr, buf_ptr, len); 6474 6475 wmi_mtrace(WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 6476 status = wmi_unified_cmd_send(wmi_handle, buf, 6477 len, 6478 WMI_REQUEST_HALPHY_CTRL_PATH_STATS_CMDID); 6479 6480 if (QDF_IS_STATUS_ERROR(status)) { 6481 wmi_buf_free(buf); 6482 return QDF_STATUS_E_FAILURE; 6483 } 6484 return QDF_STATUS_SUCCESS; 6485 } 6486 6487 /** 6488 * extract_cp_stats_more_pending_tlv - api to extract more flag from event data 6489 * @wmi_handle: wmi handle 6490 * @evt_buf: event buffer 6491 * @more_flag: buffer to populate more flag 6492 * 6493 * Return: status of operation 6494 */ 6495 static QDF_STATUS 6496 extract_cp_stats_more_pending_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6497 uint32_t *more_flag) 6498 { 6499 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6500 wmi_ctrl_path_stats_event_fixed_param *ev; 6501 6502 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6503 if (!param_buf) { 6504 wmi_err_rl("param_buf is NULL"); 6505 return QDF_STATUS_E_FAILURE; 6506 } 6507 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 6508 6509 *more_flag = ev->more; 6510 return QDF_STATUS_SUCCESS; 6511 } 6512 6513 /** 6514 * extract_halphy_stats_end_of_event_tlv - api to extract end_of_event flag 6515 * from event data 6516 * @wmi_handle: wmi handle 6517 * @evt_buf: event buffer 6518 * @end_of_event_flag: buffer to populate end_of_event flag 6519 * 6520 * Return: status of operation 6521 */ 6522 static QDF_STATUS 6523 extract_halphy_stats_end_of_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6524 uint32_t *end_of_event_flag) 6525 { 6526 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6527 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6528 6529 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6530 if (!param_buf) { 6531 wmi_err_rl("param_buf is NULL"); 6532 return QDF_STATUS_E_FAILURE; 6533 } 6534 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6535 param_buf->fixed_param; 6536 6537 *end_of_event_flag = ev->end_of_event; 6538 return QDF_STATUS_SUCCESS; 6539 } 6540 6541 /** 6542 * extract_halphy_stats_event_count_tlv() - api to extract event count flag 6543 * from event data 6544 * @wmi_handle: wmi handle 6545 * @evt_buf: event buffer 6546 * @event_count_flag: buffer to populate event_count flag 6547 * 6548 * Return: status of operation 6549 */ 6550 static QDF_STATUS 6551 extract_halphy_stats_event_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 6552 uint32_t *event_count_flag) 6553 { 6554 WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 6555 wmi_halphy_ctrl_path_stats_event_fixed_param *ev; 6556 6557 param_buf = (WMI_HALPHY_CTRL_PATH_STATS_EVENTID_param_tlvs *)evt_buf; 6558 if (!param_buf) { 6559 wmi_err_rl("param_buf is NULL"); 6560 return QDF_STATUS_E_FAILURE; 6561 } 6562 ev = (wmi_halphy_ctrl_path_stats_event_fixed_param *) 6563 param_buf->fixed_param; 6564 6565 *event_count_flag = ev->event_count; 6566 return QDF_STATUS_SUCCESS; 6567 } 6568 6569 /** 6570 * send_nlo_mawc_cmd_tlv() - Send MAWC NLO configuration 6571 * @wmi_handle: wmi handle 6572 * @params: configuration parameters 6573 * 6574 * Return: QDF_STATUS 6575 */ 6576 static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, 6577 struct nlo_mawc_params *params) 6578 { 6579 wmi_buf_t buf = NULL; 6580 QDF_STATUS status; 6581 int len; 6582 uint8_t *buf_ptr; 6583 wmi_nlo_configure_mawc_cmd_fixed_param *wmi_nlo_mawc_params; 6584 6585 len = sizeof(*wmi_nlo_mawc_params); 6586 buf = wmi_buf_alloc(wmi_handle, len); 6587 if (!buf) 6588 return QDF_STATUS_E_NOMEM; 6589 6590 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6591 wmi_nlo_mawc_params = 6592 (wmi_nlo_configure_mawc_cmd_fixed_param *) buf_ptr; 6593 WMITLV_SET_HDR(&wmi_nlo_mawc_params->tlv_header, 6594 WMITLV_TAG_STRUC_wmi_nlo_configure_mawc_cmd_fixed_param, 6595 WMITLV_GET_STRUCT_TLVLEN 6596 (wmi_nlo_configure_mawc_cmd_fixed_param)); 6597 wmi_nlo_mawc_params->vdev_id = params->vdev_id; 6598 if (params->enable) 6599 wmi_nlo_mawc_params->enable = 1; 6600 else 6601 wmi_nlo_mawc_params->enable = 0; 6602 wmi_nlo_mawc_params->exp_backoff_ratio = params->exp_backoff_ratio; 6603 wmi_nlo_mawc_params->init_scan_interval = params->init_scan_interval; 6604 wmi_nlo_mawc_params->max_scan_interval = params->max_scan_interval; 6605 wmi_debug("MAWC NLO en=%d, vdev=%d, ratio=%d, SCAN init=%d, max=%d", 6606 wmi_nlo_mawc_params->enable, wmi_nlo_mawc_params->vdev_id, 6607 wmi_nlo_mawc_params->exp_backoff_ratio, 6608 wmi_nlo_mawc_params->init_scan_interval, 6609 wmi_nlo_mawc_params->max_scan_interval); 6610 6611 wmi_mtrace(WMI_NLO_CONFIGURE_MAWC_CMDID, NO_SESSION, 0); 6612 status = wmi_unified_cmd_send(wmi_handle, buf, 6613 len, WMI_NLO_CONFIGURE_MAWC_CMDID); 6614 if (QDF_IS_STATUS_ERROR(status)) { 6615 wmi_err("WMI_NLO_CONFIGURE_MAWC_CMDID failed, Error %d", 6616 status); 6617 wmi_buf_free(buf); 6618 return QDF_STATUS_E_FAILURE; 6619 } 6620 6621 return QDF_STATUS_SUCCESS; 6622 } 6623 6624 /** 6625 * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno 6626 * scan 6627 * @scan_freq_list: frequency list for pno scan 6628 * 6629 * Return: void 6630 */ 6631 static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) 6632 { 6633 uint32_t i; 6634 uint8_t info[WMI_MAX_CHAN_INFO_LOG]; 6635 uint32_t len = 0; 6636 struct chan_info *chan_info; 6637 int ret; 6638 6639 wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); 6640 for (i = 0; i < scan_freq_list->num_chan; i++) { 6641 chan_info = &scan_freq_list->chan[i]; 6642 ret = qdf_scnprintf(info + len, sizeof(info) - len, 6643 " %d[%d]", chan_info->freq, 6644 chan_info->flags); 6645 if (ret <= 0) 6646 break; 6647 len += ret; 6648 if (len >= (sizeof(info) - 20)) { 6649 wmi_nofl_debug("Freq[flag]:%s", 6650 info); 6651 len = 0; 6652 } 6653 } 6654 if (len) 6655 wmi_nofl_debug("Freq[flag]:%s", info); 6656 } 6657 6658 /** 6659 * send_pno_start_cmd_tlv() - PNO start request 6660 * @wmi_handle: wmi handle 6661 * @pno: PNO request 6662 * 6663 * This function request FW to start PNO request. 6664 * Request: QDF status 6665 */ 6666 static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, 6667 struct pno_scan_req_params *pno) 6668 { 6669 wmi_nlo_config_cmd_fixed_param *cmd; 6670 nlo_configured_parameters *nlo_list; 6671 uint32_t *channel_list; 6672 int32_t len; 6673 qdf_freq_t freq; 6674 wmi_buf_t buf; 6675 uint8_t *buf_ptr; 6676 uint8_t i; 6677 int ret; 6678 struct probe_req_allowlist_attr *ie_allowlist = &pno->ie_allowlist; 6679 connected_nlo_rssi_params *nlo_relative_rssi; 6680 connected_nlo_bss_band_rssi_pref *nlo_band_rssi; 6681 6682 /* 6683 * TLV place holder for array nlo_configured_parameters(nlo_list) 6684 * TLV place holder for array of uint32_t channel_list 6685 * TLV place holder for chnnl prediction cfg 6686 * TLV place holder for array of wmi_vendor_oui 6687 * TLV place holder for array of connected_nlo_bss_band_rssi_pref 6688 */ 6689 len = sizeof(*cmd) + 6690 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + 6691 WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; 6692 6693 len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; 6694 len += sizeof(nlo_configured_parameters) * 6695 QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6696 len += sizeof(nlo_channel_prediction_cfg); 6697 len += sizeof(enlo_candidate_score_params); 6698 len += sizeof(wmi_vendor_oui) * ie_allowlist->num_vendor_oui; 6699 len += sizeof(connected_nlo_rssi_params); 6700 len += sizeof(connected_nlo_bss_band_rssi_pref); 6701 6702 buf = wmi_buf_alloc(wmi_handle, len); 6703 if (!buf) 6704 return QDF_STATUS_E_NOMEM; 6705 6706 cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); 6707 6708 buf_ptr = (uint8_t *) cmd; 6709 WMITLV_SET_HDR(&cmd->tlv_header, 6710 WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, 6711 WMITLV_GET_STRUCT_TLVLEN 6712 (wmi_nlo_config_cmd_fixed_param)); 6713 cmd->vdev_id = pno->vdev_id; 6714 cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; 6715 6716 #ifdef FEATURE_WLAN_SCAN_PNO 6717 WMI_SCAN_SET_DWELL_MODE(cmd->flags, 6718 pno->adaptive_dwell_mode); 6719 #endif 6720 /* Current FW does not support min-max range for dwell time */ 6721 cmd->active_dwell_time = pno->active_dwell_time; 6722 cmd->passive_dwell_time = pno->passive_dwell_time; 6723 6724 if (pno->do_passive_scan) 6725 cmd->flags |= WMI_NLO_CONFIG_SCAN_PASSIVE; 6726 /* Copy scan interval */ 6727 cmd->fast_scan_period = pno->fast_scan_period; 6728 cmd->slow_scan_period = pno->slow_scan_period; 6729 cmd->delay_start_time = WMI_SEC_TO_MSEC(pno->delay_start_time); 6730 cmd->fast_scan_max_cycles = pno->fast_scan_max_cycles; 6731 cmd->scan_backoff_multiplier = pno->scan_backoff_multiplier; 6732 6733 /* mac randomization attributes */ 6734 if (pno->scan_random.randomize) { 6735 cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | 6736 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; 6737 wmi_copy_scan_random_mac(pno->scan_random.mac_addr, 6738 pno->scan_random.mac_mask, 6739 &cmd->mac_addr, 6740 &cmd->mac_mask); 6741 } 6742 6743 buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); 6744 6745 cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); 6746 6747 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6748 cmd->no_of_ssids * sizeof(nlo_configured_parameters)); 6749 buf_ptr += WMI_TLV_HDR_SIZE; 6750 6751 nlo_list = (nlo_configured_parameters *) buf_ptr; 6752 for (i = 0; i < cmd->no_of_ssids; i++) { 6753 WMITLV_SET_HDR(&nlo_list[i].tlv_header, 6754 WMITLV_TAG_ARRAY_BYTE, 6755 WMITLV_GET_STRUCT_TLVLEN 6756 (nlo_configured_parameters)); 6757 /* Copy ssid and it's length */ 6758 nlo_list[i].ssid.valid = true; 6759 nlo_list[i].ssid.ssid.ssid_len = 6760 pno->networks_list[i].ssid.length; 6761 qdf_mem_copy(nlo_list[i].ssid.ssid.ssid, 6762 pno->networks_list[i].ssid.ssid, 6763 nlo_list[i].ssid.ssid.ssid_len); 6764 6765 /* Copy rssi threshold */ 6766 if (pno->networks_list[i].rssi_thresh && 6767 pno->networks_list[i].rssi_thresh > 6768 WMI_RSSI_THOLD_DEFAULT) { 6769 nlo_list[i].rssi_cond.valid = true; 6770 nlo_list[i].rssi_cond.rssi = 6771 pno->networks_list[i].rssi_thresh; 6772 } 6773 nlo_list[i].bcast_nw_type.valid = true; 6774 nlo_list[i].bcast_nw_type.bcast_nw_type = 6775 pno->networks_list[i].bc_new_type; 6776 } 6777 buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); 6778 6779 /* Copy channel info */ 6780 cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; 6781 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 6782 (cmd->num_of_channels * sizeof(uint32_t))); 6783 buf_ptr += WMI_TLV_HDR_SIZE; 6784 6785 channel_list = (uint32_t *) buf_ptr; 6786 for (i = 0; i < cmd->num_of_channels; i++) { 6787 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6788 pno->networks_list[0].pno_chan_list.chan[i].freq); 6789 6790 if (channel_list[i] < WMI_NLO_FREQ_THRESH) { 6791 freq = pno->networks_list[0].pno_chan_list.chan[i].freq; 6792 TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], 6793 wlan_chan_to_freq(freq)); 6794 } 6795 6796 TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], 6797 pno->networks_list[0].pno_chan_list.chan[i].flags); 6798 } 6799 6800 wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); 6801 6802 buf_ptr += cmd->num_of_channels * sizeof(uint32_t); 6803 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6804 sizeof(nlo_channel_prediction_cfg)); 6805 buf_ptr += WMI_TLV_HDR_SIZE; 6806 wmi_set_pno_channel_prediction(buf_ptr, pno); 6807 buf_ptr += sizeof(nlo_channel_prediction_cfg); 6808 /** TODO: Discrete firmware doesn't have command/option to configure 6809 * App IE which comes from wpa_supplicant as of part PNO start request. 6810 */ 6811 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param, 6812 WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params)); 6813 buf_ptr += sizeof(enlo_candidate_score_params); 6814 6815 if (ie_allowlist->allow_list) { 6816 cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ; 6817 wmi_fill_ie_allowlist_attrs(cmd->ie_bitmap, 6818 &cmd->num_vendor_oui, 6819 ie_allowlist); 6820 } 6821 6822 /* ie allow list */ 6823 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 6824 ie_allowlist->num_vendor_oui * sizeof(wmi_vendor_oui)); 6825 buf_ptr += WMI_TLV_HDR_SIZE; 6826 if (cmd->num_vendor_oui != 0) { 6827 wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui, 6828 ie_allowlist->voui); 6829 buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); 6830 } 6831 6832 if (pno->relative_rssi_set) 6833 cmd->flags |= WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG; 6834 6835 /* 6836 * Firmware calculation using connected PNO params: 6837 * New AP's RSSI >= (Connected AP's RSSI + relative_rssi +/- rssi_pref) 6838 * deduction of rssi_pref for chosen band_pref and 6839 * addition of rssi_pref for remaining bands (other than chosen band). 6840 */ 6841 nlo_relative_rssi = (connected_nlo_rssi_params *) buf_ptr; 6842 WMITLV_SET_HDR(&nlo_relative_rssi->tlv_header, 6843 WMITLV_TAG_STRUC_wmi_connected_nlo_rssi_params, 6844 WMITLV_GET_STRUCT_TLVLEN(connected_nlo_rssi_params)); 6845 nlo_relative_rssi->relative_rssi = pno->relative_rssi; 6846 buf_ptr += sizeof(*nlo_relative_rssi); 6847 6848 /* 6849 * As of now Kernel and Host supports one band and rssi preference. 6850 * Firmware supports array of band and rssi preferences 6851 */ 6852 cmd->num_cnlo_band_pref = 1; 6853 WMITLV_SET_HDR(buf_ptr, 6854 WMITLV_TAG_ARRAY_STRUC, 6855 cmd->num_cnlo_band_pref * 6856 sizeof(connected_nlo_bss_band_rssi_pref)); 6857 buf_ptr += WMI_TLV_HDR_SIZE; 6858 6859 nlo_band_rssi = (connected_nlo_bss_band_rssi_pref *) buf_ptr; 6860 for (i = 0; i < cmd->num_cnlo_band_pref; i++) { 6861 WMITLV_SET_HDR(&nlo_band_rssi[i].tlv_header, 6862 WMITLV_TAG_STRUC_wmi_connected_nlo_bss_band_rssi_pref, 6863 WMITLV_GET_STRUCT_TLVLEN( 6864 connected_nlo_bss_band_rssi_pref)); 6865 nlo_band_rssi[i].band = pno->band_rssi_pref.band; 6866 nlo_band_rssi[i].rssi_pref = pno->band_rssi_pref.rssi; 6867 } 6868 buf_ptr += cmd->num_cnlo_band_pref * sizeof(*nlo_band_rssi); 6869 6870 wmi_mtrace(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, cmd->vdev_id, 0); 6871 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6872 WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); 6873 if (ret) { 6874 wmi_err("Failed to send nlo wmi cmd"); 6875 wmi_buf_free(buf); 6876 return QDF_STATUS_E_FAILURE; 6877 } 6878 6879 return QDF_STATUS_SUCCESS; 6880 } 6881 6882 /** 6883 * is_service_enabled_tlv() - Check if service enabled 6884 * @wmi_handle: wmi handle 6885 * @service_id: service identifier 6886 * 6887 * Return: 1 enabled, 0 disabled 6888 */ 6889 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, 6890 uint32_t service_id) 6891 { 6892 struct wmi_soc *soc = wmi_handle->soc; 6893 6894 if (!soc->wmi_service_bitmap) { 6895 wmi_err("WMI service bit map is not saved yet"); 6896 return false; 6897 } 6898 6899 /* if wmi_service_enabled was received with extended2 bitmap, 6900 * use WMI_SERVICE_EXT2_IS_ENABLED to check the services. 6901 */ 6902 if (soc->wmi_ext2_service_bitmap) { 6903 if (!soc->wmi_ext_service_bitmap) { 6904 wmi_err("WMI service ext bit map is not saved yet"); 6905 return false; 6906 } 6907 6908 if (service_id > WMI_MAX_EXT_SERVICE && 6909 (service_id - WMI_MAX_EXT_SERVICE) / 32 >= 6910 soc->wmi_ext2_service_bitmap_len) { 6911 wmi_err("WMI service ext2 bit = %d is not advertised by fw", 6912 service_id); 6913 return false; 6914 } 6915 6916 return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap, 6917 soc->wmi_ext_service_bitmap, 6918 soc->wmi_ext2_service_bitmap, 6919 service_id); 6920 } 6921 6922 if (service_id >= WMI_MAX_EXT_SERVICE) { 6923 wmi_err_rl("Service id %d but WMI ext2 service bitmap is NULL", 6924 service_id); 6925 return false; 6926 } 6927 /* if wmi_service_enabled was received with extended bitmap, 6928 * use WMI_SERVICE_EXT_IS_ENABLED to check the services. 6929 */ 6930 if (soc->wmi_ext_service_bitmap) 6931 return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap, 6932 soc->wmi_ext_service_bitmap, 6933 service_id); 6934 6935 if (service_id >= WMI_MAX_SERVICE) { 6936 wmi_err("Service id %d but WMI ext service bitmap is NULL", 6937 service_id); 6938 return false; 6939 } 6940 6941 return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, 6942 service_id); 6943 } 6944 6945 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 6946 /** 6947 * send_process_ll_stats_clear_cmd_tlv() - clear link layer stats 6948 * @wmi_handle: wmi handle 6949 * @clear_req: ll stats clear request command params 6950 * 6951 * Return: QDF_STATUS_SUCCESS for success or error code 6952 */ 6953 static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle, 6954 const struct ll_stats_clear_params *clear_req) 6955 { 6956 wmi_clear_link_stats_cmd_fixed_param *cmd; 6957 int32_t len; 6958 wmi_buf_t buf; 6959 uint8_t *buf_ptr; 6960 int ret; 6961 6962 len = sizeof(*cmd); 6963 buf = wmi_buf_alloc(wmi_handle, len); 6964 6965 if (!buf) 6966 return QDF_STATUS_E_NOMEM; 6967 6968 buf_ptr = (uint8_t *) wmi_buf_data(buf); 6969 qdf_mem_zero(buf_ptr, len); 6970 cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; 6971 6972 WMITLV_SET_HDR(&cmd->tlv_header, 6973 WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, 6974 WMITLV_GET_STRUCT_TLVLEN 6975 (wmi_clear_link_stats_cmd_fixed_param)); 6976 6977 cmd->stop_stats_collection_req = clear_req->stop_req; 6978 cmd->vdev_id = clear_req->vdev_id; 6979 cmd->stats_clear_req_mask = clear_req->stats_clear_mask; 6980 6981 WMI_CHAR_ARRAY_TO_MAC_ADDR(clear_req->peer_macaddr.bytes, 6982 &cmd->peer_macaddr); 6983 6984 wmi_debug("LINK_LAYER_STATS - Clear Request Params"); 6985 wmi_debug("StopReq: %d Vdev Id: %d Clear Stat Mask: %d" 6986 " Peer MAC Addr: "QDF_MAC_ADDR_FMT, 6987 cmd->stop_stats_collection_req, 6988 cmd->vdev_id, cmd->stats_clear_req_mask, 6989 QDF_MAC_ADDR_REF(clear_req->peer_macaddr.bytes)); 6990 6991 wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); 6992 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 6993 WMI_CLEAR_LINK_STATS_CMDID); 6994 if (ret) { 6995 wmi_err("Failed to send clear link stats req"); 6996 wmi_buf_free(buf); 6997 return QDF_STATUS_E_FAILURE; 6998 } 6999 7000 wmi_debug("Clear Link Layer Stats request sent successfully"); 7001 return QDF_STATUS_SUCCESS; 7002 } 7003 7004 /** 7005 * send_process_ll_stats_set_cmd_tlv() - link layer stats set request 7006 * @wmi_handle: wmi handle 7007 * @set_req: ll stats set request command params 7008 * 7009 * Return: QDF_STATUS_SUCCESS for success or error code 7010 */ 7011 static QDF_STATUS send_process_ll_stats_set_cmd_tlv(wmi_unified_t wmi_handle, 7012 const struct ll_stats_set_params *set_req) 7013 { 7014 wmi_start_link_stats_cmd_fixed_param *cmd; 7015 int32_t len; 7016 wmi_buf_t buf; 7017 uint8_t *buf_ptr; 7018 int ret; 7019 7020 len = sizeof(*cmd); 7021 buf = wmi_buf_alloc(wmi_handle, len); 7022 7023 if (!buf) 7024 return QDF_STATUS_E_NOMEM; 7025 7026 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7027 qdf_mem_zero(buf_ptr, len); 7028 cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; 7029 7030 WMITLV_SET_HDR(&cmd->tlv_header, 7031 WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, 7032 WMITLV_GET_STRUCT_TLVLEN 7033 (wmi_start_link_stats_cmd_fixed_param)); 7034 7035 cmd->mpdu_size_threshold = set_req->mpdu_size_threshold; 7036 cmd->aggressive_statistics_gathering = 7037 set_req->aggressive_statistics_gathering; 7038 7039 wmi_debug("LINK_LAYER_STATS - Start/Set Params MPDU Size Thresh : %d Aggressive Gather: %d", 7040 cmd->mpdu_size_threshold, 7041 cmd->aggressive_statistics_gathering); 7042 7043 wmi_mtrace(WMI_START_LINK_STATS_CMDID, NO_SESSION, 0); 7044 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7045 WMI_START_LINK_STATS_CMDID); 7046 if (ret) { 7047 wmi_err("Failed to send set link stats request"); 7048 wmi_buf_free(buf); 7049 return QDF_STATUS_E_FAILURE; 7050 } 7051 7052 return QDF_STATUS_SUCCESS; 7053 } 7054 7055 /** 7056 * send_process_ll_stats_get_cmd_tlv() - link layer stats get request 7057 * @wmi_handle: wmi handle 7058 * @get_req: ll stats get request command params 7059 * 7060 * Return: QDF_STATUS_SUCCESS for success or error code 7061 */ 7062 static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, 7063 const struct ll_stats_get_params *get_req) 7064 { 7065 wmi_request_link_stats_cmd_fixed_param *cmd; 7066 int32_t len; 7067 wmi_buf_t buf; 7068 uint8_t *buf_ptr; 7069 int ret; 7070 bool is_link_stats_over_qmi; 7071 7072 len = sizeof(*cmd); 7073 buf = wmi_buf_alloc(wmi_handle, len); 7074 7075 if (!buf) 7076 return QDF_STATUS_E_NOMEM; 7077 7078 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7079 qdf_mem_zero(buf_ptr, len); 7080 cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; 7081 7082 WMITLV_SET_HDR(&cmd->tlv_header, 7083 WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, 7084 WMITLV_GET_STRUCT_TLVLEN 7085 (wmi_request_link_stats_cmd_fixed_param)); 7086 7087 cmd->request_id = get_req->req_id; 7088 cmd->stats_type = get_req->param_id_mask; 7089 cmd->vdev_id = get_req->vdev_id; 7090 7091 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7092 &cmd->peer_macaddr); 7093 7094 wmi_debug("LINK_LAYER_STATS - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: "QDF_MAC_ADDR_FMT, 7095 cmd->request_id, cmd->stats_type, cmd->vdev_id, 7096 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7097 7098 wmi_mtrace(WMI_REQUEST_LINK_STATS_CMDID, cmd->vdev_id, 0); 7099 is_link_stats_over_qmi = is_service_enabled_tlv( 7100 wmi_handle, 7101 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7102 7103 if (is_link_stats_over_qmi) { 7104 ret = wmi_unified_cmd_send_over_qmi( 7105 wmi_handle, buf, len, 7106 WMI_REQUEST_LINK_STATS_CMDID); 7107 } else { 7108 ret = wmi_unified_cmd_send_pm_chk( 7109 wmi_handle, buf, len, 7110 WMI_REQUEST_LINK_STATS_CMDID, true); 7111 } 7112 7113 if (ret) { 7114 wmi_buf_free(buf); 7115 return QDF_STATUS_E_FAILURE; 7116 } 7117 7118 return QDF_STATUS_SUCCESS; 7119 } 7120 7121 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 7122 #ifdef WLAN_FEATURE_11BE_MLO 7123 static int 7124 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7125 { 7126 int32_t len = 0; 7127 7128 /* In case of MLO connection, update the length of the buffer. 7129 * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, 7130 * hence just update the TLV header, but allocate no memory for it. 7131 */ 7132 if (!get_req->is_mlo_req) 7133 return len; 7134 7135 len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + 7136 WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + 7137 WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); 7138 7139 return len; 7140 } 7141 7142 static void 7143 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7144 void *buf_ptr) 7145 { 7146 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7147 uint32_t *vdev_id_bitmap; 7148 wmi_mac_addr *mld_mac; 7149 7150 /* In case of MLO connection, update the TLV Headers */ 7151 if (!get_req->is_mlo_req) 7152 return; 7153 7154 buf_ptr += sizeof(*unified_cmd); 7155 7156 /* Fill TLV but no data for wmi_inst_rssi_stats_params */ 7157 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 7158 buf_ptr += WMI_TLV_HDR_SIZE; 7159 7160 /* Adding vdev_bitmap_id array TLV */ 7161 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 7162 sizeof(*vdev_id_bitmap)); 7163 buf_ptr += WMI_TLV_HDR_SIZE; 7164 vdev_id_bitmap = buf_ptr; 7165 *(vdev_id_bitmap) = get_req->vdev_id_bitmap; 7166 buf_ptr += sizeof(*vdev_id_bitmap); 7167 7168 /* Adding mld_macaddr array TLV */ 7169 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 7170 sizeof(*mld_mac)); 7171 buf_ptr += WMI_TLV_HDR_SIZE; 7172 mld_mac = buf_ptr; 7173 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); 7174 7175 wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " 7176 QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, 7177 QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); 7178 } 7179 #else 7180 static inline int 7181 wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) 7182 { 7183 return 0; 7184 } 7185 7186 static inline void 7187 wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, 7188 void *buf_ptr) 7189 { 7190 } 7191 #endif 7192 7193 /** 7194 * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get 7195 * station request 7196 * @wmi_handle: wmi handle 7197 * @get_req: ll stats get request command params 7198 * 7199 * Return: QDF_STATUS_SUCCESS for success or error code 7200 */ 7201 static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( 7202 wmi_unified_t wmi_handle, 7203 const struct ll_stats_get_params *get_req) 7204 { 7205 wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; 7206 int32_t len; 7207 wmi_buf_t buf; 7208 void *buf_ptr; 7209 QDF_STATUS ret; 7210 bool is_ll_get_sta_stats_over_qmi; 7211 7212 len = sizeof(*unified_cmd); 7213 len += wmi_get_tlv_length_for_mlo_stats(get_req); 7214 7215 buf = wmi_buf_alloc(wmi_handle, len); 7216 if (!buf) 7217 return QDF_STATUS_E_NOMEM; 7218 7219 buf_ptr = wmi_buf_data(buf); 7220 7221 unified_cmd = buf_ptr; 7222 WMITLV_SET_HDR( 7223 &unified_cmd->tlv_header, 7224 WMITLV_TAG_STRUC_wmi_request_unified_ll_get_sta_cmd_fixed_param, 7225 WMITLV_GET_STRUCT_TLVLEN 7226 (wmi_request_unified_ll_get_sta_cmd_fixed_param)); 7227 7228 unified_cmd->link_stats_type = get_req->param_id_mask; 7229 unified_cmd->get_sta_stats_id = (WMI_REQUEST_AP_STAT | 7230 WMI_REQUEST_PEER_STAT | 7231 WMI_REQUEST_VDEV_STAT | 7232 WMI_REQUEST_PDEV_STAT | 7233 WMI_REQUEST_VDEV_EXTD_STAT | 7234 WMI_REQUEST_PEER_EXTD2_STAT | 7235 WMI_REQUEST_RSSI_PER_CHAIN_STAT); 7236 unified_cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7237 wmi_handle, 7238 WMI_HOST_PDEV_ID_SOC); 7239 7240 unified_cmd->vdev_id = get_req->vdev_id; 7241 unified_cmd->request_id = get_req->req_id; 7242 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->peer_macaddr.bytes, 7243 &unified_cmd->peer_macaddr); 7244 7245 wmi_debug("UNIFIED_LINK_STATS_GET_STA - Get Request Params Request ID: %u Stats Type: %0x Vdev ID: %d Peer MAC Addr: " 7246 QDF_MAC_ADDR_FMT, 7247 get_req->req_id, get_req->param_id_mask, get_req->vdev_id, 7248 QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); 7249 7250 wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); 7251 wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); 7252 7253 /** 7254 * FW support for LL_get_sta command. True represents the unified 7255 * ll_get_sta command should be sent over QMI always irrespective of 7256 * WOW state. 7257 */ 7258 is_ll_get_sta_stats_over_qmi = is_service_enabled_tlv( 7259 wmi_handle, 7260 WMI_SERVICE_UNIFIED_LL_GET_STA_OVER_QMI_SUPPORT); 7261 7262 if (is_ll_get_sta_stats_over_qmi) { 7263 ret = wmi_unified_cmd_send_over_qmi( 7264 wmi_handle, buf, len, 7265 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID); 7266 } else { 7267 ret = wmi_unified_cmd_send_pm_chk( 7268 wmi_handle, buf, len, 7269 WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, 7270 true); 7271 } 7272 7273 if (QDF_IS_STATUS_ERROR(ret)) { 7274 wmi_buf_free(buf); 7275 return QDF_STATUS_E_FAILURE; 7276 } 7277 7278 return ret; 7279 } 7280 #endif 7281 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 7282 7283 /** 7284 * send_congestion_cmd_tlv() - send request to fw to get CCA 7285 * @wmi_handle: wmi handle 7286 * @vdev_id: vdev id 7287 * 7288 * Return: QDF status 7289 */ 7290 static QDF_STATUS send_congestion_cmd_tlv(wmi_unified_t wmi_handle, 7291 uint8_t vdev_id) 7292 { 7293 wmi_buf_t buf; 7294 wmi_request_stats_cmd_fixed_param *cmd; 7295 uint8_t len; 7296 uint8_t *buf_ptr; 7297 7298 len = sizeof(*cmd); 7299 buf = wmi_buf_alloc(wmi_handle, len); 7300 if (!buf) 7301 return QDF_STATUS_E_FAILURE; 7302 7303 buf_ptr = wmi_buf_data(buf); 7304 cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; 7305 WMITLV_SET_HDR(&cmd->tlv_header, 7306 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7307 WMITLV_GET_STRUCT_TLVLEN 7308 (wmi_request_stats_cmd_fixed_param)); 7309 7310 cmd->stats_id = WMI_REQUEST_CONGESTION_STAT; 7311 cmd->vdev_id = vdev_id; 7312 wmi_debug("STATS REQ VDEV_ID:%d stats_id %d -->", 7313 cmd->vdev_id, cmd->stats_id); 7314 7315 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7316 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7317 WMI_REQUEST_STATS_CMDID)) { 7318 wmi_err("Failed to send WMI_REQUEST_STATS_CMDID"); 7319 wmi_buf_free(buf); 7320 return QDF_STATUS_E_FAILURE; 7321 } 7322 7323 return QDF_STATUS_SUCCESS; 7324 } 7325 7326 /** 7327 * send_snr_request_cmd_tlv() - send request to fw to get RSSI stats 7328 * @wmi_handle: wmi handle 7329 * 7330 * Return: QDF status 7331 */ 7332 static QDF_STATUS send_snr_request_cmd_tlv(wmi_unified_t wmi_handle) 7333 { 7334 wmi_buf_t buf; 7335 wmi_request_stats_cmd_fixed_param *cmd; 7336 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7337 7338 buf = wmi_buf_alloc(wmi_handle, len); 7339 if (!buf) 7340 return QDF_STATUS_E_FAILURE; 7341 7342 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7343 WMITLV_SET_HDR(&cmd->tlv_header, 7344 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7345 WMITLV_GET_STRUCT_TLVLEN 7346 (wmi_request_stats_cmd_fixed_param)); 7347 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7348 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7349 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7350 WMI_REQUEST_STATS_CMDID)) { 7351 wmi_err("Failed to send host stats request to fw"); 7352 wmi_buf_free(buf); 7353 return QDF_STATUS_E_FAILURE; 7354 } 7355 7356 return QDF_STATUS_SUCCESS; 7357 } 7358 7359 /** 7360 * send_snr_cmd_tlv() - get RSSI from fw 7361 * @wmi_handle: wmi handle 7362 * @vdev_id: vdev id 7363 * 7364 * Return: QDF status 7365 */ 7366 static QDF_STATUS send_snr_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id) 7367 { 7368 wmi_buf_t buf; 7369 wmi_request_stats_cmd_fixed_param *cmd; 7370 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7371 7372 buf = wmi_buf_alloc(wmi_handle, len); 7373 if (!buf) 7374 return QDF_STATUS_E_FAILURE; 7375 7376 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7377 cmd->vdev_id = vdev_id; 7378 7379 WMITLV_SET_HDR(&cmd->tlv_header, 7380 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7381 WMITLV_GET_STRUCT_TLVLEN 7382 (wmi_request_stats_cmd_fixed_param)); 7383 cmd->stats_id = WMI_REQUEST_VDEV_STAT; 7384 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7385 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7386 WMI_REQUEST_STATS_CMDID)) { 7387 wmi_err("Failed to send host stats request to fw"); 7388 wmi_buf_free(buf); 7389 return QDF_STATUS_E_FAILURE; 7390 } 7391 7392 return QDF_STATUS_SUCCESS; 7393 } 7394 7395 /** 7396 * send_link_status_req_cmd_tlv() - process link status request from UMAC 7397 * @wmi_handle: wmi handle 7398 * @link_status: get link params 7399 * 7400 * Return: QDF status 7401 */ 7402 static QDF_STATUS send_link_status_req_cmd_tlv(wmi_unified_t wmi_handle, 7403 struct link_status_params *link_status) 7404 { 7405 wmi_buf_t buf; 7406 wmi_request_stats_cmd_fixed_param *cmd; 7407 uint8_t len = sizeof(wmi_request_stats_cmd_fixed_param); 7408 7409 buf = wmi_buf_alloc(wmi_handle, len); 7410 if (!buf) 7411 return QDF_STATUS_E_FAILURE; 7412 7413 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 7414 WMITLV_SET_HDR(&cmd->tlv_header, 7415 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 7416 WMITLV_GET_STRUCT_TLVLEN 7417 (wmi_request_stats_cmd_fixed_param)); 7418 cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; 7419 cmd->vdev_id = link_status->vdev_id; 7420 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 7421 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7422 WMI_REQUEST_STATS_CMDID)) { 7423 wmi_err("Failed to send WMI link status request to fw"); 7424 wmi_buf_free(buf); 7425 return QDF_STATUS_E_FAILURE; 7426 } 7427 7428 return QDF_STATUS_SUCCESS; 7429 } 7430 7431 #ifdef WLAN_SUPPORT_GREEN_AP 7432 /** 7433 * send_egap_conf_params_cmd_tlv() - send wmi cmd of egap configuration params 7434 * @wmi_handle: wmi handler 7435 * @egap_params: pointer to egap_params 7436 * 7437 * Return: 0 for success, otherwise appropriate error code 7438 */ 7439 static QDF_STATUS send_egap_conf_params_cmd_tlv(wmi_unified_t wmi_handle, 7440 struct wlan_green_ap_egap_params *egap_params) 7441 { 7442 wmi_ap_ps_egap_param_cmd_fixed_param *cmd; 7443 wmi_buf_t buf; 7444 int32_t err; 7445 7446 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 7447 if (!buf) 7448 return QDF_STATUS_E_NOMEM; 7449 7450 cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); 7451 WMITLV_SET_HDR(&cmd->tlv_header, 7452 WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, 7453 WMITLV_GET_STRUCT_TLVLEN( 7454 wmi_ap_ps_egap_param_cmd_fixed_param)); 7455 7456 cmd->enable = egap_params->host_enable_egap; 7457 cmd->inactivity_time = egap_params->egap_inactivity_time; 7458 cmd->wait_time = egap_params->egap_wait_time; 7459 cmd->flags = egap_params->egap_feature_flags; 7460 wmi_mtrace(WMI_AP_PS_EGAP_PARAM_CMDID, NO_SESSION, 0); 7461 err = wmi_unified_cmd_send(wmi_handle, buf, 7462 sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); 7463 if (err) { 7464 wmi_err("Failed to send ap_ps_egap cmd"); 7465 wmi_buf_free(buf); 7466 return QDF_STATUS_E_FAILURE; 7467 } 7468 7469 return QDF_STATUS_SUCCESS; 7470 } 7471 #endif 7472 7473 /** 7474 * send_csa_offload_enable_cmd_tlv() - send CSA offload enable command 7475 * @wmi_handle: wmi handle 7476 * @vdev_id: vdev id 7477 * 7478 * Return: QDF_STATUS_SUCCESS for success or error code 7479 */ 7480 static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle, 7481 uint8_t vdev_id) 7482 { 7483 wmi_csa_offload_enable_cmd_fixed_param *cmd; 7484 wmi_buf_t buf; 7485 int32_t len = sizeof(*cmd); 7486 7487 wmi_debug("vdev_id %d", vdev_id); 7488 buf = wmi_buf_alloc(wmi_handle, len); 7489 if (!buf) 7490 return QDF_STATUS_E_NOMEM; 7491 7492 cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); 7493 WMITLV_SET_HDR(&cmd->tlv_header, 7494 WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, 7495 WMITLV_GET_STRUCT_TLVLEN 7496 (wmi_csa_offload_enable_cmd_fixed_param)); 7497 cmd->vdev_id = vdev_id; 7498 cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; 7499 wmi_mtrace(WMI_CSA_OFFLOAD_ENABLE_CMDID, cmd->vdev_id, 0); 7500 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7501 WMI_CSA_OFFLOAD_ENABLE_CMDID)) { 7502 wmi_err("Failed to send CSA offload enable command"); 7503 wmi_buf_free(buf); 7504 return QDF_STATUS_E_FAILURE; 7505 } 7506 7507 return 0; 7508 } 7509 7510 #ifdef WLAN_FEATURE_CIF_CFR 7511 /** 7512 * send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings 7513 * @wmi_handle: wmi handle 7514 * @cfg: dma cfg req 7515 * 7516 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 7517 */ 7518 static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle, 7519 wmi_oem_dma_ring_cfg_req_fixed_param *cfg) 7520 { 7521 wmi_buf_t buf; 7522 uint8_t *cmd; 7523 QDF_STATUS ret; 7524 7525 WMITLV_SET_HDR(cfg, 7526 WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param, 7527 (sizeof(*cfg) - WMI_TLV_HDR_SIZE)); 7528 7529 buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg)); 7530 if (!buf) 7531 return QDF_STATUS_E_FAILURE; 7532 7533 cmd = (uint8_t *) wmi_buf_data(buf); 7534 qdf_mem_copy(cmd, cfg, sizeof(*cfg)); 7535 wmi_debug("Sending OEM Data Request to target, data len %lu", 7536 sizeof(*cfg)); 7537 wmi_mtrace(WMI_OEM_DMA_RING_CFG_REQ_CMDID, NO_SESSION, 0); 7538 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg), 7539 WMI_OEM_DMA_RING_CFG_REQ_CMDID); 7540 if (QDF_IS_STATUS_ERROR(ret)) { 7541 wmi_err("Failed to send WMI_OEM_DMA_RING_CFG_REQ_CMDID"); 7542 wmi_buf_free(buf); 7543 } 7544 7545 return ret; 7546 } 7547 #endif 7548 7549 /** 7550 * send_start_11d_scan_cmd_tlv() - start 11d scan request 7551 * @wmi_handle: wmi handle 7552 * @start_11d_scan: 11d scan start request parameters 7553 * 7554 * This function request FW to start 11d scan. 7555 * 7556 * Return: QDF status 7557 */ 7558 static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7559 struct reg_start_11d_scan_req *start_11d_scan) 7560 { 7561 wmi_11d_scan_start_cmd_fixed_param *cmd; 7562 int32_t len; 7563 wmi_buf_t buf; 7564 int ret; 7565 7566 len = sizeof(*cmd); 7567 buf = wmi_buf_alloc(wmi_handle, len); 7568 if (!buf) 7569 return QDF_STATUS_E_NOMEM; 7570 7571 cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf); 7572 7573 WMITLV_SET_HDR(&cmd->tlv_header, 7574 WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param, 7575 WMITLV_GET_STRUCT_TLVLEN 7576 (wmi_11d_scan_start_cmd_fixed_param)); 7577 7578 cmd->vdev_id = start_11d_scan->vdev_id; 7579 cmd->scan_period_msec = start_11d_scan->scan_period_msec; 7580 cmd->start_interval_msec = start_11d_scan->start_interval_msec; 7581 7582 wmi_debug("vdev %d sending 11D scan start req", cmd->vdev_id); 7583 7584 wmi_mtrace(WMI_11D_SCAN_START_CMDID, cmd->vdev_id, 0); 7585 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7586 WMI_11D_SCAN_START_CMDID); 7587 if (ret) { 7588 wmi_err("Failed to send start 11d scan wmi cmd"); 7589 wmi_buf_free(buf); 7590 return QDF_STATUS_E_FAILURE; 7591 } 7592 7593 return QDF_STATUS_SUCCESS; 7594 } 7595 7596 /** 7597 * send_stop_11d_scan_cmd_tlv() - stop 11d scan request 7598 * @wmi_handle: wmi handle 7599 * @stop_11d_scan: 11d scan stop request parameters 7600 * 7601 * This function request FW to stop 11d scan. 7602 * 7603 * Return: QDF status 7604 */ 7605 static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle, 7606 struct reg_stop_11d_scan_req *stop_11d_scan) 7607 { 7608 wmi_11d_scan_stop_cmd_fixed_param *cmd; 7609 int32_t len; 7610 wmi_buf_t buf; 7611 int ret; 7612 7613 len = sizeof(*cmd); 7614 buf = wmi_buf_alloc(wmi_handle, len); 7615 if (!buf) 7616 return QDF_STATUS_E_NOMEM; 7617 7618 cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf); 7619 7620 WMITLV_SET_HDR(&cmd->tlv_header, 7621 WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param, 7622 WMITLV_GET_STRUCT_TLVLEN 7623 (wmi_11d_scan_stop_cmd_fixed_param)); 7624 7625 cmd->vdev_id = stop_11d_scan->vdev_id; 7626 7627 wmi_debug("vdev %d sending 11D scan stop req", cmd->vdev_id); 7628 7629 wmi_mtrace(WMI_11D_SCAN_STOP_CMDID, cmd->vdev_id, 0); 7630 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7631 WMI_11D_SCAN_STOP_CMDID); 7632 if (ret) { 7633 wmi_err("Failed to send stop 11d scan wmi cmd"); 7634 wmi_buf_free(buf); 7635 return QDF_STATUS_E_FAILURE; 7636 } 7637 7638 return QDF_STATUS_SUCCESS; 7639 } 7640 7641 /** 7642 * send_start_oem_data_cmd_tlv() - start OEM data request to target 7643 * @wmi_handle: wmi handle 7644 * @data_len: the length of @data 7645 * @data: the pointer to data buf 7646 * 7647 * Return: QDF status 7648 */ 7649 static QDF_STATUS send_start_oem_data_cmd_tlv(wmi_unified_t wmi_handle, 7650 uint32_t data_len, 7651 uint8_t *data) 7652 { 7653 wmi_buf_t buf; 7654 uint8_t *cmd; 7655 QDF_STATUS ret; 7656 7657 buf = wmi_buf_alloc(wmi_handle, 7658 (data_len + WMI_TLV_HDR_SIZE)); 7659 if (!buf) 7660 return QDF_STATUS_E_FAILURE; 7661 7662 cmd = (uint8_t *) wmi_buf_data(buf); 7663 7664 WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, data_len); 7665 cmd += WMI_TLV_HDR_SIZE; 7666 qdf_mem_copy(cmd, data, 7667 data_len); 7668 7669 wmi_debug("Sending OEM Data Request to target, data len %d", data_len); 7670 7671 wmi_mtrace(WMI_OEM_REQ_CMDID, NO_SESSION, 0); 7672 ret = wmi_unified_cmd_send(wmi_handle, buf, 7673 (data_len + 7674 WMI_TLV_HDR_SIZE), WMI_OEM_REQ_CMDID); 7675 7676 if (QDF_IS_STATUS_ERROR(ret)) { 7677 wmi_err("Failed to send WMI_OEM_REQ_CMDID"); 7678 wmi_buf_free(buf); 7679 } 7680 7681 return ret; 7682 } 7683 7684 #ifdef FEATURE_OEM_DATA 7685 /** 7686 * send_start_oemv2_data_cmd_tlv() - start OEM data to target 7687 * @wmi_handle: wmi handle 7688 * @oem_data: the pointer to oem data 7689 * 7690 * Return: QDF status 7691 */ 7692 static QDF_STATUS send_start_oemv2_data_cmd_tlv(wmi_unified_t wmi_handle, 7693 struct oem_data *oem_data) 7694 { 7695 QDF_STATUS ret; 7696 wmi_oem_data_cmd_fixed_param *cmd; 7697 struct wmi_ops *ops; 7698 wmi_buf_t buf; 7699 uint16_t len = sizeof(*cmd); 7700 uint16_t oem_data_len_aligned; 7701 uint8_t *buf_ptr; 7702 uint32_t pdev_id; 7703 7704 if (!oem_data || !oem_data->data) { 7705 wmi_err_rl("oem data is not valid"); 7706 return QDF_STATUS_E_FAILURE; 7707 } 7708 7709 oem_data_len_aligned = roundup(oem_data->data_len, sizeof(uint32_t)); 7710 if (oem_data_len_aligned < oem_data->data_len) { 7711 wmi_err_rl("integer overflow while rounding up data_len"); 7712 return QDF_STATUS_E_FAILURE; 7713 } 7714 7715 if (oem_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) { 7716 wmi_err_rl("wmi_max_msg_size overflow for given data_len"); 7717 return QDF_STATUS_E_FAILURE; 7718 } 7719 7720 len += WMI_TLV_HDR_SIZE + oem_data_len_aligned; 7721 buf = wmi_buf_alloc(wmi_handle, len); 7722 if (!buf) 7723 return QDF_STATUS_E_NOMEM; 7724 7725 buf_ptr = (uint8_t *)wmi_buf_data(buf); 7726 cmd = (wmi_oem_data_cmd_fixed_param *)buf_ptr; 7727 WMITLV_SET_HDR(&cmd->tlv_header, 7728 WMITLV_TAG_STRUC_wmi_oem_data_cmd_fixed_param, 7729 WMITLV_GET_STRUCT_TLVLEN(wmi_oem_data_cmd_fixed_param)); 7730 7731 pdev_id = oem_data->pdev_id; 7732 if (oem_data->pdev_vdev_flag) { 7733 ops = wmi_handle->ops; 7734 if (oem_data->is_host_pdev_id) 7735 pdev_id = 7736 ops->convert_host_pdev_id_to_target(wmi_handle, 7737 pdev_id); 7738 else 7739 pdev_id = 7740 ops->convert_pdev_id_host_to_target(wmi_handle, 7741 pdev_id); 7742 } 7743 7744 cmd->vdev_id = oem_data->vdev_id; 7745 cmd->data_len = oem_data->data_len; 7746 cmd->pdev_vdev_flag = oem_data->pdev_vdev_flag; 7747 cmd->pdev_id = pdev_id; 7748 7749 buf_ptr += sizeof(*cmd); 7750 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, oem_data_len_aligned); 7751 buf_ptr += WMI_TLV_HDR_SIZE; 7752 qdf_mem_copy(buf_ptr, oem_data->data, oem_data->data_len); 7753 7754 wmi_mtrace(WMI_OEM_DATA_CMDID, NO_SESSION, 0); 7755 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_OEM_DATA_CMDID); 7756 if (QDF_IS_STATUS_ERROR(ret)) { 7757 wmi_err_rl("Failed with ret = %d", ret); 7758 wmi_buf_free(buf); 7759 } 7760 7761 return ret; 7762 } 7763 #endif 7764 7765 /** 7766 * send_dfs_phyerr_filter_offload_en_cmd_tlv() - enable dfs phyerr filter 7767 * @wmi_handle: wmi handle 7768 * @dfs_phyerr_filter_offload: is dfs phyerr filter offload 7769 * 7770 * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or 7771 * WMI_DFS_PHYERR_FILTER_DIS_CMDID command 7772 * to firmware based on phyerr filtering 7773 * offload status. 7774 * 7775 * Return: 1 success, 0 failure 7776 */ 7777 static QDF_STATUS 7778 send_dfs_phyerr_filter_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 7779 bool dfs_phyerr_filter_offload) 7780 { 7781 wmi_dfs_phyerr_filter_ena_cmd_fixed_param *enable_phyerr_offload_cmd; 7782 wmi_dfs_phyerr_filter_dis_cmd_fixed_param *disable_phyerr_offload_cmd; 7783 wmi_buf_t buf; 7784 uint16_t len; 7785 QDF_STATUS ret; 7786 7787 7788 if (false == dfs_phyerr_filter_offload) { 7789 wmi_debug("Phyerror Filtering offload is Disabled in ini"); 7790 len = sizeof(*disable_phyerr_offload_cmd); 7791 buf = wmi_buf_alloc(wmi_handle, len); 7792 if (!buf) 7793 return 0; 7794 7795 disable_phyerr_offload_cmd = 7796 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) 7797 wmi_buf_data(buf); 7798 7799 WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, 7800 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, 7801 WMITLV_GET_STRUCT_TLVLEN 7802 (wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); 7803 7804 /* 7805 * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID 7806 * to the firmware to disable the phyerror 7807 * filtering offload. 7808 */ 7809 wmi_mtrace(WMI_DFS_PHYERR_FILTER_DIS_CMDID, NO_SESSION, 0); 7810 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7811 WMI_DFS_PHYERR_FILTER_DIS_CMDID); 7812 if (QDF_IS_STATUS_ERROR(ret)) { 7813 wmi_err("Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", 7814 ret); 7815 wmi_buf_free(buf); 7816 return QDF_STATUS_E_FAILURE; 7817 } 7818 wmi_debug("WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success"); 7819 } else { 7820 wmi_debug("Phyerror Filtering offload is Enabled in ini"); 7821 7822 len = sizeof(*enable_phyerr_offload_cmd); 7823 buf = wmi_buf_alloc(wmi_handle, len); 7824 if (!buf) 7825 return QDF_STATUS_E_FAILURE; 7826 7827 enable_phyerr_offload_cmd = 7828 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) 7829 wmi_buf_data(buf); 7830 7831 WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, 7832 WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, 7833 WMITLV_GET_STRUCT_TLVLEN 7834 (wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); 7835 7836 /* 7837 * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID 7838 * to the firmware to enable the phyerror 7839 * filtering offload. 7840 */ 7841 wmi_mtrace(WMI_DFS_PHYERR_FILTER_ENA_CMDID, NO_SESSION, 0); 7842 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 7843 WMI_DFS_PHYERR_FILTER_ENA_CMDID); 7844 7845 if (QDF_IS_STATUS_ERROR(ret)) { 7846 wmi_err("Failed to send DFS PHYERR CMD ret=%d", ret); 7847 wmi_buf_free(buf); 7848 return QDF_STATUS_E_FAILURE; 7849 } 7850 wmi_debug("WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success"); 7851 } 7852 7853 return QDF_STATUS_SUCCESS; 7854 } 7855 7856 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 7857 /** 7858 * send_pktlog_wmi_send_cmd_tlv() - send pktlog enable/disable command to target 7859 * @wmi_handle: wmi handle 7860 * @pktlog_event: pktlog event 7861 * @cmd_id: pktlog cmd id 7862 * @user_triggered: user triggered input for PKTLOG enable mode 7863 * 7864 * Return: QDF status 7865 */ 7866 static QDF_STATUS send_pktlog_wmi_send_cmd_tlv(wmi_unified_t wmi_handle, 7867 WMI_PKTLOG_EVENT pktlog_event, 7868 WMI_CMD_ID cmd_id, uint8_t user_triggered) 7869 { 7870 WMI_PKTLOG_EVENT PKTLOG_EVENT; 7871 WMI_CMD_ID CMD_ID; 7872 wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; 7873 wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; 7874 int len = 0; 7875 wmi_buf_t buf; 7876 int32_t idx, max_idx; 7877 7878 PKTLOG_EVENT = pktlog_event; 7879 CMD_ID = cmd_id; 7880 7881 max_idx = sizeof(pktlog_event_tlv) / (sizeof(pktlog_event_tlv[0])); 7882 switch (CMD_ID) { 7883 case WMI_PDEV_PKTLOG_ENABLE_CMDID: 7884 len = sizeof(*cmd); 7885 buf = wmi_buf_alloc(wmi_handle, len); 7886 if (!buf) 7887 return QDF_STATUS_E_NOMEM; 7888 7889 cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) 7890 wmi_buf_data(buf); 7891 WMITLV_SET_HDR(&cmd->tlv_header, 7892 WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, 7893 WMITLV_GET_STRUCT_TLVLEN 7894 (wmi_pdev_pktlog_enable_cmd_fixed_param)); 7895 cmd->evlist = 0; 7896 for (idx = 0; idx < max_idx; idx++) { 7897 if (PKTLOG_EVENT & (1 << idx)) 7898 cmd->evlist |= pktlog_event_tlv[idx]; 7899 } 7900 cmd->enable = user_triggered ? WMI_PKTLOG_ENABLE_FORCE 7901 : WMI_PKTLOG_ENABLE_AUTO; 7902 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 7903 wmi_handle, 7904 WMI_HOST_PDEV_ID_SOC); 7905 wmi_mtrace(WMI_PDEV_PKTLOG_ENABLE_CMDID, NO_SESSION, 0); 7906 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7907 WMI_PDEV_PKTLOG_ENABLE_CMDID)) { 7908 wmi_err("Failed to send pktlog enable cmdid"); 7909 goto wmi_send_failed; 7910 } 7911 break; 7912 case WMI_PDEV_PKTLOG_DISABLE_CMDID: 7913 len = sizeof(*disable_cmd); 7914 buf = wmi_buf_alloc(wmi_handle, len); 7915 if (!buf) 7916 return QDF_STATUS_E_NOMEM; 7917 7918 disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) 7919 wmi_buf_data(buf); 7920 WMITLV_SET_HDR(&disable_cmd->tlv_header, 7921 WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, 7922 WMITLV_GET_STRUCT_TLVLEN 7923 (wmi_pdev_pktlog_disable_cmd_fixed_param)); 7924 disable_cmd->pdev_id = 7925 wmi_handle->ops->convert_pdev_id_host_to_target( 7926 wmi_handle, 7927 WMI_HOST_PDEV_ID_SOC); 7928 wmi_mtrace(WMI_PDEV_PKTLOG_DISABLE_CMDID, NO_SESSION, 0); 7929 if (wmi_unified_cmd_send(wmi_handle, buf, len, 7930 WMI_PDEV_PKTLOG_DISABLE_CMDID)) { 7931 wmi_err("failed to send pktlog disable cmdid"); 7932 goto wmi_send_failed; 7933 } 7934 break; 7935 default: 7936 wmi_debug("Invalid PKTLOG command: %d", CMD_ID); 7937 break; 7938 } 7939 7940 return QDF_STATUS_SUCCESS; 7941 7942 wmi_send_failed: 7943 wmi_buf_free(buf); 7944 return QDF_STATUS_E_FAILURE; 7945 } 7946 #endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ 7947 7948 /** 7949 * send_stats_ext_req_cmd_tlv() - request ext stats from fw 7950 * @wmi_handle: wmi handle 7951 * @preq: stats ext params 7952 * 7953 * Return: QDF status 7954 */ 7955 static QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle, 7956 struct stats_ext_params *preq) 7957 { 7958 QDF_STATUS ret; 7959 wmi_req_stats_ext_cmd_fixed_param *cmd; 7960 wmi_buf_t buf; 7961 size_t len; 7962 uint8_t *buf_ptr; 7963 uint16_t max_wmi_msg_size = wmi_get_max_msg_len(wmi_handle); 7964 uint32_t *vdev_bitmap; 7965 7966 if (preq->request_data_len > (max_wmi_msg_size - WMI_TLV_HDR_SIZE - 7967 sizeof(*cmd))) { 7968 wmi_err("Data length=%d is greater than max wmi msg size", 7969 preq->request_data_len); 7970 return QDF_STATUS_E_FAILURE; 7971 } 7972 7973 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len + 7974 WMI_TLV_HDR_SIZE + sizeof(uint32_t); 7975 7976 buf = wmi_buf_alloc(wmi_handle, len); 7977 if (!buf) 7978 return QDF_STATUS_E_NOMEM; 7979 7980 buf_ptr = (uint8_t *) wmi_buf_data(buf); 7981 cmd = (wmi_req_stats_ext_cmd_fixed_param *) buf_ptr; 7982 7983 WMITLV_SET_HDR(&cmd->tlv_header, 7984 WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, 7985 WMITLV_GET_STRUCT_TLVLEN 7986 (wmi_req_stats_ext_cmd_fixed_param)); 7987 cmd->vdev_id = preq->vdev_id; 7988 cmd->data_len = preq->request_data_len; 7989 7990 wmi_debug("The data len value is %u and vdev id set is %u", 7991 preq->request_data_len, preq->vdev_id); 7992 7993 buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); 7994 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); 7995 7996 buf_ptr += WMI_TLV_HDR_SIZE; 7997 qdf_mem_copy(buf_ptr, preq->request_data, cmd->data_len); 7998 7999 buf_ptr += cmd->data_len; 8000 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(uint32_t)); 8001 8002 buf_ptr += WMI_TLV_HDR_SIZE; 8003 8004 vdev_bitmap = (A_UINT32 *)buf_ptr; 8005 8006 vdev_bitmap[0] = preq->vdev_id_bitmap; 8007 8008 wmi_debug("Sending MLO vdev_id_bitmap:%x", vdev_bitmap[0]); 8009 8010 buf_ptr += sizeof(uint32_t); 8011 8012 wmi_mtrace(WMI_REQUEST_STATS_EXT_CMDID, cmd->vdev_id, 0); 8013 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8014 WMI_REQUEST_STATS_EXT_CMDID); 8015 if (QDF_IS_STATUS_ERROR(ret)) { 8016 wmi_err("Failed to send notify cmd ret = %d", ret); 8017 wmi_buf_free(buf); 8018 } 8019 8020 return ret; 8021 } 8022 8023 /** 8024 * send_process_dhcpserver_offload_cmd_tlv() - enable DHCP server offload 8025 * @wmi_handle: wmi handle 8026 * @params: DHCP server offload info 8027 * 8028 * Return: QDF_STATUS_SUCCESS for success or error code 8029 */ 8030 static QDF_STATUS 8031 send_process_dhcpserver_offload_cmd_tlv(wmi_unified_t wmi_handle, 8032 struct dhcp_offload_info_params *params) 8033 { 8034 wmi_set_dhcp_server_offload_cmd_fixed_param *cmd; 8035 wmi_buf_t buf; 8036 QDF_STATUS status; 8037 8038 buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); 8039 if (!buf) 8040 return QDF_STATUS_E_NOMEM; 8041 8042 cmd = (wmi_set_dhcp_server_offload_cmd_fixed_param *) wmi_buf_data(buf); 8043 8044 WMITLV_SET_HDR(&cmd->tlv_header, 8045 WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, 8046 WMITLV_GET_STRUCT_TLVLEN 8047 (wmi_set_dhcp_server_offload_cmd_fixed_param)); 8048 cmd->vdev_id = params->vdev_id; 8049 cmd->enable = params->dhcp_offload_enabled; 8050 cmd->num_client = params->dhcp_client_num; 8051 cmd->srv_ipv4 = params->dhcp_srv_addr; 8052 cmd->start_lsb = 0; 8053 wmi_mtrace(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID, cmd->vdev_id, 0); 8054 status = wmi_unified_cmd_send(wmi_handle, buf, 8055 sizeof(*cmd), 8056 WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); 8057 if (QDF_IS_STATUS_ERROR(status)) { 8058 wmi_err("Failed to send set_dhcp_server_offload cmd"); 8059 wmi_buf_free(buf); 8060 return QDF_STATUS_E_FAILURE; 8061 } 8062 wmi_debug("Set dhcp server offload to vdevId %d", params->vdev_id); 8063 8064 return status; 8065 } 8066 8067 /** 8068 * send_pdev_set_regdomain_cmd_tlv() - send set regdomain command to fw 8069 * @wmi_handle: wmi handle 8070 * @param: pointer to pdev regdomain params 8071 * 8072 * Return: QDF_STATUS_SUCCESS for success or error code 8073 */ 8074 static QDF_STATUS 8075 send_pdev_set_regdomain_cmd_tlv(wmi_unified_t wmi_handle, 8076 struct pdev_set_regdomain_params *param) 8077 { 8078 wmi_buf_t buf; 8079 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 8080 int32_t len = sizeof(*cmd); 8081 8082 buf = wmi_buf_alloc(wmi_handle, len); 8083 if (!buf) 8084 return QDF_STATUS_E_NOMEM; 8085 8086 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8087 WMITLV_SET_HDR(&cmd->tlv_header, 8088 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8089 WMITLV_GET_STRUCT_TLVLEN 8090 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8091 8092 cmd->reg_domain = param->currentRDinuse; 8093 cmd->reg_domain_2G = param->currentRD2G; 8094 cmd->reg_domain_5G = param->currentRD5G; 8095 cmd->conformance_test_limit_2G = param->ctl_2G; 8096 cmd->conformance_test_limit_5G = param->ctl_5G; 8097 cmd->dfs_domain = param->dfsDomain; 8098 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8099 wmi_handle, 8100 param->pdev_id); 8101 8102 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8103 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8104 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8105 wmi_err("Failed to send pdev set regdomain command"); 8106 wmi_buf_free(buf); 8107 return QDF_STATUS_E_FAILURE; 8108 } 8109 8110 return QDF_STATUS_SUCCESS; 8111 } 8112 8113 /** 8114 * send_regdomain_info_to_fw_cmd_tlv() - send regdomain info to fw 8115 * @wmi_handle: wmi handle 8116 * @reg_dmn: reg domain 8117 * @regdmn2G: 2G reg domain 8118 * @regdmn5G: 5G reg domain 8119 * @ctl2G: 2G test limit 8120 * @ctl5G: 5G test limit 8121 * 8122 * Return: none 8123 */ 8124 static QDF_STATUS send_regdomain_info_to_fw_cmd_tlv(wmi_unified_t wmi_handle, 8125 uint32_t reg_dmn, uint16_t regdmn2G, 8126 uint16_t regdmn5G, uint8_t ctl2G, 8127 uint8_t ctl5G) 8128 { 8129 wmi_buf_t buf; 8130 wmi_pdev_set_regdomain_cmd_fixed_param *cmd; 8131 int32_t len = sizeof(*cmd); 8132 8133 8134 buf = wmi_buf_alloc(wmi_handle, len); 8135 if (!buf) 8136 return QDF_STATUS_E_NOMEM; 8137 8138 cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); 8139 WMITLV_SET_HDR(&cmd->tlv_header, 8140 WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, 8141 WMITLV_GET_STRUCT_TLVLEN 8142 (wmi_pdev_set_regdomain_cmd_fixed_param)); 8143 cmd->reg_domain = reg_dmn; 8144 cmd->reg_domain_2G = regdmn2G; 8145 cmd->reg_domain_5G = regdmn5G; 8146 cmd->conformance_test_limit_2G = ctl2G; 8147 cmd->conformance_test_limit_5G = ctl5G; 8148 8149 wmi_debug("regd = %x, regd_2g = %x, regd_5g = %x, ctl_2g = %x, ctl_5g = %x", 8150 cmd->reg_domain, cmd->reg_domain_2G, cmd->reg_domain_5G, 8151 cmd->conformance_test_limit_2G, 8152 cmd->conformance_test_limit_5G); 8153 8154 wmi_mtrace(WMI_PDEV_SET_REGDOMAIN_CMDID, NO_SESSION, 0); 8155 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8156 WMI_PDEV_SET_REGDOMAIN_CMDID)) { 8157 wmi_err("Failed to send pdev set regdomain command"); 8158 wmi_buf_free(buf); 8159 return QDF_STATUS_E_FAILURE; 8160 } 8161 8162 return QDF_STATUS_SUCCESS; 8163 } 8164 8165 /** 8166 * copy_custom_aggr_bitmap() - copies host side bitmap using FW APIs 8167 * @param: param sent from the host side 8168 * @cmd: param to be sent to the fw side 8169 */ 8170 static inline void copy_custom_aggr_bitmap( 8171 struct set_custom_aggr_size_params *param, 8172 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd) 8173 { 8174 WMI_VDEV_CUSTOM_AGGR_AC_SET(cmd->enable_bitmap, 8175 param->ac); 8176 WMI_VDEV_CUSTOM_AGGR_TYPE_SET(cmd->enable_bitmap, 8177 param->aggr_type); 8178 WMI_VDEV_CUSTOM_TX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8179 param->tx_aggr_size_disable); 8180 WMI_VDEV_CUSTOM_RX_AGGR_SZ_DIS_SET(cmd->enable_bitmap, 8181 param->rx_aggr_size_disable); 8182 WMI_VDEV_CUSTOM_TX_AC_EN_SET(cmd->enable_bitmap, 8183 param->tx_ac_enable); 8184 WMI_VDEV_CUSTOM_AGGR_256_BA_EN_SET(cmd->enable_bitmap, 8185 param->aggr_ba_enable); 8186 } 8187 8188 /** 8189 * send_vdev_set_custom_aggr_size_cmd_tlv() - custom aggr size param in fw 8190 * @wmi_handle: wmi handle 8191 * @param: pointer to hold custom aggr size params 8192 * 8193 * Return: QDF_STATUS_SUCCESS for success or error code 8194 */ 8195 static QDF_STATUS send_vdev_set_custom_aggr_size_cmd_tlv( 8196 wmi_unified_t wmi_handle, 8197 struct set_custom_aggr_size_params *param) 8198 { 8199 wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; 8200 wmi_buf_t buf; 8201 int32_t len = sizeof(*cmd); 8202 8203 buf = wmi_buf_alloc(wmi_handle, len); 8204 if (!buf) 8205 return QDF_STATUS_E_FAILURE; 8206 8207 cmd = (wmi_vdev_set_custom_aggr_size_cmd_fixed_param *) 8208 wmi_buf_data(buf); 8209 WMITLV_SET_HDR(&cmd->tlv_header, 8210 WMITLV_TAG_STRUC_wmi_vdev_set_custom_aggr_size_cmd_fixed_param, 8211 WMITLV_GET_STRUCT_TLVLEN( 8212 wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); 8213 cmd->vdev_id = param->vdev_id; 8214 cmd->tx_aggr_size = param->tx_aggr_size; 8215 cmd->rx_aggr_size = param->rx_aggr_size; 8216 copy_custom_aggr_bitmap(param, cmd); 8217 8218 wmi_debug("Set custom aggr: vdev id=0x%X, tx aggr size=0x%X " 8219 "rx_aggr_size=0x%X access category=0x%X, agg_type=0x%X " 8220 "tx_aggr_size_disable=0x%X, rx_aggr_size_disable=0x%X " 8221 "tx_ac_enable=0x%X", 8222 param->vdev_id, param->tx_aggr_size, param->rx_aggr_size, 8223 param->ac, param->aggr_type, param->tx_aggr_size_disable, 8224 param->rx_aggr_size_disable, param->tx_ac_enable); 8225 8226 wmi_mtrace(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, cmd->vdev_id, 0); 8227 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8228 WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID)) { 8229 wmi_err("Setting custom aggregation size failed"); 8230 wmi_buf_free(buf); 8231 return QDF_STATUS_E_FAILURE; 8232 } 8233 8234 return QDF_STATUS_SUCCESS; 8235 } 8236 8237 /** 8238 * send_vdev_set_qdepth_thresh_cmd_tlv() - WMI set qdepth threshold 8239 * @wmi_handle: handle to WMI. 8240 * @param: pointer to tx antenna param 8241 * 8242 * Return: QDF_STATUS_SUCCESS for success or error code 8243 */ 8244 8245 static QDF_STATUS send_vdev_set_qdepth_thresh_cmd_tlv(wmi_unified_t wmi_handle, 8246 struct set_qdepth_thresh_params *param) 8247 { 8248 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *cmd; 8249 wmi_msduq_qdepth_thresh_update *cmd_update; 8250 wmi_buf_t buf; 8251 int32_t len = 0; 8252 int i; 8253 uint8_t *buf_ptr; 8254 QDF_STATUS ret; 8255 8256 if (param->num_of_msduq_updates > QDEPTH_THRESH_MAX_UPDATES) { 8257 wmi_err("Invalid Update Count!"); 8258 return QDF_STATUS_E_INVAL; 8259 } 8260 8261 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; 8262 len += (sizeof(wmi_msduq_qdepth_thresh_update) * 8263 param->num_of_msduq_updates); 8264 buf = wmi_buf_alloc(wmi_handle, len); 8265 8266 if (!buf) 8267 return QDF_STATUS_E_NOMEM; 8268 8269 buf_ptr = (uint8_t *)wmi_buf_data(buf); 8270 cmd = (wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param *) 8271 buf_ptr; 8272 8273 WMITLV_SET_HDR(&cmd->tlv_header, 8274 WMITLV_TAG_STRUC_wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param 8275 , WMITLV_GET_STRUCT_TLVLEN( 8276 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param)); 8277 8278 cmd->pdev_id = 8279 wmi_handle->ops->convert_pdev_id_host_to_target( 8280 wmi_handle, 8281 param->pdev_id); 8282 cmd->vdev_id = param->vdev_id; 8283 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac_addr, &cmd->peer_mac_address); 8284 cmd->num_of_msduq_updates = param->num_of_msduq_updates; 8285 8286 buf_ptr += sizeof( 8287 wmi_peer_tid_msduq_qdepth_thresh_update_cmd_fixed_param); 8288 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 8289 param->num_of_msduq_updates * 8290 sizeof(wmi_msduq_qdepth_thresh_update)); 8291 buf_ptr += WMI_TLV_HDR_SIZE; 8292 cmd_update = (wmi_msduq_qdepth_thresh_update *)buf_ptr; 8293 8294 for (i = 0; i < cmd->num_of_msduq_updates; i++) { 8295 WMITLV_SET_HDR(&cmd_update->tlv_header, 8296 WMITLV_TAG_STRUC_wmi_msduq_qdepth_thresh_update, 8297 WMITLV_GET_STRUCT_TLVLEN( 8298 wmi_msduq_qdepth_thresh_update)); 8299 cmd_update->tid_num = param->update_params[i].tid_num; 8300 cmd_update->msduq_update_mask = 8301 param->update_params[i].msduq_update_mask; 8302 cmd_update->qdepth_thresh_value = 8303 param->update_params[i].qdepth_thresh_value; 8304 wmi_debug("Set QDepth Threshold: vdev=0x%X pdev=0x%X, tid=0x%X " 8305 "mac_addr_upper4=%X, mac_addr_lower2:%X," 8306 " update mask=0x%X thresh val=0x%X", 8307 cmd->vdev_id, cmd->pdev_id, cmd_update->tid_num, 8308 cmd->peer_mac_address.mac_addr31to0, 8309 cmd->peer_mac_address.mac_addr47to32, 8310 cmd_update->msduq_update_mask, 8311 cmd_update->qdepth_thresh_value); 8312 cmd_update++; 8313 } 8314 8315 wmi_mtrace(WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID, 8316 cmd->vdev_id, 0); 8317 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8318 WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID); 8319 8320 if (ret != 0) { 8321 wmi_err("Failed to send WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID"); 8322 wmi_buf_free(buf); 8323 } 8324 8325 return ret; 8326 } 8327 8328 /** 8329 * send_set_vap_dscp_tid_map_cmd_tlv() - send vap dscp tid map cmd to fw 8330 * @wmi_handle: wmi handle 8331 * @param: pointer to hold vap dscp tid map param 8332 * 8333 * Return: QDF_STATUS_SUCCESS for success or error code 8334 */ 8335 static QDF_STATUS 8336 send_set_vap_dscp_tid_map_cmd_tlv(wmi_unified_t wmi_handle, 8337 struct vap_dscp_tid_map_params *param) 8338 { 8339 wmi_buf_t buf; 8340 wmi_vdev_set_dscp_tid_map_cmd_fixed_param *cmd; 8341 int32_t len = sizeof(*cmd); 8342 8343 buf = wmi_buf_alloc(wmi_handle, len); 8344 if (!buf) 8345 return QDF_STATUS_E_FAILURE; 8346 8347 cmd = (wmi_vdev_set_dscp_tid_map_cmd_fixed_param *)wmi_buf_data(buf); 8348 qdf_mem_copy(cmd->dscp_to_tid_map, param->dscp_to_tid_map, 8349 sizeof(uint32_t) * WMI_DSCP_MAP_MAX); 8350 8351 cmd->vdev_id = param->vdev_id; 8352 cmd->enable_override = 0; 8353 8354 wmi_debug("Setting dscp for vap id: %d", cmd->vdev_id); 8355 wmi_mtrace(WMI_VDEV_SET_DSCP_TID_MAP_CMDID, cmd->vdev_id, 0); 8356 if (wmi_unified_cmd_send(wmi_handle, buf, len, 8357 WMI_VDEV_SET_DSCP_TID_MAP_CMDID)) { 8358 wmi_err("Failed to set dscp cmd"); 8359 wmi_buf_free(buf); 8360 return QDF_STATUS_E_FAILURE; 8361 } 8362 8363 return QDF_STATUS_SUCCESS; 8364 } 8365 8366 /** 8367 * send_vdev_set_fwtest_param_cmd_tlv() - send fwtest param in fw 8368 * @wmi_handle: wmi handle 8369 * @param: pointer to hold fwtest param 8370 * 8371 * Return: QDF_STATUS_SUCCESS for success or error code 8372 */ 8373 static QDF_STATUS send_vdev_set_fwtest_param_cmd_tlv(wmi_unified_t wmi_handle, 8374 struct set_fwtest_params *param) 8375 { 8376 wmi_fwtest_set_param_cmd_fixed_param *cmd; 8377 wmi_buf_t buf; 8378 int32_t len = sizeof(*cmd); 8379 8380 buf = wmi_buf_alloc(wmi_handle, len); 8381 8382 if (!buf) 8383 return QDF_STATUS_E_FAILURE; 8384 8385 cmd = (wmi_fwtest_set_param_cmd_fixed_param *)wmi_buf_data(buf); 8386 WMITLV_SET_HDR(&cmd->tlv_header, 8387 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 8388 WMITLV_GET_STRUCT_TLVLEN( 8389 wmi_fwtest_set_param_cmd_fixed_param)); 8390 cmd->param_id = param->arg; 8391 cmd->param_value = param->value; 8392 8393 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 8394 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FWTEST_CMDID)) { 8395 wmi_err("Setting FW test param failed"); 8396 wmi_buf_free(buf); 8397 return QDF_STATUS_E_FAILURE; 8398 } 8399 8400 return QDF_STATUS_SUCCESS; 8401 } 8402 8403 /** 8404 * send_phyerr_disable_cmd_tlv() - WMI phyerr disable function 8405 * @wmi_handle: handle to WMI. 8406 * 8407 * Return: QDF_STATUS_SUCCESS for success or error code 8408 */ 8409 static QDF_STATUS send_phyerr_disable_cmd_tlv(wmi_unified_t wmi_handle) 8410 { 8411 wmi_pdev_dfs_disable_cmd_fixed_param *cmd; 8412 wmi_buf_t buf; 8413 QDF_STATUS ret; 8414 int32_t len; 8415 8416 len = sizeof(*cmd); 8417 8418 buf = wmi_buf_alloc(wmi_handle, len); 8419 if (!buf) 8420 return QDF_STATUS_E_FAILURE; 8421 8422 cmd = (wmi_pdev_dfs_disable_cmd_fixed_param *)wmi_buf_data(buf); 8423 WMITLV_SET_HDR(&cmd->tlv_header, 8424 WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, 8425 WMITLV_GET_STRUCT_TLVLEN( 8426 wmi_pdev_dfs_disable_cmd_fixed_param)); 8427 /* Filling it with WMI_PDEV_ID_SOC for now */ 8428 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8429 wmi_handle, 8430 WMI_HOST_PDEV_ID_SOC); 8431 8432 wmi_mtrace(WMI_PDEV_DFS_DISABLE_CMDID, NO_SESSION, 0); 8433 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8434 WMI_PDEV_DFS_DISABLE_CMDID); 8435 8436 if (ret != 0) { 8437 wmi_err("Sending PDEV DFS disable cmd failed"); 8438 wmi_buf_free(buf); 8439 } 8440 8441 return ret; 8442 } 8443 8444 /** 8445 * send_phyerr_enable_cmd_tlv() - WMI phyerr disable function 8446 * @wmi_handle: handle to WMI. 8447 * 8448 * Return: QDF_STATUS_SUCCESS for success or error code 8449 */ 8450 static QDF_STATUS send_phyerr_enable_cmd_tlv(wmi_unified_t wmi_handle) 8451 { 8452 wmi_pdev_dfs_enable_cmd_fixed_param *cmd; 8453 wmi_buf_t buf; 8454 QDF_STATUS ret; 8455 int32_t len; 8456 8457 len = sizeof(*cmd); 8458 8459 buf = wmi_buf_alloc(wmi_handle, len); 8460 if (!buf) 8461 return QDF_STATUS_E_FAILURE; 8462 8463 cmd = (wmi_pdev_dfs_enable_cmd_fixed_param *)wmi_buf_data(buf); 8464 WMITLV_SET_HDR(&cmd->tlv_header, 8465 WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, 8466 WMITLV_GET_STRUCT_TLVLEN( 8467 wmi_pdev_dfs_enable_cmd_fixed_param)); 8468 /* Reserved for future use */ 8469 cmd->reserved0 = 0; 8470 8471 wmi_mtrace(WMI_PDEV_DFS_ENABLE_CMDID, NO_SESSION, 0); 8472 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8473 WMI_PDEV_DFS_ENABLE_CMDID); 8474 8475 if (ret != 0) { 8476 wmi_err("Sending PDEV DFS enable cmd failed"); 8477 wmi_buf_free(buf); 8478 } 8479 8480 return ret; 8481 } 8482 8483 /** 8484 * send_periodic_chan_stats_config_cmd_tlv() - send periodic chan stats cmd 8485 * to fw 8486 * @wmi_handle: wmi handle 8487 * @param: pointer to hold periodic chan stats param 8488 * 8489 * Return: QDF_STATUS_SUCCESS for success or error code 8490 */ 8491 static QDF_STATUS 8492 send_periodic_chan_stats_config_cmd_tlv(wmi_unified_t wmi_handle, 8493 struct periodic_chan_stats_params *param) 8494 { 8495 wmi_set_periodic_channel_stats_config_fixed_param *cmd; 8496 wmi_buf_t buf; 8497 QDF_STATUS ret; 8498 int32_t len; 8499 8500 len = sizeof(*cmd); 8501 8502 buf = wmi_buf_alloc(wmi_handle, len); 8503 if (!buf) 8504 return QDF_STATUS_E_FAILURE; 8505 8506 cmd = (wmi_set_periodic_channel_stats_config_fixed_param *) 8507 wmi_buf_data(buf); 8508 WMITLV_SET_HDR(&cmd->tlv_header, 8509 WMITLV_TAG_STRUC_wmi_set_periodic_channel_stats_config_fixed_param, 8510 WMITLV_GET_STRUCT_TLVLEN( 8511 wmi_set_periodic_channel_stats_config_fixed_param)); 8512 cmd->enable = param->enable; 8513 cmd->stats_period = param->stats_period; 8514 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 8515 wmi_handle, 8516 param->pdev_id); 8517 8518 wmi_mtrace(WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID, NO_SESSION, 0); 8519 ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), 8520 WMI_SET_PERIODIC_CHANNEL_STATS_CONFIG_CMDID); 8521 8522 if (ret != 0) { 8523 wmi_err("Sending periodic chan stats config failed"); 8524 wmi_buf_free(buf); 8525 } 8526 8527 return ret; 8528 } 8529 8530 #ifdef WLAN_IOT_SIM_SUPPORT 8531 /** 8532 * send_simulation_test_cmd_tlv() - send simulation test command to fw 8533 * 8534 * @wmi_handle: wmi handle 8535 * @param: pointer to hold simulation test parameter 8536 * 8537 * Return: QDF_STATUS_SUCCESS for success or error code 8538 */ 8539 static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, 8540 struct simulation_test_params 8541 *param) 8542 { 8543 wmi_simulation_test_cmd_fixed_param *cmd; 8544 u32 wmi_buf_len; 8545 wmi_buf_t buf; 8546 u8 *buf_ptr; 8547 u32 aligned_len = 0; 8548 8549 wmi_buf_len = sizeof(*cmd); 8550 if (param->buf_len) { 8551 aligned_len = roundup(param->buf_len, sizeof(A_UINT32)); 8552 wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; 8553 } 8554 8555 buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); 8556 if (!buf) { 8557 wmi_err("wmi_buf_alloc failed"); 8558 return QDF_STATUS_E_NOMEM; 8559 } 8560 8561 buf_ptr = wmi_buf_data(buf); 8562 cmd = (wmi_simulation_test_cmd_fixed_param *)buf_ptr; 8563 WMITLV_SET_HDR(&cmd->tlv_header, 8564 WMITLV_TAG_STRUC_wmi_simulation_test_cmd_fixed_param, 8565 WMITLV_GET_STRUCT_TLVLEN( 8566 wmi_simulation_test_cmd_fixed_param)); 8567 cmd->pdev_id = param->pdev_id; 8568 cmd->vdev_id = param->vdev_id; 8569 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac, &cmd->peer_macaddr); 8570 cmd->test_cmd_type = param->test_cmd_type; 8571 cmd->test_subcmd_type = param->test_subcmd_type; 8572 WMI_SIM_FRAME_TYPE_SET(cmd->frame_type_subtype_seq, param->frame_type); 8573 WMI_SIM_FRAME_SUBTYPE_SET(cmd->frame_type_subtype_seq, 8574 param->frame_subtype); 8575 WMI_SIM_FRAME_SEQ_SET(cmd->frame_type_subtype_seq, param->seq); 8576 WMI_SIM_FRAME_OFFSET_SET(cmd->frame_offset_length, param->offset); 8577 WMI_SIM_FRAME_LENGTH_SET(cmd->frame_offset_length, param->frame_length); 8578 cmd->buf_len = param->buf_len; 8579 8580 if (param->buf_len) { 8581 buf_ptr += sizeof(*cmd); 8582 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, aligned_len); 8583 buf_ptr += WMI_TLV_HDR_SIZE; 8584 qdf_mem_copy(buf_ptr, param->bufp, param->buf_len); 8585 } 8586 8587 if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, 8588 WMI_SIMULATION_TEST_CMDID)) { 8589 wmi_err("Failed to send test simulation cmd"); 8590 wmi_buf_free(buf); 8591 return QDF_STATUS_E_FAILURE; 8592 } 8593 8594 return QDF_STATUS_SUCCESS; 8595 } 8596 #endif 8597 8598 #ifdef WLAN_FEATURE_11BE 8599 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ 8600 #else 8601 #define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID 8602 #endif 8603 enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) 8604 { 8605 switch (wmi_width) { 8606 case WMI_CHAN_WIDTH_20: 8607 return CH_WIDTH_20MHZ; 8608 case WMI_CHAN_WIDTH_40: 8609 return CH_WIDTH_40MHZ; 8610 case WMI_CHAN_WIDTH_80: 8611 return CH_WIDTH_80MHZ; 8612 case WMI_CHAN_WIDTH_160: 8613 return CH_WIDTH_160MHZ; 8614 case WMI_CHAN_WIDTH_80P80: 8615 return CH_WIDTH_80P80MHZ; 8616 case WMI_CHAN_WIDTH_5: 8617 return CH_WIDTH_5MHZ; 8618 case WMI_CHAN_WIDTH_10: 8619 return CH_WIDTH_10MHZ; 8620 case WMI_CHAN_WIDTH_320: 8621 return WLAN_PHY_CH_WIDTH_320MHZ; 8622 default: 8623 return CH_WIDTH_INVALID; 8624 } 8625 } 8626 8627 #ifdef WLAN_FEATURE_11BE 8628 /** 8629 * wmi_host_to_fw_phymode_11be() - convert host to fw phymode for 11be phymode 8630 * @host_phymode: phymode to convert 8631 * 8632 * Return: one of the 11be values defined in enum WMI_HOST_WLAN_PHY_MODE; 8633 * or WMI_HOST_MODE_UNKNOWN if the input is not an 11be phymode 8634 */ 8635 static WMI_HOST_WLAN_PHY_MODE 8636 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8637 { 8638 switch (host_phymode) { 8639 case WLAN_PHYMODE_11BEA_EHT20: 8640 return WMI_HOST_MODE_11BE_EHT20; 8641 case WLAN_PHYMODE_11BEA_EHT40: 8642 return WMI_HOST_MODE_11BE_EHT40; 8643 case WLAN_PHYMODE_11BEA_EHT80: 8644 return WMI_HOST_MODE_11BE_EHT80; 8645 case WLAN_PHYMODE_11BEA_EHT160: 8646 return WMI_HOST_MODE_11BE_EHT160; 8647 case WLAN_PHYMODE_11BEA_EHT320: 8648 return WMI_HOST_MODE_11BE_EHT320; 8649 case WLAN_PHYMODE_11BEG_EHT20: 8650 return WMI_HOST_MODE_11BE_EHT20_2G; 8651 case WLAN_PHYMODE_11BEG_EHT40: 8652 case WLAN_PHYMODE_11BEG_EHT40PLUS: 8653 case WLAN_PHYMODE_11BEG_EHT40MINUS: 8654 return WMI_HOST_MODE_11BE_EHT40_2G; 8655 default: 8656 return WMI_HOST_MODE_UNKNOWN; 8657 } 8658 } 8659 #else 8660 static WMI_HOST_WLAN_PHY_MODE 8661 wmi_host_to_fw_phymode_11be(enum wlan_phymode host_phymode) 8662 { 8663 return WMI_HOST_MODE_UNKNOWN; 8664 } 8665 #endif 8666 8667 WMI_HOST_WLAN_PHY_MODE wmi_host_to_fw_phymode(enum wlan_phymode host_phymode) 8668 { 8669 switch (host_phymode) { 8670 case WLAN_PHYMODE_11A: 8671 return WMI_HOST_MODE_11A; 8672 case WLAN_PHYMODE_11G: 8673 return WMI_HOST_MODE_11G; 8674 case WLAN_PHYMODE_11B: 8675 return WMI_HOST_MODE_11B; 8676 case WLAN_PHYMODE_11G_ONLY: 8677 return WMI_HOST_MODE_11GONLY; 8678 case WLAN_PHYMODE_11NA_HT20: 8679 return WMI_HOST_MODE_11NA_HT20; 8680 case WLAN_PHYMODE_11NG_HT20: 8681 return WMI_HOST_MODE_11NG_HT20; 8682 case WLAN_PHYMODE_11NA_HT40: 8683 return WMI_HOST_MODE_11NA_HT40; 8684 case WLAN_PHYMODE_11NG_HT40: 8685 case WLAN_PHYMODE_11NG_HT40PLUS: 8686 case WLAN_PHYMODE_11NG_HT40MINUS: 8687 return WMI_HOST_MODE_11NG_HT40; 8688 case WLAN_PHYMODE_11AC_VHT20: 8689 return WMI_HOST_MODE_11AC_VHT20; 8690 case WLAN_PHYMODE_11AC_VHT40: 8691 return WMI_HOST_MODE_11AC_VHT40; 8692 case WLAN_PHYMODE_11AC_VHT80: 8693 return WMI_HOST_MODE_11AC_VHT80; 8694 case WLAN_PHYMODE_11AC_VHT20_2G: 8695 return WMI_HOST_MODE_11AC_VHT20_2G; 8696 case WLAN_PHYMODE_11AC_VHT40PLUS_2G: 8697 case WLAN_PHYMODE_11AC_VHT40MINUS_2G: 8698 case WLAN_PHYMODE_11AC_VHT40_2G: 8699 return WMI_HOST_MODE_11AC_VHT40_2G; 8700 case WLAN_PHYMODE_11AC_VHT80_2G: 8701 return WMI_HOST_MODE_11AC_VHT80_2G; 8702 case WLAN_PHYMODE_11AC_VHT80_80: 8703 return WMI_HOST_MODE_11AC_VHT80_80; 8704 case WLAN_PHYMODE_11AC_VHT160: 8705 return WMI_HOST_MODE_11AC_VHT160; 8706 case WLAN_PHYMODE_11AXA_HE20: 8707 return WMI_HOST_MODE_11AX_HE20; 8708 case WLAN_PHYMODE_11AXA_HE40: 8709 return WMI_HOST_MODE_11AX_HE40; 8710 case WLAN_PHYMODE_11AXA_HE80: 8711 return WMI_HOST_MODE_11AX_HE80; 8712 case WLAN_PHYMODE_11AXA_HE80_80: 8713 return WMI_HOST_MODE_11AX_HE80_80; 8714 case WLAN_PHYMODE_11AXA_HE160: 8715 return WMI_HOST_MODE_11AX_HE160; 8716 case WLAN_PHYMODE_11AXG_HE20: 8717 return WMI_HOST_MODE_11AX_HE20_2G; 8718 case WLAN_PHYMODE_11AXG_HE40: 8719 case WLAN_PHYMODE_11AXG_HE40PLUS: 8720 case WLAN_PHYMODE_11AXG_HE40MINUS: 8721 return WMI_HOST_MODE_11AX_HE40_2G; 8722 case WLAN_PHYMODE_11AXG_HE80: 8723 return WMI_HOST_MODE_11AX_HE80_2G; 8724 default: 8725 return wmi_host_to_fw_phymode_11be(host_phymode); 8726 } 8727 } 8728 8729 /* 8730 * convert_host_to_target_ch_width()- map host channel width(enum phy_ch_width) 8731 * to wmi channel width 8732 * @chan_width: Host channel width 8733 * 8734 * Return: wmi channel width 8735 */ 8736 static 8737 wmi_channel_width convert_host_to_target_ch_width(uint32_t chan_width) 8738 { 8739 switch (chan_width) { 8740 case CH_WIDTH_20MHZ: 8741 return WMI_CHAN_WIDTH_20; 8742 case CH_WIDTH_40MHZ: 8743 return WMI_CHAN_WIDTH_40; 8744 case CH_WIDTH_80MHZ: 8745 return WMI_CHAN_WIDTH_80; 8746 case CH_WIDTH_160MHZ: 8747 return WMI_CHAN_WIDTH_160; 8748 case CH_WIDTH_80P80MHZ: 8749 return WMI_CHAN_WIDTH_80P80; 8750 case CH_WIDTH_5MHZ: 8751 return WMI_CHAN_WIDTH_5; 8752 case CH_WIDTH_10MHZ: 8753 return WMI_CHAN_WIDTH_10; 8754 #ifdef WLAN_FEATURE_11BE 8755 case CH_WIDTH_320MHZ: 8756 return WMI_CHAN_WIDTH_320; 8757 #endif 8758 default: 8759 return WMI_CHAN_WIDTH_MAX; 8760 } 8761 } 8762 8763 /** 8764 * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure 8765 * command to fw 8766 * @wmi_handle: wmi handle 8767 * @param: pointer to hold spectral config parameter 8768 * 8769 * Return: QDF_STATUS_SUCCESS for success or error code 8770 */ 8771 static QDF_STATUS send_vdev_spectral_configure_cmd_tlv(wmi_unified_t wmi_handle, 8772 struct vdev_spectral_configure_params *param) 8773 { 8774 wmi_vdev_spectral_configure_cmd_fixed_param *cmd; 8775 wmi_buf_t buf; 8776 QDF_STATUS ret; 8777 int32_t len; 8778 8779 len = sizeof(*cmd); 8780 buf = wmi_buf_alloc(wmi_handle, len); 8781 if (!buf) 8782 return QDF_STATUS_E_FAILURE; 8783 8784 cmd = (wmi_vdev_spectral_configure_cmd_fixed_param *)wmi_buf_data(buf); 8785 WMITLV_SET_HDR(&cmd->tlv_header, 8786 WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, 8787 WMITLV_GET_STRUCT_TLVLEN( 8788 wmi_vdev_spectral_configure_cmd_fixed_param)); 8789 8790 cmd->vdev_id = param->vdev_id; 8791 cmd->spectral_scan_count = param->count; 8792 cmd->spectral_scan_period = param->period; 8793 cmd->spectral_scan_priority = param->spectral_pri; 8794 cmd->spectral_scan_fft_size = param->fft_size; 8795 cmd->spectral_scan_gc_ena = param->gc_enable; 8796 cmd->spectral_scan_restart_ena = param->restart_enable; 8797 cmd->spectral_scan_noise_floor_ref = param->noise_floor_ref; 8798 cmd->spectral_scan_init_delay = param->init_delay; 8799 cmd->spectral_scan_nb_tone_thr = param->nb_tone_thr; 8800 cmd->spectral_scan_str_bin_thr = param->str_bin_thr; 8801 cmd->spectral_scan_wb_rpt_mode = param->wb_rpt_mode; 8802 cmd->spectral_scan_rssi_rpt_mode = param->rssi_rpt_mode; 8803 cmd->spectral_scan_rssi_thr = param->rssi_thr; 8804 cmd->spectral_scan_pwr_format = param->pwr_format; 8805 cmd->spectral_scan_rpt_mode = param->rpt_mode; 8806 cmd->spectral_scan_bin_scale = param->bin_scale; 8807 cmd->spectral_scan_dBm_adj = param->dbm_adj; 8808 cmd->spectral_scan_chn_mask = param->chn_mask; 8809 cmd->spectral_scan_mode = param->mode; 8810 cmd->spectral_scan_center_freq1 = param->center_freq1; 8811 cmd->spectral_scan_center_freq2 = param->center_freq2; 8812 cmd->spectral_scan_chan_width = 8813 convert_host_to_target_ch_width(param->chan_width); 8814 cmd->recapture_sample_on_gain_change = param->fft_recap; 8815 /* Not used, fill with zeros */ 8816 cmd->spectral_scan_chan_freq = 0; 8817 8818 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, cmd->vdev_id, 0); 8819 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8820 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); 8821 8822 if (ret != 0) { 8823 wmi_err("Sending set quiet cmd failed"); 8824 wmi_buf_free(buf); 8825 } 8826 8827 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID"); 8828 wmi_debug("vdev_id: %u spectral_scan_count: %u", 8829 param->vdev_id, param->count); 8830 wmi_debug("spectral_scan_period: %u spectral_scan_priority: %u", 8831 param->period, param->spectral_pri); 8832 wmi_debug("spectral_fft_recapture_cap: %u", param->fft_recap); 8833 wmi_debug("spectral_scan_fft_size: %u spectral_scan_gc_ena: %u", 8834 param->fft_size, param->gc_enable); 8835 wmi_debug("spectral_scan_restart_ena: %u", param->restart_enable); 8836 wmi_debug("spectral_scan_noise_floor_ref: %u", param->noise_floor_ref); 8837 wmi_debug("spectral_scan_init_delay: %u", param->init_delay); 8838 wmi_debug("spectral_scan_nb_tone_thr: %u", param->nb_tone_thr); 8839 wmi_debug("spectral_scan_str_bin_thr: %u", param->str_bin_thr); 8840 wmi_debug("spectral_scan_wb_rpt_mode: %u", param->wb_rpt_mode); 8841 wmi_debug("spectral_scan_rssi_rpt_mode: %u", param->rssi_rpt_mode); 8842 wmi_debug("spectral_scan_rssi_thr: %u spectral_scan_pwr_format: %u", 8843 param->rssi_thr, param->pwr_format); 8844 wmi_debug("spectral_scan_rpt_mode: %u spectral_scan_bin_scale: %u", 8845 param->rpt_mode, param->bin_scale); 8846 wmi_debug("spectral_scan_dBm_adj: %u spectral_scan_chn_mask: %u", 8847 param->dbm_adj, param->chn_mask); 8848 wmi_debug("spectral_scan_mode: %u spectral_scan_center_freq1: %u", 8849 param->mode, param->center_freq1); 8850 wmi_debug("spectral_scan_center_freq2: %u spectral_scan_chan_freq: %u", 8851 param->center_freq2, param->chan_freq); 8852 wmi_debug("spectral_scan_chan_width: %u Status: %d", 8853 param->chan_width, ret); 8854 8855 return ret; 8856 } 8857 8858 /** 8859 * send_vdev_spectral_enable_cmd_tlv() - send VDEV spectral configure 8860 * command to fw 8861 * @wmi_handle: wmi handle 8862 * @param: pointer to hold spectral enable parameter 8863 * 8864 * Return: QDF_STATUS_SUCCESS for success or error code 8865 */ 8866 static QDF_STATUS send_vdev_spectral_enable_cmd_tlv(wmi_unified_t wmi_handle, 8867 struct vdev_spectral_enable_params *param) 8868 { 8869 wmi_vdev_spectral_enable_cmd_fixed_param *cmd; 8870 wmi_buf_t buf; 8871 QDF_STATUS ret; 8872 int32_t len; 8873 8874 len = sizeof(*cmd); 8875 buf = wmi_buf_alloc(wmi_handle, len); 8876 if (!buf) 8877 return QDF_STATUS_E_FAILURE; 8878 8879 cmd = (wmi_vdev_spectral_enable_cmd_fixed_param *)wmi_buf_data(buf); 8880 WMITLV_SET_HDR(&cmd->tlv_header, 8881 WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, 8882 WMITLV_GET_STRUCT_TLVLEN( 8883 wmi_vdev_spectral_enable_cmd_fixed_param)); 8884 8885 cmd->vdev_id = param->vdev_id; 8886 8887 if (param->active_valid) { 8888 cmd->trigger_cmd = param->active ? 1 : 2; 8889 /* 1: Trigger, 2: Clear Trigger */ 8890 } else { 8891 cmd->trigger_cmd = 0; /* 0: Ignore */ 8892 } 8893 8894 if (param->enabled_valid) { 8895 cmd->enable_cmd = param->enabled ? 1 : 2; 8896 /* 1: Enable 2: Disable */ 8897 } else { 8898 cmd->enable_cmd = 0; /* 0: Ignore */ 8899 } 8900 cmd->spectral_scan_mode = param->mode; 8901 8902 wmi_debug("vdev_id = %u trigger_cmd = %u enable_cmd = %u", 8903 cmd->vdev_id, cmd->trigger_cmd, cmd->enable_cmd); 8904 wmi_debug("spectral_scan_mode = %u", cmd->spectral_scan_mode); 8905 8906 wmi_mtrace(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, cmd->vdev_id, 0); 8907 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 8908 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); 8909 8910 if (ret != 0) { 8911 wmi_err("Sending scan enable CMD failed"); 8912 wmi_buf_free(buf); 8913 } 8914 8915 wmi_debug("Sent WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, Status: %d", 8916 ret); 8917 8918 return ret; 8919 } 8920 8921 #ifdef WLAN_CONV_SPECTRAL_ENABLE 8922 static QDF_STATUS 8923 extract_pdev_sscan_fw_cmd_fixed_param_tlv( 8924 wmi_unified_t wmi_handle, 8925 uint8_t *event, struct spectral_startscan_resp_params *param) 8926 { 8927 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8928 wmi_pdev_sscan_fw_cmd_fixed_param *ev; 8929 8930 if (!wmi_handle) { 8931 wmi_err("WMI handle is null"); 8932 return QDF_STATUS_E_INVAL; 8933 } 8934 8935 if (!event) { 8936 wmi_err("WMI event is null"); 8937 return QDF_STATUS_E_INVAL; 8938 } 8939 8940 if (!param) { 8941 wmi_err("Spectral startscan response params is null"); 8942 return QDF_STATUS_E_INVAL; 8943 } 8944 8945 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8946 if (!param_buf) 8947 return QDF_STATUS_E_INVAL; 8948 8949 ev = param_buf->fixed_param; 8950 if (!ev) 8951 return QDF_STATUS_E_INVAL; 8952 8953 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 8954 wmi_handle, 8955 ev->pdev_id); 8956 param->smode = ev->spectral_scan_mode; 8957 param->num_fft_bin_index = param_buf->num_fft_bin_index; 8958 param->num_det_info = param_buf->num_det_info; 8959 8960 wmi_debug("pdev id:%u smode:%u num_fft_bin_index:%u num_det_info:%u", 8961 ev->pdev_id, ev->spectral_scan_mode, 8962 param_buf->num_fft_bin_index, param_buf->num_det_info); 8963 8964 return QDF_STATUS_SUCCESS; 8965 } 8966 8967 static QDF_STATUS 8968 extract_pdev_sscan_fft_bin_index_tlv( 8969 wmi_unified_t wmi_handle, uint8_t *event, 8970 struct spectral_fft_bin_markers_160_165mhz *param) 8971 { 8972 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf; 8973 wmi_pdev_sscan_fft_bin_index *ev; 8974 8975 param_buf = (WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *)event; 8976 if (!param_buf) 8977 return QDF_STATUS_E_INVAL; 8978 8979 ev = param_buf->fft_bin_index; 8980 if (!ev) 8981 return QDF_STATUS_E_INVAL; 8982 8983 param->start_pri80 = WMI_SSCAN_PRI80_START_BIN_GET(ev->pri80_bins); 8984 param->num_pri80 = WMI_SSCAN_PRI80_END_BIN_GET(ev->pri80_bins) - 8985 param->start_pri80 + 1; 8986 param->start_sec80 = WMI_SSCAN_SEC80_START_BIN_GET(ev->sec80_bins); 8987 param->num_sec80 = WMI_SSCAN_SEC80_END_BIN_GET(ev->sec80_bins) - 8988 param->start_sec80 + 1; 8989 param->start_5mhz = WMI_SSCAN_MID_5MHZ_START_BIN_GET(ev->mid_5mhz_bins); 8990 param->num_5mhz = WMI_SSCAN_MID_5MHZ_END_BIN_GET(ev->mid_5mhz_bins) - 8991 param->start_5mhz + 1; 8992 param->is_valid = true; 8993 8994 wmi_debug("start_pri80: %u num_pri80: %u start_sec80: %u num_sec80: %u start_5mhz: %u, num_5mhz: %u", 8995 param->start_pri80, param->num_pri80, 8996 param->start_sec80, param->num_sec80, 8997 param->start_5mhz, param->num_5mhz); 8998 8999 return QDF_STATUS_SUCCESS; 9000 } 9001 9002 /** 9003 * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information 9004 * for a spectral scan session 9005 * @wmi_handle: handle to WMI. 9006 * @event: Event buffer 9007 * @chan_info: Spectral session channel information data structure to be filled 9008 * by this API 9009 * 9010 * Return: QDF_STATUS of operation 9011 */ 9012 static QDF_STATUS 9013 extract_pdev_spectral_session_chan_info_tlv( 9014 wmi_unified_t wmi_handle, void *event, 9015 struct spectral_session_chan_info *chan_info) 9016 { 9017 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 9018 wmi_pdev_sscan_chan_info *chan_info_tlv; 9019 9020 if (!param_buf) { 9021 wmi_err("param_buf is NULL"); 9022 return QDF_STATUS_E_NULL_VALUE; 9023 } 9024 9025 if (!chan_info) { 9026 wmi_err("chan_info is NULL"); 9027 return QDF_STATUS_E_NULL_VALUE; 9028 } 9029 9030 chan_info_tlv = param_buf->chan_info; 9031 if (!chan_info_tlv) { 9032 wmi_err("chan_info tlv is not present in the event"); 9033 return QDF_STATUS_E_NULL_VALUE; 9034 } 9035 9036 wmi_debug("operating_pri20_freq:%u operating_cfreq1:%u" 9037 "operating_cfreq2:%u operating_bw:%u" 9038 "operating_puncture_20mhz_bitmap:%u" 9039 "sscan_cfreq1:%u sscan_cfreq2:%u" 9040 "sscan_bw:%u sscan_puncture_20mhz_bitmap:%u", 9041 chan_info_tlv->operating_pri20_freq, 9042 chan_info_tlv->operating_cfreq1, 9043 chan_info_tlv->operating_cfreq2, chan_info_tlv->operating_bw, 9044 chan_info_tlv->operating_puncture_20mhz_bitmap, 9045 chan_info_tlv->sscan_cfreq1, chan_info_tlv->sscan_cfreq2, 9046 chan_info_tlv->sscan_bw, 9047 chan_info_tlv->sscan_puncture_20mhz_bitmap); 9048 9049 chan_info->operating_pri20_freq = 9050 (qdf_freq_t)chan_info_tlv->operating_pri20_freq; 9051 chan_info->operating_cfreq1 = 9052 (qdf_freq_t)chan_info_tlv->operating_cfreq1; 9053 chan_info->operating_cfreq2 = 9054 (qdf_freq_t)chan_info_tlv->operating_cfreq2; 9055 chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); 9056 chan_info->operating_puncture_20mhz_bitmap = 9057 chan_info_tlv->operating_puncture_20mhz_bitmap; 9058 9059 chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; 9060 chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; 9061 chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); 9062 chan_info->sscan_puncture_20mhz_bitmap = 9063 chan_info_tlv->sscan_puncture_20mhz_bitmap; 9064 9065 return QDF_STATUS_SUCCESS; 9066 } 9067 9068 static QDF_STATUS 9069 extract_pdev_spectral_session_detector_info_tlv( 9070 wmi_unified_t wmi_handle, void *event, 9071 struct spectral_session_det_info *det_info, uint8_t idx) 9072 { 9073 WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; 9074 wmi_pdev_sscan_per_detector_info *det_info_tlv; 9075 9076 if (!param_buf) { 9077 wmi_err("param_buf is NULL"); 9078 return QDF_STATUS_E_NULL_VALUE; 9079 } 9080 9081 if (!det_info) { 9082 wmi_err("chan_info is NULL"); 9083 return QDF_STATUS_E_NULL_VALUE; 9084 } 9085 9086 if (!param_buf->det_info) { 9087 wmi_err("det_info tlv is not present in the event"); 9088 return QDF_STATUS_E_NULL_VALUE; 9089 } 9090 9091 if (idx >= param_buf->num_det_info) { 9092 wmi_err("det_info index(%u) is greater than or equal to %u", 9093 idx, param_buf->num_det_info); 9094 return QDF_STATUS_E_FAILURE; 9095 } 9096 9097 det_info_tlv = ¶m_buf->det_info[idx]; 9098 9099 wmi_debug("det_info_idx: %u detector_id:%u start_freq:%u end_freq:%u", 9100 idx, det_info_tlv->detector_id, 9101 det_info_tlv->start_freq, det_info_tlv->end_freq); 9102 9103 det_info->det_id = det_info_tlv->detector_id; 9104 det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq; 9105 det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq; 9106 9107 return QDF_STATUS_SUCCESS; 9108 } 9109 9110 /** 9111 * extract_spectral_caps_fixed_param_tlv() - Extract fixed params from Spectral 9112 * capabilities WMI event 9113 * @wmi_handle: handle to WMI. 9114 * @event: Event buffer 9115 * @params: Spectral capabilities event parameters data structure to be filled 9116 * by this API 9117 * 9118 * Return: QDF_STATUS of operation 9119 */ 9120 static QDF_STATUS 9121 extract_spectral_caps_fixed_param_tlv( 9122 wmi_unified_t wmi_handle, void *event, 9123 struct spectral_capabilities_event_params *params) 9124 { 9125 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9126 9127 if (!param_buf) { 9128 wmi_err("param_buf is NULL"); 9129 return QDF_STATUS_E_NULL_VALUE; 9130 } 9131 9132 if (!params) { 9133 wmi_err("event parameters is NULL"); 9134 return QDF_STATUS_E_NULL_VALUE; 9135 } 9136 9137 params->num_sscan_bw_caps = param_buf->num_sscan_bw_caps; 9138 params->num_fft_size_caps = param_buf->num_fft_size_caps; 9139 9140 wmi_debug("num_sscan_bw_caps:%u num_fft_size_caps:%u", 9141 params->num_sscan_bw_caps, params->num_fft_size_caps); 9142 9143 return QDF_STATUS_SUCCESS; 9144 } 9145 9146 /** 9147 * extract_spectral_scan_bw_caps_tlv() - Extract bandwidth caps from 9148 * Spectral capabilities WMI event 9149 * @wmi_handle: handle to WMI. 9150 * @event: Event buffer 9151 * @bw_caps: Data structure to be populated by this API after extraction 9152 * 9153 * Return: QDF_STATUS of operation 9154 */ 9155 static QDF_STATUS 9156 extract_spectral_scan_bw_caps_tlv( 9157 wmi_unified_t wmi_handle, void *event, 9158 struct spectral_scan_bw_capabilities *bw_caps) 9159 { 9160 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9161 int idx; 9162 9163 if (!param_buf) { 9164 wmi_err("param_buf is NULL"); 9165 return QDF_STATUS_E_NULL_VALUE; 9166 } 9167 9168 if (!bw_caps) { 9169 wmi_err("bw_caps is null"); 9170 return QDF_STATUS_E_NULL_VALUE; 9171 } 9172 9173 for (idx = 0; idx < param_buf->num_sscan_bw_caps; idx++) { 9174 bw_caps[idx].pdev_id = 9175 wmi_handle->ops->convert_pdev_id_target_to_host( 9176 wmi_handle, 9177 param_buf->sscan_bw_caps[idx].pdev_id); 9178 bw_caps[idx].smode = param_buf->sscan_bw_caps[idx].sscan_mode; 9179 bw_caps[idx].operating_bw = wmi_map_ch_width( 9180 param_buf->sscan_bw_caps[idx].operating_bw); 9181 bw_caps[idx].supported_bws = 9182 param_buf->sscan_bw_caps[idx].supported_flags; 9183 9184 wmi_debug("bw_caps[%u]:: pdev_id:%u smode:%u" 9185 "operating_bw:%u supported_flags:0x%x", 9186 idx, param_buf->sscan_bw_caps[idx].pdev_id, 9187 param_buf->sscan_bw_caps[idx].sscan_mode, 9188 param_buf->sscan_bw_caps[idx].operating_bw, 9189 param_buf->sscan_bw_caps[idx].supported_flags); 9190 } 9191 9192 return QDF_STATUS_SUCCESS; 9193 } 9194 9195 /** 9196 * extract_spectral_fft_size_caps_tlv() - Extract FFT size caps from 9197 * Spectral capabilities WMI event 9198 * @wmi_handle: handle to WMI. 9199 * @event: Event buffer 9200 * @fft_size_caps: Data structure to be populated by this API after extraction 9201 * 9202 * Return: QDF_STATUS of operation 9203 */ 9204 static QDF_STATUS 9205 extract_spectral_fft_size_caps_tlv( 9206 wmi_unified_t wmi_handle, void *event, 9207 struct spectral_fft_size_capabilities *fft_size_caps) 9208 { 9209 WMI_SPECTRAL_CAPABILITIES_EVENTID_param_tlvs *param_buf = event; 9210 int idx; 9211 9212 if (!param_buf) { 9213 wmi_err("param_buf is NULL"); 9214 return QDF_STATUS_E_NULL_VALUE; 9215 } 9216 9217 if (!fft_size_caps) { 9218 wmi_err("fft size caps is NULL"); 9219 return QDF_STATUS_E_NULL_VALUE; 9220 } 9221 9222 for (idx = 0; idx < param_buf->num_fft_size_caps; idx++) { 9223 fft_size_caps[idx].pdev_id = 9224 wmi_handle->ops->convert_pdev_id_target_to_host( 9225 wmi_handle, 9226 param_buf->fft_size_caps[idx].pdev_id); 9227 fft_size_caps[idx].sscan_bw = wmi_map_ch_width( 9228 param_buf->fft_size_caps[idx].sscan_bw); 9229 fft_size_caps[idx].supports_fft_sizes = 9230 param_buf->fft_size_caps[idx].supported_flags; 9231 9232 wmi_debug("fft_size_caps[%u]:: pdev_id:%u sscan_bw:%u" 9233 "supported_flags:0x%x", 9234 idx, param_buf->fft_size_caps[idx].pdev_id, 9235 param_buf->fft_size_caps[idx].sscan_bw, 9236 param_buf->fft_size_caps[idx].supported_flags); 9237 } 9238 9239 return QDF_STATUS_SUCCESS; 9240 } 9241 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 9242 9243 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 9244 static inline void 9245 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9246 struct thermal_mitigation_params *param) 9247 { 9248 tt_conf->client_id = param->client_id; 9249 tt_conf->priority = param->priority; 9250 } 9251 #else 9252 static inline void 9253 wmi_fill_client_id_priority(wmi_therm_throt_config_request_fixed_param *tt_conf, 9254 struct thermal_mitigation_params *param) 9255 { 9256 } 9257 #endif 9258 9259 /** 9260 * send_thermal_mitigation_param_cmd_tlv() - configure thermal mitigation params 9261 * @wmi_handle : handle to WMI. 9262 * @param : pointer to hold thermal mitigation param 9263 * 9264 * Return: QDF_STATUS_SUCCESS for success or error code 9265 */ 9266 static QDF_STATUS send_thermal_mitigation_param_cmd_tlv( 9267 wmi_unified_t wmi_handle, 9268 struct thermal_mitigation_params *param) 9269 { 9270 wmi_therm_throt_config_request_fixed_param *tt_conf = NULL; 9271 wmi_therm_throt_level_config_info *lvl_conf = NULL; 9272 wmi_buf_t buf = NULL; 9273 uint8_t *buf_ptr = NULL; 9274 int error; 9275 int32_t len; 9276 int i; 9277 9278 len = sizeof(*tt_conf) + WMI_TLV_HDR_SIZE + 9279 param->num_thermal_conf * 9280 sizeof(wmi_therm_throt_level_config_info); 9281 9282 buf = wmi_buf_alloc(wmi_handle, len); 9283 if (!buf) 9284 return QDF_STATUS_E_NOMEM; 9285 9286 tt_conf = (wmi_therm_throt_config_request_fixed_param *) wmi_buf_data(buf); 9287 9288 /* init fixed params */ 9289 WMITLV_SET_HDR(tt_conf, 9290 WMITLV_TAG_STRUC_wmi_therm_throt_config_request_fixed_param, 9291 (WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_config_request_fixed_param))); 9292 9293 tt_conf->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 9294 wmi_handle, 9295 param->pdev_id); 9296 tt_conf->enable = param->enable; 9297 tt_conf->dc = param->dc; 9298 tt_conf->dc_per_event = param->dc_per_event; 9299 tt_conf->therm_throt_levels = param->num_thermal_conf; 9300 wmi_fill_client_id_priority(tt_conf, param); 9301 buf_ptr = (uint8_t *) ++tt_conf; 9302 /* init TLV params */ 9303 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9304 (param->num_thermal_conf * 9305 sizeof(wmi_therm_throt_level_config_info))); 9306 9307 lvl_conf = (wmi_therm_throt_level_config_info *) (buf_ptr + WMI_TLV_HDR_SIZE); 9308 for (i = 0; i < param->num_thermal_conf; i++) { 9309 WMITLV_SET_HDR(&lvl_conf->tlv_header, 9310 WMITLV_TAG_STRUC_wmi_therm_throt_level_config_info, 9311 WMITLV_GET_STRUCT_TLVLEN(wmi_therm_throt_level_config_info)); 9312 lvl_conf->temp_lwm = param->levelconf[i].tmplwm; 9313 lvl_conf->temp_hwm = param->levelconf[i].tmphwm; 9314 lvl_conf->dc_off_percent = param->levelconf[i].dcoffpercent; 9315 lvl_conf->prio = param->levelconf[i].priority; 9316 lvl_conf++; 9317 } 9318 9319 wmi_mtrace(WMI_THERM_THROT_SET_CONF_CMDID, NO_SESSION, 0); 9320 error = wmi_unified_cmd_send(wmi_handle, buf, len, 9321 WMI_THERM_THROT_SET_CONF_CMDID); 9322 if (QDF_IS_STATUS_ERROR(error)) { 9323 wmi_buf_free(buf); 9324 wmi_err("Failed to send WMI_THERM_THROT_SET_CONF_CMDID command"); 9325 } 9326 9327 return error; 9328 } 9329 9330 /** 9331 * send_coex_config_cmd_tlv() - send coex config command to fw 9332 * @wmi_handle: wmi handle 9333 * @param: pointer to coex config param 9334 * 9335 * Return: QDF_STATUS_SUCCESS for success or error code 9336 */ 9337 static QDF_STATUS 9338 send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, 9339 struct coex_config_params *param) 9340 { 9341 WMI_COEX_CONFIG_CMD_fixed_param *cmd; 9342 wmi_buf_t buf; 9343 QDF_STATUS ret; 9344 int32_t len; 9345 9346 len = sizeof(*cmd); 9347 buf = wmi_buf_alloc(wmi_handle, len); 9348 if (!buf) 9349 return QDF_STATUS_E_FAILURE; 9350 9351 cmd = (WMI_COEX_CONFIG_CMD_fixed_param *)wmi_buf_data(buf); 9352 WMITLV_SET_HDR(&cmd->tlv_header, 9353 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9354 WMITLV_GET_STRUCT_TLVLEN( 9355 WMI_COEX_CONFIG_CMD_fixed_param)); 9356 9357 cmd->vdev_id = param->vdev_id; 9358 cmd->config_type = param->config_type; 9359 cmd->config_arg1 = param->config_arg1; 9360 cmd->config_arg2 = param->config_arg2; 9361 cmd->config_arg3 = param->config_arg3; 9362 cmd->config_arg4 = param->config_arg4; 9363 cmd->config_arg5 = param->config_arg5; 9364 cmd->config_arg6 = param->config_arg6; 9365 9366 wmi_mtrace(WMI_COEX_CONFIG_CMDID, cmd->vdev_id, 0); 9367 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9368 WMI_COEX_CONFIG_CMDID); 9369 9370 if (ret != 0) { 9371 wmi_err("Sending COEX CONFIG CMD failed"); 9372 wmi_buf_free(buf); 9373 } 9374 9375 return ret; 9376 } 9377 9378 /** 9379 * send_coex_multi_config_cmd_tlv() - send coex multiple config command to fw 9380 * @wmi_handle: wmi handle 9381 * @param: pointer to coex multiple config parameters 9382 * 9383 * Return: QDF_STATUS_SUCCESS for success or error code 9384 */ 9385 static QDF_STATUS 9386 send_coex_multi_config_cmd_tlv(wmi_unified_t wmi_handle, 9387 struct coex_multi_config *param) 9388 { 9389 wmi_coex_multiple_config_cmd_fixed_param *cmd; 9390 WMI_COEX_CONFIG_CMD_fixed_param *dst_cfg; 9391 struct coex_config_item *src_cfg; 9392 wmi_buf_t buf; 9393 QDF_STATUS ret; 9394 uint32_t len, i; 9395 uint8_t *buf_ptr; 9396 9397 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 9398 param->num_configs * sizeof(*dst_cfg); 9399 buf = wmi_buf_alloc(wmi_handle, len); 9400 if (!buf) 9401 return QDF_STATUS_E_FAILURE; 9402 9403 buf_ptr = (uint8_t *)wmi_buf_data(buf); 9404 cmd = (wmi_coex_multiple_config_cmd_fixed_param *)buf_ptr; 9405 WMITLV_SET_HDR(&cmd->tlv_header, 9406 WMITLV_TAG_STRUC_wmi_coex_multiple_config_cmd_fixed_param, 9407 WMITLV_GET_STRUCT_TLVLEN( 9408 wmi_coex_multiple_config_cmd_fixed_param)); 9409 9410 buf_ptr += sizeof(*cmd); 9411 9412 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 9413 sizeof(*dst_cfg) * param->num_configs); 9414 buf_ptr += WMI_TLV_HDR_SIZE; 9415 9416 dst_cfg = (WMI_COEX_CONFIG_CMD_fixed_param *)buf_ptr; 9417 for (i = 0; i < param->num_configs; i++, dst_cfg++) { 9418 src_cfg = ¶m->cfg_items[i]; 9419 WMITLV_SET_HDR(&dst_cfg->tlv_header, 9420 WMITLV_TAG_STRUC_WMI_COEX_CONFIG_CMD_fixed_param, 9421 WMITLV_GET_STRUCT_TLVLEN( 9422 WMI_COEX_CONFIG_CMD_fixed_param)); 9423 dst_cfg->vdev_id = param->vdev_id; 9424 dst_cfg->config_type = src_cfg->config_type; 9425 dst_cfg->config_arg1 = src_cfg->config_arg1; 9426 dst_cfg->config_arg2 = src_cfg->config_arg2; 9427 dst_cfg->config_arg3 = src_cfg->config_arg3; 9428 dst_cfg->config_arg4 = src_cfg->config_arg4; 9429 dst_cfg->config_arg5 = src_cfg->config_arg5; 9430 dst_cfg->config_arg6 = src_cfg->config_arg6; 9431 } 9432 9433 wmi_mtrace(WMI_COEX_MULTIPLE_CONFIG_CMDID, param->vdev_id, 0); 9434 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9435 WMI_COEX_MULTIPLE_CONFIG_CMDID); 9436 9437 if (QDF_IS_STATUS_ERROR(ret)) { 9438 wmi_err("Sending COEX MULTIPLE CONFIG CMD failed"); 9439 wmi_buf_free(buf); 9440 } 9441 9442 return ret; 9443 } 9444 9445 #ifdef WLAN_FEATURE_DBAM_CONFIG 9446 9447 static enum wmi_coex_dbam_mode_type 9448 map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) 9449 { 9450 switch (mode) { 9451 case COEX_DBAM_ENABLE: 9452 return WMI_COEX_DBAM_ENABLE; 9453 case COEX_DBAM_FORCE_ENABLE: 9454 return WMI_COEX_DBAM_FORCED; 9455 case COEX_DBAM_DISABLE: 9456 default: 9457 return WMI_COEX_DBAM_DISABLE; 9458 } 9459 } 9460 9461 /** 9462 * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw 9463 * @wmi_handle: wmi handle 9464 * @param: pointer to coex dbam config param 9465 * 9466 * Return: QDF_STATUS_SUCCESS for success or error code 9467 */ 9468 static QDF_STATUS 9469 send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, 9470 struct coex_dbam_config_params *param) 9471 { 9472 wmi_coex_dbam_cmd_fixed_param *cmd; 9473 wmi_buf_t buf; 9474 void *buf_ptr; 9475 QDF_STATUS ret; 9476 int32_t len; 9477 9478 len = sizeof(*cmd); 9479 buf = wmi_buf_alloc(wmi_handle, len); 9480 if (!buf) { 9481 wmi_err_rl("Failed to allocate wmi buffer"); 9482 return QDF_STATUS_E_NOMEM; 9483 } 9484 9485 buf_ptr = wmi_buf_data(buf); 9486 cmd = buf_ptr; 9487 WMITLV_SET_HDR(&cmd->tlv_header, 9488 WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, 9489 WMITLV_GET_STRUCT_TLVLEN( 9490 wmi_coex_dbam_cmd_fixed_param)); 9491 9492 cmd->vdev_id = param->vdev_id; 9493 cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); 9494 9495 wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); 9496 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 9497 WMI_COEX_DBAM_CMDID); 9498 9499 if (QDF_IS_STATUS_ERROR(ret)) { 9500 wmi_err("Sending DBAM CONFIG CMD failed"); 9501 wmi_buf_free(buf); 9502 return QDF_STATUS_E_FAILURE; 9503 } 9504 9505 return ret; 9506 } 9507 9508 static enum coex_dbam_comp_status 9509 wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) 9510 { 9511 switch (status) { 9512 case WMI_COEX_DBAM_COMP_SUCCESS: 9513 case WMI_COEX_DBAM_COMP_ONGOING: 9514 case WMI_COEX_DBAM_COMP_DELAYED: 9515 return COEX_DBAM_COMP_SUCCESS; 9516 case WMI_COEX_DBAM_COMP_NOT_SUPPORT: 9517 return COEX_DBAM_COMP_NOT_SUPPORT; 9518 case WMI_COEX_DBAM_COMP_INVALID_PARAM: 9519 case WMI_COEX_DBAM_COMP_FAIL: 9520 default: 9521 return COEX_DBAM_COMP_FAIL; 9522 } 9523 } 9524 9525 /** 9526 * extract_dbam_config_resp_event_tlv() - extract dbam complete status event 9527 * @wmi_handle: WMI handle 9528 * @evt_buf: event buffer 9529 * @resp: pointer to coex dbam config response 9530 * 9531 * Return: QDF_STATUS 9532 */ 9533 static QDF_STATUS 9534 extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 9535 struct coex_dbam_config_resp *resp) 9536 { 9537 WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; 9538 wmi_coex_dbam_complete_event_fixed_param *event; 9539 9540 param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; 9541 9542 event = param_buf->fixed_param; 9543 9544 resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); 9545 9546 return QDF_STATUS_SUCCESS; 9547 } 9548 #endif 9549 9550 #ifdef WLAN_SUPPORT_TWT 9551 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9552 target_resource_config *tgt_res_cfg) 9553 { 9554 resource_cfg->twt_ap_pdev_count = tgt_res_cfg->twt_ap_pdev_count; 9555 resource_cfg->twt_ap_sta_count = tgt_res_cfg->twt_ap_sta_count; 9556 } 9557 #else 9558 static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, 9559 target_resource_config *tgt_res_cfg) 9560 { 9561 resource_cfg->twt_ap_pdev_count = 0; 9562 resource_cfg->twt_ap_sta_count = 0; 9563 } 9564 #endif 9565 9566 #ifdef WLAN_FEATURE_NAN 9567 static void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9568 { 9569 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_CHANNEL_SUPPORT_SET( 9570 resource_cfg->host_service_flags, 1); 9571 } 9572 #else 9573 static inline 9574 void wmi_set_nan_channel_support(wmi_resource_config *resource_cfg) 9575 { 9576 } 9577 #endif 9578 9579 #if defined(CONFIG_AFC_SUPPORT) 9580 static 9581 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9582 target_resource_config *tgt_res_cfg) 9583 { 9584 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_INDOOR_SUPPORT_CHECK_SET( 9585 resource_cfg->host_service_flags, 9586 tgt_res_cfg->afc_indoor_support); 9587 9588 WMI_RSRC_CFG_HOST_SERVICE_FLAG_AFC_OUTDOOR_SUPPORT_CHECK_SET( 9589 resource_cfg->host_service_flags, 9590 tgt_res_cfg->afc_outdoor_support); 9591 } 9592 #else 9593 static 9594 void wmi_copy_afc_deployment_config(wmi_resource_config *resource_cfg, 9595 target_resource_config *tgt_res_cfg) 9596 { 9597 } 9598 #endif 9599 9600 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 9601 static inline 9602 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9603 target_resource_config *tgt_res_cfg) 9604 { 9605 if (tgt_res_cfg->tx_ilp_enable) 9606 WMI_RSRC_CFG_FLAGS2_LATENCY_FLOWQ_SUPPORT_SET( 9607 resource_cfg->flags2, 1); 9608 } 9609 #else 9610 static inline 9611 void wmi_copy_latency_flowq_support(wmi_resource_config *resource_cfg, 9612 target_resource_config *tgt_res_cfg) 9613 { 9614 } 9615 #endif 9616 9617 #ifdef MOBILE_DFS_SUPPORT 9618 static inline 9619 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9620 target_resource_config *tgt_res_cfg) 9621 { 9622 WMI_RSRC_CFG_HOST_SERVICE_FLAG_RADAR_FLAGS_FULL_BW_NOL_SET(resource_cfg->host_service_flags, 9623 tgt_res_cfg->is_full_bw_nol_supported); 9624 } 9625 #else 9626 static inline 9627 void wmi_copy_full_bw_nol_cfg(wmi_resource_config *resource_cfg, 9628 target_resource_config *tgt_res_cfg) 9629 { 9630 } 9631 #endif 9632 9633 static 9634 void wmi_copy_resource_config(wmi_resource_config *resource_cfg, 9635 target_resource_config *tgt_res_cfg) 9636 { 9637 resource_cfg->num_vdevs = tgt_res_cfg->num_vdevs; 9638 resource_cfg->num_peers = tgt_res_cfg->num_peers; 9639 resource_cfg->num_offload_peers = tgt_res_cfg->num_offload_peers; 9640 resource_cfg->num_offload_reorder_buffs = 9641 tgt_res_cfg->num_offload_reorder_buffs; 9642 resource_cfg->num_peer_keys = tgt_res_cfg->num_peer_keys; 9643 resource_cfg->num_tids = tgt_res_cfg->num_tids; 9644 resource_cfg->ast_skid_limit = tgt_res_cfg->ast_skid_limit; 9645 resource_cfg->tx_chain_mask = tgt_res_cfg->tx_chain_mask; 9646 resource_cfg->rx_chain_mask = tgt_res_cfg->rx_chain_mask; 9647 resource_cfg->rx_timeout_pri[0] = tgt_res_cfg->rx_timeout_pri[0]; 9648 resource_cfg->rx_timeout_pri[1] = tgt_res_cfg->rx_timeout_pri[1]; 9649 resource_cfg->rx_timeout_pri[2] = tgt_res_cfg->rx_timeout_pri[2]; 9650 resource_cfg->rx_timeout_pri[3] = tgt_res_cfg->rx_timeout_pri[3]; 9651 resource_cfg->rx_decap_mode = tgt_res_cfg->rx_decap_mode; 9652 resource_cfg->scan_max_pending_req = 9653 tgt_res_cfg->scan_max_pending_req; 9654 resource_cfg->bmiss_offload_max_vdev = 9655 tgt_res_cfg->bmiss_offload_max_vdev; 9656 resource_cfg->roam_offload_max_vdev = 9657 tgt_res_cfg->roam_offload_max_vdev; 9658 resource_cfg->roam_offload_max_ap_profiles = 9659 tgt_res_cfg->roam_offload_max_ap_profiles; 9660 resource_cfg->num_mcast_groups = tgt_res_cfg->num_mcast_groups; 9661 resource_cfg->num_mcast_table_elems = 9662 tgt_res_cfg->num_mcast_table_elems; 9663 resource_cfg->mcast2ucast_mode = tgt_res_cfg->mcast2ucast_mode; 9664 resource_cfg->tx_dbg_log_size = tgt_res_cfg->tx_dbg_log_size; 9665 resource_cfg->num_wds_entries = tgt_res_cfg->num_wds_entries; 9666 resource_cfg->dma_burst_size = tgt_res_cfg->dma_burst_size; 9667 resource_cfg->mac_aggr_delim = tgt_res_cfg->mac_aggr_delim; 9668 resource_cfg->rx_skip_defrag_timeout_dup_detection_check = 9669 tgt_res_cfg->rx_skip_defrag_timeout_dup_detection_check; 9670 resource_cfg->vow_config = tgt_res_cfg->vow_config; 9671 resource_cfg->gtk_offload_max_vdev = tgt_res_cfg->gtk_offload_max_vdev; 9672 resource_cfg->num_msdu_desc = tgt_res_cfg->num_msdu_desc; 9673 resource_cfg->max_frag_entries = tgt_res_cfg->max_frag_entries; 9674 resource_cfg->num_tdls_vdevs = tgt_res_cfg->num_tdls_vdevs; 9675 resource_cfg->num_tdls_conn_table_entries = 9676 tgt_res_cfg->num_tdls_conn_table_entries; 9677 resource_cfg->beacon_tx_offload_max_vdev = 9678 tgt_res_cfg->beacon_tx_offload_max_vdev; 9679 resource_cfg->num_multicast_filter_entries = 9680 tgt_res_cfg->num_multicast_filter_entries; 9681 resource_cfg->num_wow_filters = 9682 tgt_res_cfg->num_wow_filters; 9683 resource_cfg->num_keep_alive_pattern = 9684 tgt_res_cfg->num_keep_alive_pattern; 9685 resource_cfg->keep_alive_pattern_size = 9686 tgt_res_cfg->keep_alive_pattern_size; 9687 resource_cfg->max_tdls_concurrent_sleep_sta = 9688 tgt_res_cfg->max_tdls_concurrent_sleep_sta; 9689 resource_cfg->max_tdls_concurrent_buffer_sta = 9690 tgt_res_cfg->max_tdls_concurrent_buffer_sta; 9691 resource_cfg->wmi_send_separate = 9692 tgt_res_cfg->wmi_send_separate; 9693 resource_cfg->num_ocb_vdevs = 9694 tgt_res_cfg->num_ocb_vdevs; 9695 resource_cfg->num_ocb_channels = 9696 tgt_res_cfg->num_ocb_channels; 9697 resource_cfg->num_ocb_schedules = 9698 tgt_res_cfg->num_ocb_schedules; 9699 resource_cfg->bpf_instruction_size = tgt_res_cfg->apf_instruction_size; 9700 resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters; 9701 resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id; 9702 resource_cfg->max_num_dbs_scan_duty_cycle = 9703 tgt_res_cfg->max_num_dbs_scan_duty_cycle; 9704 resource_cfg->sched_params = tgt_res_cfg->scheduler_params; 9705 resource_cfg->num_packet_filters = tgt_res_cfg->num_packet_filters; 9706 resource_cfg->num_max_sta_vdevs = tgt_res_cfg->num_max_sta_vdevs; 9707 resource_cfg->max_bssid_indicator = tgt_res_cfg->max_bssid_indicator; 9708 resource_cfg->max_num_group_keys = tgt_res_cfg->max_num_group_keys; 9709 /* Deferred AI: Max rnr neighbors supported in multisoc case 9710 * where in SoC can support 6ghz. During WMI init of a SoC 9711 * currently there is no way to figure if another SOC is plugged in 9712 * and it can support 6Ghz. 9713 */ 9714 resource_cfg->max_rnr_neighbours = MAX_SUPPORTED_NEIGHBORS; 9715 resource_cfg->ema_max_vap_cnt = tgt_res_cfg->ema_max_vap_cnt; 9716 resource_cfg->ema_max_profile_period = 9717 tgt_res_cfg->ema_max_profile_period; 9718 resource_cfg->ema_init_config = tgt_res_cfg->ema_init_config; 9719 resource_cfg->carrier_config = tgt_res_cfg->carrier_profile_config; 9720 9721 if (tgt_res_cfg->max_ndp_sessions) 9722 resource_cfg->max_ndp_sessions = 9723 tgt_res_cfg->max_ndp_sessions; 9724 resource_cfg->max_ndi_interfaces = tgt_res_cfg->max_ndi; 9725 resource_cfg->num_max_active_vdevs = tgt_res_cfg->num_max_active_vdevs; 9726 resource_cfg->num_max_mlo_link_per_ml_bss = 9727 tgt_res_cfg->num_max_mlo_link_per_ml_bss; 9728 9729 if (tgt_res_cfg->atf_config) 9730 WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1); 9731 if (tgt_res_cfg->mgmt_comp_evt_bundle_support) 9732 WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET( 9733 resource_cfg->flag1, 1); 9734 if (tgt_res_cfg->tx_msdu_new_partition_id_support) 9735 WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET( 9736 resource_cfg->flag1, 1); 9737 if (tgt_res_cfg->cce_disable) 9738 WMI_RSRC_CFG_FLAG_TCL_CCE_DISABLE_SET(resource_cfg->flag1, 1); 9739 if (tgt_res_cfg->enable_pci_gen) 9740 WMI_RSRC_CFG_FLAG_PCIE_GEN_SWITCH_CAPABLITY_SET( 9741 resource_cfg->flag1, 1); 9742 if (tgt_res_cfg->eapol_minrate_set) { 9743 WMI_RSRC_CFG_FLAG_EAPOL_REKEY_MINRATE_SUPPORT_ENABLE_SET( 9744 resource_cfg->flag1, 1); 9745 if (tgt_res_cfg->eapol_minrate_ac_set != 3) { 9746 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_VALID_SET( 9747 resource_cfg->flag1, 1); 9748 WMI_RSRC_CFG_FLAG_EAPOL_AC_OVERRIDE_SET( 9749 resource_cfg->flag1, 9750 tgt_res_cfg->eapol_minrate_ac_set); 9751 } 9752 } 9753 if (tgt_res_cfg->new_htt_msg_format) { 9754 WMI_RSRC_CFG_FLAG_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN_SET( 9755 resource_cfg->flag1, 1); 9756 } 9757 9758 if (tgt_res_cfg->peer_unmap_conf_support) 9759 WMI_RSRC_CFG_FLAG_PEER_UNMAP_RESPONSE_SUPPORT_SET( 9760 resource_cfg->flag1, 1); 9761 9762 if (tgt_res_cfg->tstamp64_en) 9763 WMI_RSRC_CFG_FLAG_TX_COMPLETION_TX_TSF64_ENABLE_SET( 9764 resource_cfg->flag1, 1); 9765 9766 if (tgt_res_cfg->three_way_coex_config_legacy_en) 9767 WMI_RSRC_CFG_FLAG_THREE_WAY_COEX_CONFIG_LEGACY_SUPPORT_SET( 9768 resource_cfg->flag1, 1); 9769 if (tgt_res_cfg->pktcapture_support) 9770 WMI_RSRC_CFG_FLAG_PACKET_CAPTURE_SUPPORT_SET( 9771 resource_cfg->flag1, 1); 9772 9773 /* 9774 * Control padding using config param/ini of iphdr_pad_config 9775 */ 9776 if (tgt_res_cfg->iphdr_pad_config) 9777 WMI_RSRC_CFG_FLAG_IPHR_PAD_CONFIG_ENABLE_SET( 9778 resource_cfg->flag1, 1); 9779 9780 WMI_RSRC_CFG_FLAG_IPA_DISABLE_SET(resource_cfg->flag1, 9781 tgt_res_cfg->ipa_disable); 9782 9783 if (tgt_res_cfg->time_sync_ftm) 9784 WMI_RSRC_CFG_FLAG_AUDIO_SYNC_SUPPORT_SET(resource_cfg->flag1, 9785 1); 9786 9787 wmi_copy_twt_resource_config(resource_cfg, tgt_res_cfg); 9788 resource_cfg->peer_map_unmap_versions = 9789 tgt_res_cfg->peer_map_unmap_version; 9790 resource_cfg->smart_ant_cap = tgt_res_cfg->smart_ant_cap; 9791 if (tgt_res_cfg->re_ul_resp) 9792 WMI_SET_BITS(resource_cfg->flags2, 0, 4, 9793 tgt_res_cfg->re_ul_resp); 9794 9795 /* 9796 * Enable Service Aware Wifi 9797 */ 9798 if (tgt_res_cfg->sawf) 9799 WMI_RSRC_CFG_FLAGS2_SAWF_CONFIG_ENABLE_SET(resource_cfg->flags2, 9800 tgt_res_cfg->sawf); 9801 9802 /* 9803 * Enable ast flow override per peer 9804 */ 9805 resource_cfg->msdu_flow_override_config0 = 0; 9806 WMI_MSDU_FLOW_AST_ENABLE_SET( 9807 resource_cfg->msdu_flow_override_config0, 9808 WMI_CONFIG_MSDU_AST_INDEX_1, 9809 tgt_res_cfg->ast_1_valid_mask_enable); 9810 9811 WMI_MSDU_FLOW_AST_ENABLE_SET( 9812 resource_cfg->msdu_flow_override_config0, 9813 WMI_CONFIG_MSDU_AST_INDEX_2, 9814 tgt_res_cfg->ast_2_valid_mask_enable); 9815 9816 WMI_MSDU_FLOW_AST_ENABLE_SET( 9817 resource_cfg->msdu_flow_override_config0, 9818 WMI_CONFIG_MSDU_AST_INDEX_3, 9819 tgt_res_cfg->ast_3_valid_mask_enable); 9820 9821 /* 9822 * Enable ast flow mask and TID valid mask configurations 9823 */ 9824 resource_cfg->msdu_flow_override_config1 = 0; 9825 9826 /*Enable UDP flow for Ast index 0*/ 9827 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9828 resource_cfg->msdu_flow_override_config1, 9829 WMI_CONFIG_MSDU_AST_INDEX_0, 9830 tgt_res_cfg->ast_0_flow_mask_enable); 9831 9832 /*Enable Non UDP flow for Ast index 1*/ 9833 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9834 resource_cfg->msdu_flow_override_config1, 9835 WMI_CONFIG_MSDU_AST_INDEX_1, 9836 tgt_res_cfg->ast_1_flow_mask_enable); 9837 9838 /*Enable Hi-Priority flow for Ast index 2*/ 9839 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9840 resource_cfg->msdu_flow_override_config1, 9841 WMI_CONFIG_MSDU_AST_INDEX_2, 9842 tgt_res_cfg->ast_2_flow_mask_enable); 9843 9844 /*Enable Low-Priority flow for Ast index 3*/ 9845 WMI_MSDU_FLOW_ASTX_MSDU_FLOW_MASKS_SET( 9846 resource_cfg->msdu_flow_override_config1, 9847 WMI_CONFIG_MSDU_AST_INDEX_3, 9848 tgt_res_cfg->ast_3_flow_mask_enable); 9849 9850 /*Enable all 8 tid for Hi-Pririty Flow Queue*/ 9851 WMI_MSDU_FLOW_TID_VALID_HI_MASKS_SET( 9852 resource_cfg->msdu_flow_override_config1, 9853 tgt_res_cfg->ast_tid_high_mask_enable); 9854 9855 /*Enable all 8 tid for Low-Pririty Flow Queue*/ 9856 WMI_MSDU_FLOW_TID_VALID_LOW_MASKS_SET( 9857 resource_cfg->msdu_flow_override_config1, 9858 tgt_res_cfg->ast_tid_low_mask_enable); 9859 WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_SET( 9860 resource_cfg->host_service_flags, 9861 tgt_res_cfg->nan_separate_iface_support); 9862 WMI_RSRC_CFG_HOST_SERVICE_FLAG_HOST_SUPPORT_MULTI_RADIO_EVTS_PER_RADIO_SET( 9863 resource_cfg->host_service_flags, 1); 9864 9865 WMI_RSRC_CFG_FLAG_VIDEO_OVER_WIFI_ENABLE_SET( 9866 resource_cfg->flag1, tgt_res_cfg->carrier_vow_optimization); 9867 9868 if (tgt_res_cfg->is_sap_connected_d3wow_enabled) 9869 WMI_RSRC_CFG_FLAGS2_IS_SAP_CONNECTED_D3WOW_ENABLED_SET( 9870 resource_cfg->flags2, 1); 9871 if (tgt_res_cfg->is_go_connected_d3wow_enabled) 9872 WMI_RSRC_CFG_FLAGS2_IS_GO_CONNECTED_D3WOW_ENABLED_SET( 9873 resource_cfg->flags2, 1); 9874 9875 if (tgt_res_cfg->sae_eapol_offload) 9876 WMI_RSRC_CFG_HOST_SERVICE_FLAG_SAE_EAPOL_OFFLOAD_SUPPORT_SET( 9877 resource_cfg->host_service_flags, 1); 9878 9879 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_CC_EXT_SUPPORT_SET( 9880 resource_cfg->host_service_flags, 9881 tgt_res_cfg->is_reg_cc_ext_event_supported); 9882 9883 WMI_RSRC_CFG_HOST_SERVICE_FLAG_BANG_RADAR_320M_SUPPORT_SET( 9884 resource_cfg->host_service_flags, 9885 tgt_res_cfg->is_host_dfs_320mhz_bangradar_supported); 9886 9887 WMI_RSRC_CFG_HOST_SERVICE_FLAG_LPI_SP_MODE_SUPPORT_SET( 9888 resource_cfg->host_service_flags, 9889 tgt_res_cfg->is_6ghz_sp_pwrmode_supp_enabled); 9890 9891 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_TIMER_CHECK_SET( 9892 resource_cfg->host_service_flags, 9893 tgt_res_cfg->afc_timer_check_disable); 9894 9895 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REG_DISCARD_AFC_REQ_ID_CHECK_SET( 9896 resource_cfg->host_service_flags, 9897 tgt_res_cfg->afc_req_id_check_disable); 9898 9899 wmi_copy_afc_deployment_config(resource_cfg, tgt_res_cfg); 9900 9901 wmi_set_nan_channel_support(resource_cfg); 9902 9903 if (tgt_res_cfg->twt_ack_support_cap) 9904 WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( 9905 resource_cfg->host_service_flags, 1); 9906 9907 if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) 9908 WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( 9909 resource_cfg->host_service_flags, 1); 9910 /* 9911 * DP Peer Meta data FW version 9912 */ 9913 WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET( 9914 resource_cfg->flags2, 9915 tgt_res_cfg->dp_peer_meta_data_ver); 9916 9917 if (tgt_res_cfg->notify_frame_support) 9918 WMI_RSRC_CFG_FLAGS2_NOTIFY_FRAME_CONFIG_ENABLE_SET( 9919 resource_cfg->flags2, 1); 9920 9921 if (tgt_res_cfg->rf_path) 9922 WMI_RSRC_CFG_FLAGS2_RF_PATH_MODE_SET( 9923 resource_cfg->flags2, tgt_res_cfg->rf_path); 9924 9925 if (tgt_res_cfg->fw_ast_indication_disable) { 9926 WMI_RSRC_CFG_FLAGS2_DISABLE_WDS_PEER_MAP_UNMAP_EVENT_SET 9927 (resource_cfg->flags2, 9928 tgt_res_cfg->fw_ast_indication_disable); 9929 } 9930 9931 wmi_copy_latency_flowq_support(resource_cfg, tgt_res_cfg); 9932 wmi_copy_full_bw_nol_cfg(resource_cfg, tgt_res_cfg); 9933 9934 } 9935 9936 #ifdef FEATURE_SET 9937 /** 9938 * convert_host_to_target_vendor1_req2_version() -Convert host vendor1 9939 * requirement2 version to target vendor1 requirement2 version 9940 * @vendor1_req2_ver: Host vendor1 requirement2 version 9941 * 9942 * Return: Target vendor1 requirement2 version 9943 */ 9944 static WMI_VENDOR1_REQ2_VERSION convert_host_to_target_vendor1_req2_version( 9945 WMI_HOST_VENDOR1_REQ2_VERSION vendor1_req2_ver) 9946 { 9947 switch (vendor1_req2_ver) { 9948 case WMI_HOST_VENDOR1_REQ2_VERSION_3_00: 9949 return WMI_VENDOR1_REQ2_VERSION_3_00; 9950 case WMI_HOST_VENDOR1_REQ2_VERSION_3_01: 9951 return WMI_VENDOR1_REQ2_VERSION_3_01; 9952 case WMI_HOST_VENDOR1_REQ2_VERSION_3_20: 9953 return WMI_VENDOR1_REQ2_VERSION_3_20; 9954 case WMI_HOST_VENDOR1_REQ2_VERSION_3_50: 9955 return WMI_VENDOR1_REQ2_VERSION_3_50; 9956 default: 9957 return WMI_VENDOR1_REQ2_VERSION_3_00; 9958 } 9959 } 9960 9961 /** 9962 * convert_host_to_target_vendor1_req1_version() -Convert host vendor1 9963 * requirement1 version to target vendor1 requirement1 version 9964 * @vendor1_req1_ver: Host vendor1 requirement1 version 9965 * 9966 * Return: Target vendor1 requirement1 version 9967 */ 9968 static WMI_VENDOR1_REQ1_VERSION convert_host_to_target_vendor1_req1_version( 9969 WMI_HOST_VENDOR1_REQ1_VERSION vendor1_req1_ver) 9970 { 9971 switch (vendor1_req1_ver) { 9972 case WMI_HOST_VENDOR1_REQ1_VERSION_3_00: 9973 return WMI_VENDOR1_REQ1_VERSION_3_00; 9974 case WMI_HOST_VENDOR1_REQ1_VERSION_3_01: 9975 return WMI_VENDOR1_REQ1_VERSION_3_01; 9976 case WMI_HOST_VENDOR1_REQ1_VERSION_3_20: 9977 return WMI_VENDOR1_REQ1_VERSION_3_20; 9978 case WMI_HOST_VENDOR1_REQ1_VERSION_3_30: 9979 return WMI_VENDOR1_REQ1_VERSION_3_30; 9980 case WMI_HOST_VENDOR1_REQ1_VERSION_3_40: 9981 return WMI_VENDOR1_REQ1_VERSION_3_40; 9982 case WMI_HOST_VENDOR1_REQ1_VERSION_4_00: 9983 return WMI_VENDOR1_REQ1_VERSION_4_00; 9984 default: 9985 return WMI_VENDOR1_REQ1_VERSION_3_00; 9986 } 9987 } 9988 9989 /** 9990 * convert_host_to_target_wifi_standard() -Convert host wifi standard to 9991 * target wifi standard 9992 * @wifi_standard: Host wifi standard 9993 * 9994 * Return: Target wifi standard 9995 */ 9996 static WMI_WIFI_STANDARD convert_host_to_target_wifi_standard( 9997 WMI_HOST_WIFI_STANDARD wifi_standard) 9998 { 9999 switch (wifi_standard) { 10000 case WMI_HOST_WIFI_STANDARD_4: 10001 return WMI_WIFI_STANDARD_4; 10002 case WMI_HOST_WIFI_STANDARD_5: 10003 return WMI_WIFI_STANDARD_5; 10004 case WMI_HOST_WIFI_STANDARD_6: 10005 return WMI_WIFI_STANDARD_6; 10006 case WMI_HOST_WIFI_STANDARD_6E: 10007 return WMI_WIFI_STANDARD_6E; 10008 case WMI_HOST_WIFI_STANDARD_7: 10009 return WMI_WIFI_STANDARD_7; 10010 default: 10011 return WMI_WIFI_STANDARD_4; 10012 } 10013 } 10014 10015 /** 10016 * convert_host_to_target_band_concurrency() -Convert host band concurrency to 10017 * target band concurrency 10018 * @band_concurrency: Host Band concurrency 10019 * 10020 * Return: Target band concurrency 10021 */ 10022 static WMI_BAND_CONCURRENCY convert_host_to_target_band_concurrency( 10023 WMI_HOST_BAND_CONCURRENCY band_concurrency) 10024 { 10025 switch (band_concurrency) { 10026 case WMI_HOST_BAND_CONCURRENCY_DBS: 10027 return WMI_HOST_DBS; 10028 case WMI_HOST_BAND_CONCURRENCY_DBS_SBS: 10029 return WMI_HOST_DBS_SBS; 10030 default: 10031 return WMI_HOST_NONE; 10032 } 10033 } 10034 10035 /** 10036 * convert_host_to_target_num_antennas() -Convert host num antennas to 10037 * target num antennas 10038 * @num_antennas: Host num antennas 10039 * 10040 * Return: Target num antennas 10041 */ 10042 static WMI_NUM_ANTENNAS convert_host_to_target_num_antennas( 10043 WMI_HOST_NUM_ANTENNAS num_antennas) 10044 { 10045 switch (num_antennas) { 10046 case WMI_HOST_SISO: 10047 return WMI_SISO; 10048 case WMI_HOST_MIMO_2X2: 10049 return WMI_MIMO_2X2; 10050 default: 10051 return WMI_SISO; 10052 } 10053 } 10054 10055 /** 10056 * convert_host_to_target_band_capability() -Convert host band capability to 10057 * target band capability 10058 * @host_band_capability: Host band capability 10059 * 10060 * Return: Target band capability bitmap 10061 */ 10062 static uint8_t 10063 convert_host_to_target_band_capability(uint32_t host_band_capability) 10064 { 10065 uint8_t band_capability; 10066 10067 band_capability = (host_band_capability & WMI_HOST_BAND_CAP_2GHZ) | 10068 (host_band_capability & WMI_HOST_BAND_CAP_5GHZ) | 10069 (host_band_capability & WMI_HOST_BAND_CAP_6GHZ); 10070 return band_capability; 10071 } 10072 10073 /** 10074 * copy_feature_set_info() -Copy feature set info from host to target 10075 * @feature_set_bitmap: Target feature set pointer 10076 * @feature_set: Host feature set structure 10077 * 10078 * Return: None 10079 */ 10080 static inline void copy_feature_set_info(uint32_t *feature_set_bitmap, 10081 struct target_feature_set *feature_set) 10082 { 10083 WMI_NUM_ANTENNAS num_antennas; 10084 WMI_BAND_CONCURRENCY band_concurrency; 10085 WMI_WIFI_STANDARD wifi_standard; 10086 WMI_VENDOR1_REQ1_VERSION vendor1_req1_version; 10087 WMI_VENDOR1_REQ2_VERSION vendor1_req2_version; 10088 uint8_t band_capability; 10089 10090 num_antennas = convert_host_to_target_num_antennas( 10091 feature_set->num_antennas); 10092 band_concurrency = convert_host_to_target_band_concurrency( 10093 feature_set->concurrency_support); 10094 wifi_standard = convert_host_to_target_wifi_standard( 10095 feature_set->wifi_standard); 10096 vendor1_req1_version = convert_host_to_target_vendor1_req1_version( 10097 feature_set->vendor_req_1_version); 10098 vendor1_req2_version = convert_host_to_target_vendor1_req2_version( 10099 feature_set->vendor_req_2_version); 10100 10101 band_capability = 10102 convert_host_to_target_band_capability( 10103 feature_set->band_capability); 10104 10105 WMI_SET_WIFI_STANDARD(feature_set_bitmap, wifi_standard); 10106 WMI_SET_BAND_CONCURRENCY_SUPPORT(feature_set_bitmap, band_concurrency); 10107 WMI_SET_PNO_SCAN_IN_UNASSOC_STATE(feature_set_bitmap, 10108 feature_set->pno_in_unassoc_state); 10109 WMI_SET_PNO_SCAN_IN_ASSOC_STATE(feature_set_bitmap, 10110 feature_set->pno_in_assoc_state); 10111 WMI_SET_TWT_FEATURE_SUPPORT(feature_set_bitmap, 10112 feature_set->enable_twt); 10113 WMI_SET_TWT_REQUESTER(feature_set_bitmap, 10114 feature_set->enable_twt_requester); 10115 WMI_SET_TWT_BROADCAST(feature_set_bitmap, 10116 feature_set->enable_twt_broadcast); 10117 WMI_SET_TWT_FLEXIBLE(feature_set_bitmap, 10118 feature_set->enable_twt_flexible); 10119 WMI_SET_WIFI_OPT_FEATURE_SUPPORT(feature_set_bitmap, 10120 feature_set->enable_wifi_optimizer); 10121 WMI_SET_RFC8325_FEATURE_SUPPORT(feature_set_bitmap, 10122 feature_set->enable_rfc835); 10123 WMI_SET_MHS_5G_SUPPORT(feature_set_bitmap, 10124 feature_set->sap_5g_supported); 10125 WMI_SET_MHS_6G_SUPPORT(feature_set_bitmap, 10126 feature_set->sap_6g_supported); 10127 WMI_SET_MHS_MAX_CLIENTS_SUPPORT(feature_set_bitmap, 10128 feature_set->sap_max_num_clients); 10129 WMI_SET_MHS_SET_COUNTRY_CODE_HAL_SUPPORT( 10130 feature_set_bitmap, 10131 feature_set->set_country_code_hal_supported); 10132 WMI_SET_MHS_GETVALID_CHANNELS_SUPPORT( 10133 feature_set_bitmap, 10134 feature_set->get_valid_channel_supported); 10135 WMI_SET_MHS_DOT11_MODE_SUPPORT(feature_set_bitmap, 10136 feature_set->supported_dot11mode); 10137 WMI_SET_MHS_WPA3_SUPPORT(feature_set_bitmap, 10138 feature_set->sap_wpa3_support); 10139 WMI_SET_VENDOR_REQ_1_VERSION(feature_set_bitmap, vendor1_req1_version); 10140 WMI_SET_ROAMING_HIGH_CU_ROAM_TRIGGER( 10141 feature_set_bitmap, 10142 feature_set->roaming_high_cu_roam_trigger); 10143 WMI_SET_ROAMING_EMERGENCY_TRIGGER( 10144 feature_set_bitmap, 10145 feature_set->roaming_emergency_trigger); 10146 WMI_SET_ROAMING_BTM_TRIGGER(feature_set_bitmap, 10147 feature_set->roaming_btm_trihgger); 10148 WMI_SET_ROAMING_IDLE_TRIGGER(feature_set_bitmap, 10149 feature_set->roaming_idle_trigger); 10150 WMI_SET_ROAMING_WTC_TRIGGER(feature_set_bitmap, 10151 feature_set->roaming_wtc_trigger); 10152 WMI_SET_ROAMING_BTCOEX_TRIGGER(feature_set_bitmap, 10153 feature_set->roaming_btcoex_trigger); 10154 WMI_SET_ROAMING_BTW_WPA_WPA2(feature_set_bitmap, 10155 feature_set->roaming_btw_wpa_wpa2); 10156 WMI_SET_ROAMING_MANAGE_CHAN_LIST_API( 10157 feature_set_bitmap, 10158 feature_set->roaming_manage_chan_list_api); 10159 WMI_SET_ROAMING_ADAPTIVE_11R(feature_set_bitmap, 10160 feature_set->roaming_adaptive_11r); 10161 WMI_SET_ROAMING_CTRL_API_GET_SET(feature_set_bitmap, 10162 feature_set->roaming_ctrl_api_get_set); 10163 WMI_SET_ROAMING_CTRL_API_REASSOC(feature_set_bitmap, 10164 feature_set->roaming_ctrl_api_reassoc); 10165 WMI_SET_ROAMING_CTRL_GET_CU(feature_set_bitmap, 10166 feature_set->roaming_ctrl_get_cu); 10167 WMI_SET_VENDOR_REQ_2_VERSION(feature_set_bitmap, vendor1_req2_version); 10168 WMI_SET_ASSURANCE_DISCONNECT_REASON_API( 10169 feature_set_bitmap, 10170 feature_set->assurance_disconnect_reason_api); 10171 WMI_SET_FRAME_PCAP_LOG_MGMT(feature_set_bitmap, 10172 feature_set->frame_pcap_log_mgmt); 10173 WMI_SET_FRAME_PCAP_LOG_CTRL(feature_set_bitmap, 10174 feature_set->frame_pcap_log_ctrl); 10175 WMI_SET_FRAME_PCAP_LOG_DATA(feature_set_bitmap, 10176 feature_set->frame_pcap_log_data); 10177 WMI_SET_SECURITY_WPA3_SAE_H2E(feature_set_bitmap, 10178 feature_set->security_wpa3_sae_h2e); 10179 WMI_SET_SECURITY_WPA3_SAE_FT(feature_set_bitmap, 10180 feature_set->security_wpa3_sae_ft); 10181 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB( 10182 feature_set_bitmap, 10183 feature_set->security_wpa3_enterp_suitb); 10184 WMI_SET_SECURITY_WPA3_ENTERP_SUITEB_192bit( 10185 feature_set_bitmap, 10186 feature_set->security_wpa3_enterp_suitb_192bit); 10187 WMI_SET_SECURITY_FILS_SHA256(feature_set_bitmap, 10188 feature_set->security_fills_sha_256); 10189 WMI_SET_SECURITY_FILS_SHA384(feature_set_bitmap, 10190 feature_set->security_fills_sha_384); 10191 WMI_SET_SECURITY_FILS_SHA256_FT(feature_set_bitmap, 10192 feature_set->security_fills_sha_256_FT); 10193 WMI_SET_SECURITY_FILS_SHA384_FT(feature_set_bitmap, 10194 feature_set->security_fills_sha_384_FT); 10195 WMI_SET_SECURITY_ENCHANCED_OPEN(feature_set_bitmap, 10196 feature_set->security_enhanced_open); 10197 WMI_SET_NAN_SUPPORT(feature_set_bitmap, feature_set->enable_nan); 10198 WMI_SET_TDLS_SUPPORT(feature_set_bitmap, feature_set->enable_tdls); 10199 WMI_SET_P2P6E_SUPPORT(feature_set_bitmap, feature_set->enable_p2p_6e); 10200 WMI_SET_TDLS_OFFCHAN_SUPPORT(feature_set_bitmap, 10201 feature_set->enable_tdls_offchannel); 10202 WMI_SET_TDLS_CAP_ENHANCE(feature_set_bitmap, 10203 feature_set->enable_tdls_capability_enhance); 10204 WMI_SET_MAX_TDLS_PEERS_SUPPORT(feature_set_bitmap, 10205 feature_set->max_tdls_peers); 10206 WMI_SET_STA_DUAL_P2P_SUPPORT(feature_set_bitmap, 10207 (feature_set->iface_combinations & 10208 MLME_IFACE_STA_DUAL_P2P_SUPPORT) > 0); 10209 WMI_SET_STA_P2P_SUPPORT(feature_set_bitmap, 10210 (feature_set->iface_combinations & 10211 MLME_IFACE_STA_P2P_SUPPORT) > 0); 10212 WMI_SET_STA_SAP_SUPPORT(feature_set_bitmap, 10213 (feature_set->iface_combinations & 10214 MLME_IFACE_STA_SAP_SUPPORT) > 0); 10215 WMI_SET_STA_NAN_SUPPORT(feature_set_bitmap, 10216 (feature_set->iface_combinations & 10217 MLME_IFACE_STA_NAN_SUPPORT) > 0); 10218 WMI_SET_STA_TDLS_SUPPORT(feature_set_bitmap, 10219 (feature_set->iface_combinations & 10220 MLME_IFACE_STA_TDLS_SUPPORT) > 0); 10221 WMI_SET_STA_SAP_P2P_SUPPORT(feature_set_bitmap, 10222 (feature_set->iface_combinations & 10223 MLME_IFACE_STA_SAP_P2P_SUPPORT) > 0); 10224 WMI_SET_STA_SAP_NAN_SUPPORT(feature_set_bitmap, 10225 (feature_set->iface_combinations & 10226 MLME_IFACE_STA_SAP_NAN_SUPPORT) > 0); 10227 WMI_SET_STA_P2P_NAN_SUPPORT(feature_set_bitmap, 10228 (feature_set->iface_combinations & 10229 MLME_IFACE_STA_P2P_NAN_SUPPORT) > 0); 10230 WMI_SET_STA_P2P_TDLS_SUPPORT(feature_set_bitmap, 10231 (feature_set->iface_combinations & 10232 MLME_IFACE_STA_P2P_TDLS_SUPPORT) > 0); 10233 WMI_SET_STA_SAP_TDLS_SUPPORT(feature_set_bitmap, 10234 (feature_set->iface_combinations & 10235 MLME_IFACE_STA_SAP_TDLS_SUPPORT) > 0); 10236 WMI_SET_STA_NAN_TDLS_SUPPORT(feature_set_bitmap, 10237 (feature_set->iface_combinations & 10238 MLME_IFACE_STA_NAN_TDLS_SUPPORT) > 0); 10239 WMI_SET_STA_SAP_P2P_TDLS_SUPPORT(feature_set_bitmap, 10240 (feature_set->iface_combinations & 10241 MLME_IFACE_STA_SAP_P2P_TDLS_SUPPORT) > 0); 10242 WMI_SET_STA_SAP_NAN_TDLS_SUPPORT(feature_set_bitmap, 10243 (feature_set->iface_combinations & 10244 MLME_IFACE_STA_SAP_NAN_TDLS_SUPPORT) > 0); 10245 WMI_SET_STA_P2P_P2P_TDLS_SUPPORT(feature_set_bitmap, 10246 (feature_set->iface_combinations & 10247 MLME_IFACE_STA_P2P_P2P_TDLS_SUPPORT) > 0); 10248 WMI_SET_STA_P2P_NAN_TDLS_SUPPORT(feature_set_bitmap, 10249 (feature_set->iface_combinations & 10250 MLME_IFACE_STA_P2P_NAN_TDLS_SUPPORT) > 0); 10251 WMI_SET_PEER_BIGDATA_GETBSSINFO_API_SUPPORT( 10252 feature_set_bitmap, 10253 feature_set->peer_bigdata_getbssinfo_support); 10254 WMI_SET_PEER_BIGDATA_GETASSOCREJECTINFO_API_SUPPORT( 10255 feature_set_bitmap, 10256 feature_set->peer_bigdata_assocreject_info_support); 10257 WMI_SET_PEER_BIGDATA_GETSTAINFO_API_SUPPORT( 10258 feature_set_bitmap, 10259 feature_set->peer_getstainfo_support); 10260 WMI_SET_FEATURE_SET_VERSION(feature_set_bitmap, 10261 feature_set->feature_set_version); 10262 WMI_SET_NUM_ANTENNAS(feature_set_bitmap, num_antennas); 10263 WMI_SET_HOST_BAND_CAP(feature_set_bitmap, band_capability); 10264 WMI_SET_STA_DUMP_SUPPORT(feature_set_bitmap, 10265 feature_set->sta_dump_support); 10266 } 10267 10268 /** 10269 * feature_set_cmd_send_tlv() -Send feature set command 10270 * @wmi_handle: WMI handle 10271 * @feature_set: Feature set structure 10272 * 10273 * Return: QDF_STATUS_SUCCESS on success else return failure 10274 */ 10275 static QDF_STATUS feature_set_cmd_send_tlv( 10276 struct wmi_unified *wmi_handle, 10277 struct target_feature_set *feature_set) 10278 { 10279 wmi_pdev_featureset_cmd_fixed_param *cmd; 10280 wmi_buf_t buf; 10281 uint16_t len; 10282 QDF_STATUS ret; 10283 uint8_t *buf_ptr; 10284 uint32_t *feature_set_bitmap; 10285 10286 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10287 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t); 10288 buf = wmi_buf_alloc(wmi_handle, len); 10289 10290 if (!buf) 10291 return QDF_STATUS_E_NOMEM; 10292 10293 wmi_debug("Send feature set param"); 10294 10295 buf_ptr = (uint8_t *)wmi_buf_data(buf); 10296 10297 cmd = (wmi_pdev_featureset_cmd_fixed_param *)wmi_buf_data(buf); 10298 10299 WMITLV_SET_HDR(&cmd->tlv_header, 10300 WMITLV_TAG_STRUC_wmi_pdev_featureset_cmd_fixed_param, 10301 WMITLV_GET_STRUCT_TLVLEN( 10302 wmi_pdev_featureset_cmd_fixed_param)); 10303 10304 feature_set_bitmap = (uint32_t *)(buf_ptr + sizeof(*cmd) + 10305 WMI_TLV_HDR_SIZE); 10306 WMITLV_SET_HDR(buf_ptr + sizeof(*cmd), WMITLV_TAG_ARRAY_UINT32, 10307 (WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * sizeof(uint32_t))); 10308 copy_feature_set_info(feature_set_bitmap, feature_set); 10309 10310 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10311 feature_set_bitmap, 10312 WMI_FEATURE_SET_BITMAP_ARRAY_LEN32 * 10313 sizeof(uint32_t)); 10314 10315 wmi_mtrace(WMI_PDEV_FEATURESET_CMDID, NO_SESSION, 0); 10316 10317 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10318 WMI_PDEV_FEATURESET_CMDID); 10319 if (QDF_IS_STATUS_ERROR(ret)) 10320 wmi_buf_free(buf); 10321 10322 return ret; 10323 } 10324 #endif 10325 10326 /* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd 10327 * @wmi_handle: pointer to wmi handle 10328 * @buf_ptr: pointer to current position in init command buffer 10329 * @len: pointer to length. This will be updated with current length of cmd 10330 * @param: point host parameters for init command 10331 * 10332 * Return: Updated pointer of buf_ptr. 10333 */ 10334 static inline uint8_t *copy_hw_mode_in_init_cmd(struct wmi_unified *wmi_handle, 10335 uint8_t *buf_ptr, int *len, struct wmi_init_cmd_param *param) 10336 { 10337 uint16_t idx; 10338 10339 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) { 10340 wmi_pdev_set_hw_mode_cmd_fixed_param *hw_mode; 10341 wmi_pdev_band_to_mac *band_to_mac; 10342 10343 hw_mode = (wmi_pdev_set_hw_mode_cmd_fixed_param *) 10344 (buf_ptr + sizeof(wmi_init_cmd_fixed_param) + 10345 sizeof(wmi_resource_config) + 10346 WMI_TLV_HDR_SIZE + (param->num_mem_chunks * 10347 sizeof(wlan_host_memory_chunk))); 10348 10349 WMITLV_SET_HDR(&hw_mode->tlv_header, 10350 WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param, 10351 (WMITLV_GET_STRUCT_TLVLEN 10352 (wmi_pdev_set_hw_mode_cmd_fixed_param))); 10353 10354 hw_mode->hw_mode_index = param->hw_mode_id; 10355 hw_mode->num_band_to_mac = param->num_band_to_mac; 10356 10357 buf_ptr = (uint8_t *) (hw_mode + 1); 10358 band_to_mac = (wmi_pdev_band_to_mac *) (buf_ptr + 10359 WMI_TLV_HDR_SIZE); 10360 for (idx = 0; idx < param->num_band_to_mac; idx++) { 10361 WMITLV_SET_HDR(&band_to_mac[idx].tlv_header, 10362 WMITLV_TAG_STRUC_wmi_pdev_band_to_mac, 10363 WMITLV_GET_STRUCT_TLVLEN 10364 (wmi_pdev_band_to_mac)); 10365 band_to_mac[idx].pdev_id = 10366 wmi_handle->ops->convert_pdev_id_host_to_target( 10367 wmi_handle, 10368 param->band_to_mac[idx].pdev_id); 10369 band_to_mac[idx].start_freq = 10370 param->band_to_mac[idx].start_freq; 10371 band_to_mac[idx].end_freq = 10372 param->band_to_mac[idx].end_freq; 10373 } 10374 *len += sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 10375 (param->num_band_to_mac * 10376 sizeof(wmi_pdev_band_to_mac)) + 10377 WMI_TLV_HDR_SIZE; 10378 10379 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 10380 (param->num_band_to_mac * 10381 sizeof(wmi_pdev_band_to_mac))); 10382 } 10383 10384 return buf_ptr; 10385 } 10386 10387 static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle, 10388 wmi_init_cmd_fixed_param *cmd) 10389 { 10390 int num_allowlist; 10391 wmi_abi_version my_vers; 10392 10393 num_allowlist = sizeof(version_whitelist) / 10394 sizeof(wmi_whitelist_version_info); 10395 my_vers.abi_version_0 = WMI_ABI_VERSION_0; 10396 my_vers.abi_version_1 = WMI_ABI_VERSION_1; 10397 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; 10398 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; 10399 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; 10400 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; 10401 10402 wmi_cmp_and_set_abi_version(num_allowlist, version_whitelist, 10403 &my_vers, 10404 (struct _wmi_abi_version *)&wmi_handle->fw_abi_version, 10405 &cmd->host_abi_vers); 10406 10407 qdf_debug("INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", 10408 WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), 10409 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), 10410 cmd->host_abi_vers.abi_version_ns_0, 10411 cmd->host_abi_vers.abi_version_ns_1, 10412 cmd->host_abi_vers.abi_version_ns_2, 10413 cmd->host_abi_vers.abi_version_ns_3); 10414 10415 /* Save version sent from host - 10416 * Will be used to check ready event 10417 */ 10418 qdf_mem_copy(&wmi_handle->final_abi_vers, &cmd->host_abi_vers, 10419 sizeof(wmi_abi_version)); 10420 } 10421 10422 /* 10423 * send_cfg_action_frm_tb_ppdu_cmd_tlv() - send action frame tb ppdu cfg to FW 10424 * @wmi_handle: Pointer to WMi handle 10425 * @ie_data: Pointer for ie data 10426 * 10427 * This function sends action frame tb ppdu cfg to FW 10428 * 10429 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10430 * 10431 */ 10432 static QDF_STATUS send_cfg_action_frm_tb_ppdu_cmd_tlv(wmi_unified_t wmi_handle, 10433 struct cfg_action_frm_tb_ppdu_param *cfg_msg) 10434 { 10435 wmi_pdev_he_tb_action_frm_cmd_fixed_param *cmd; 10436 wmi_buf_t buf; 10437 uint8_t *buf_ptr; 10438 uint32_t len, frm_len_aligned; 10439 QDF_STATUS ret; 10440 10441 frm_len_aligned = roundup(cfg_msg->frm_len, sizeof(uint32_t)); 10442 /* Allocate memory for the WMI command */ 10443 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + frm_len_aligned; 10444 10445 buf = wmi_buf_alloc(wmi_handle, len); 10446 if (!buf) 10447 return QDF_STATUS_E_NOMEM; 10448 10449 buf_ptr = wmi_buf_data(buf); 10450 qdf_mem_zero(buf_ptr, len); 10451 10452 /* Populate the WMI command */ 10453 cmd = (wmi_pdev_he_tb_action_frm_cmd_fixed_param *)buf_ptr; 10454 10455 WMITLV_SET_HDR(&cmd->tlv_header, 10456 WMITLV_TAG_STRUC_wmi_pdev_he_tb_action_frm_cmd_fixed_param, 10457 WMITLV_GET_STRUCT_TLVLEN( 10458 wmi_pdev_he_tb_action_frm_cmd_fixed_param)); 10459 cmd->enable = cfg_msg->cfg; 10460 cmd->data_len = cfg_msg->frm_len; 10461 10462 buf_ptr += sizeof(*cmd); 10463 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, frm_len_aligned); 10464 buf_ptr += WMI_TLV_HDR_SIZE; 10465 10466 qdf_mem_copy(buf_ptr, cfg_msg->data, cmd->data_len); 10467 10468 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 10469 WMI_PDEV_HE_TB_ACTION_FRM_CMDID); 10470 if (QDF_IS_STATUS_ERROR(ret)) { 10471 wmi_err("HE TB action frame cmnd send fail, ret %d", ret); 10472 wmi_buf_free(buf); 10473 } 10474 10475 return ret; 10476 } 10477 10478 static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf) 10479 { 10480 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 10481 wmi_service_ready_event_fixed_param *ev; 10482 10483 10484 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 10485 10486 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 10487 if (!ev) 10488 return QDF_STATUS_E_FAILURE; 10489 10490 /*Save fw version from service ready message */ 10491 /*This will be used while sending INIT message */ 10492 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10493 sizeof(wmi_handle->fw_abi_version)); 10494 10495 return QDF_STATUS_SUCCESS; 10496 } 10497 10498 /** 10499 * check_and_update_fw_version_cmd_tlv() - save fw version 10500 * @wmi_handle: pointer to wmi handle 10501 * @evt_buf: pointer to the event buffer 10502 * 10503 * This function extracts and saves the firmware WMI ABI version 10504 * 10505 * Return: QDF_STATUS_SUCCESS for success otherwise failure 10506 * 10507 */ 10508 static QDF_STATUS check_and_update_fw_version_cmd_tlv(wmi_unified_t wmi_handle, 10509 void *evt_buf) 10510 { 10511 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 10512 wmi_ready_event_fixed_param *ev = NULL; 10513 10514 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 10515 ev = param_buf->fixed_param; 10516 if (!wmi_versions_are_compatible((struct _wmi_abi_version *) 10517 &wmi_handle->final_abi_vers, 10518 &ev->fw_abi_vers)) { 10519 /* 10520 * Error: Our host version and the given firmware version 10521 * are incompatible. 10522 **/ 10523 wmi_debug("Error: Incompatible WMI version." 10524 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", 10525 WMI_VER_GET_MAJOR(wmi_handle->final_abi_vers. 10526 abi_version_0), 10527 WMI_VER_GET_MINOR(wmi_handle->final_abi_vers. 10528 abi_version_0), 10529 wmi_handle->final_abi_vers.abi_version_ns_0, 10530 wmi_handle->final_abi_vers.abi_version_ns_1, 10531 wmi_handle->final_abi_vers.abi_version_ns_2, 10532 wmi_handle->final_abi_vers.abi_version_ns_3, 10533 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), 10534 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), 10535 ev->fw_abi_vers.abi_version_ns_0, 10536 ev->fw_abi_vers.abi_version_ns_1, 10537 ev->fw_abi_vers.abi_version_ns_2, 10538 ev->fw_abi_vers.abi_version_ns_3); 10539 10540 return QDF_STATUS_E_FAILURE; 10541 } 10542 qdf_mem_copy(&wmi_handle->final_abi_vers, &ev->fw_abi_vers, 10543 sizeof(wmi_abi_version)); 10544 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 10545 sizeof(wmi_abi_version)); 10546 10547 return QDF_STATUS_SUCCESS; 10548 } 10549 10550 /** 10551 * send_log_supported_evt_cmd_tlv() - Enable/Disable FW diag/log events 10552 * @wmi_handle: wmi handle 10553 * @event: Event received from FW 10554 * @len: Length of the event 10555 * 10556 * Enables the low frequency events and disables the high frequency 10557 * events. Bit 17 indicates if the event if low/high frequency. 10558 * 1 - high frequency, 0 - low frequency 10559 * 10560 * Return: QDF_STATUS_SUCCESS for success or error code 10561 */ 10562 static QDF_STATUS send_log_supported_evt_cmd_tlv(wmi_unified_t wmi_handle, 10563 uint8_t *event, 10564 uint32_t len) 10565 { 10566 uint32_t num_of_diag_events_logs; 10567 wmi_diag_event_log_config_fixed_param *cmd; 10568 wmi_buf_t buf; 10569 uint8_t *buf_ptr; 10570 uint32_t *cmd_args, *evt_args; 10571 uint32_t buf_len, i; 10572 10573 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf; 10574 wmi_diag_event_log_supported_event_fixed_params *wmi_event; 10575 10576 wmi_debug("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID"); 10577 10578 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event; 10579 if (!param_buf) { 10580 wmi_err("Invalid log supported event buffer"); 10581 return QDF_STATUS_E_INVAL; 10582 } 10583 wmi_event = param_buf->fixed_param; 10584 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs; 10585 10586 if (num_of_diag_events_logs > 10587 param_buf->num_diag_events_logs_list) { 10588 wmi_err("message number of events %d is more than tlv hdr content %d", 10589 num_of_diag_events_logs, 10590 param_buf->num_diag_events_logs_list); 10591 return QDF_STATUS_E_INVAL; 10592 } 10593 10594 evt_args = param_buf->diag_events_logs_list; 10595 if (!evt_args) { 10596 wmi_err("Event list is empty, num_of_diag_events_logs=%d", 10597 num_of_diag_events_logs); 10598 return QDF_STATUS_E_INVAL; 10599 } 10600 10601 wmi_debug("num_of_diag_events_logs=%d", num_of_diag_events_logs); 10602 10603 /* Free any previous allocation */ 10604 if (wmi_handle->events_logs_list) { 10605 qdf_mem_free(wmi_handle->events_logs_list); 10606 wmi_handle->events_logs_list = NULL; 10607 } 10608 10609 if (num_of_diag_events_logs > 10610 (WMI_SVC_MSG_MAX_SIZE / sizeof(uint32_t))) { 10611 wmi_err("excess num of logs: %d", num_of_diag_events_logs); 10612 QDF_ASSERT(0); 10613 return QDF_STATUS_E_INVAL; 10614 } 10615 /* Store the event list for run time enable/disable */ 10616 wmi_handle->events_logs_list = qdf_mem_malloc(num_of_diag_events_logs * 10617 sizeof(uint32_t)); 10618 if (!wmi_handle->events_logs_list) 10619 return QDF_STATUS_E_NOMEM; 10620 10621 wmi_handle->num_of_diag_events_logs = num_of_diag_events_logs; 10622 10623 /* Prepare the send buffer */ 10624 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10625 (num_of_diag_events_logs * sizeof(uint32_t)); 10626 10627 buf = wmi_buf_alloc(wmi_handle, buf_len); 10628 if (!buf) { 10629 qdf_mem_free(wmi_handle->events_logs_list); 10630 wmi_handle->events_logs_list = NULL; 10631 return QDF_STATUS_E_NOMEM; 10632 } 10633 10634 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10635 buf_ptr = (uint8_t *) cmd; 10636 10637 WMITLV_SET_HDR(&cmd->tlv_header, 10638 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10639 WMITLV_GET_STRUCT_TLVLEN( 10640 wmi_diag_event_log_config_fixed_param)); 10641 10642 cmd->num_of_diag_events_logs = num_of_diag_events_logs; 10643 10644 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10645 10646 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10647 (num_of_diag_events_logs * sizeof(uint32_t))); 10648 10649 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10650 10651 /* Populate the events */ 10652 for (i = 0; i < num_of_diag_events_logs; i++) { 10653 /* Low freq (0) - Enable (1) the event 10654 * High freq (1) - Disable (0) the event 10655 */ 10656 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i], 10657 !(WMI_DIAG_FREQUENCY_GET(evt_args[i]))); 10658 /* Set the event ID */ 10659 WMI_DIAG_ID_SET(cmd_args[i], 10660 WMI_DIAG_ID_GET(evt_args[i])); 10661 /* Set the type */ 10662 WMI_DIAG_TYPE_SET(cmd_args[i], 10663 WMI_DIAG_TYPE_GET(evt_args[i])); 10664 /* Storing the event/log list in WMI */ 10665 wmi_handle->events_logs_list[i] = evt_args[i]; 10666 } 10667 10668 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10669 if (wmi_unified_cmd_send(wmi_handle, buf, buf_len, 10670 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10671 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10672 wmi_buf_free(buf); 10673 /* Not clearing events_logs_list, though wmi cmd failed. 10674 * Host can still have this list 10675 */ 10676 return QDF_STATUS_E_INVAL; 10677 } 10678 10679 return 0; 10680 } 10681 10682 /** 10683 * send_enable_specific_fw_logs_cmd_tlv() - Start/Stop logging of diag log id 10684 * @wmi_handle: wmi handle 10685 * @start_log: Start logging related parameters 10686 * 10687 * Send the command to the FW based on which specific logging of diag 10688 * event/log id can be started/stopped 10689 * 10690 * Return: None 10691 */ 10692 static QDF_STATUS send_enable_specific_fw_logs_cmd_tlv(wmi_unified_t wmi_handle, 10693 struct wmi_wifi_start_log *start_log) 10694 { 10695 wmi_diag_event_log_config_fixed_param *cmd; 10696 wmi_buf_t buf; 10697 uint8_t *buf_ptr; 10698 uint32_t len, count, log_level, i; 10699 uint32_t *cmd_args; 10700 uint32_t total_len; 10701 count = 0; 10702 10703 if (!wmi_handle->events_logs_list) { 10704 wmi_debug("Not received event/log list from FW, yet"); 10705 return QDF_STATUS_E_NOMEM; 10706 } 10707 /* total_len stores the number of events where BITS 17 and 18 are set. 10708 * i.e., events of high frequency (17) and for extended debugging (18) 10709 */ 10710 total_len = 0; 10711 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10712 if ((WMI_DIAG_FREQUENCY_GET(wmi_handle->events_logs_list[i])) && 10713 (WMI_DIAG_EXT_FEATURE_GET(wmi_handle->events_logs_list[i]))) 10714 total_len++; 10715 } 10716 10717 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + 10718 (total_len * sizeof(uint32_t)); 10719 10720 buf = wmi_buf_alloc(wmi_handle, len); 10721 if (!buf) 10722 return QDF_STATUS_E_NOMEM; 10723 10724 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf); 10725 buf_ptr = (uint8_t *) cmd; 10726 10727 WMITLV_SET_HDR(&cmd->tlv_header, 10728 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param, 10729 WMITLV_GET_STRUCT_TLVLEN( 10730 wmi_diag_event_log_config_fixed_param)); 10731 10732 cmd->num_of_diag_events_logs = total_len; 10733 10734 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param); 10735 10736 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 10737 (total_len * sizeof(uint32_t))); 10738 10739 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 10740 10741 if (start_log->verbose_level >= WMI_LOG_LEVEL_ACTIVE) 10742 log_level = 1; 10743 else 10744 log_level = 0; 10745 10746 wmi_debug("Length: %d Log_level: %d", total_len, log_level); 10747 for (i = 0; i < wmi_handle->num_of_diag_events_logs; i++) { 10748 uint32_t val = wmi_handle->events_logs_list[i]; 10749 if ((WMI_DIAG_FREQUENCY_GET(val)) && 10750 (WMI_DIAG_EXT_FEATURE_GET(val))) { 10751 10752 WMI_DIAG_ID_SET(cmd_args[count], 10753 WMI_DIAG_ID_GET(val)); 10754 WMI_DIAG_TYPE_SET(cmd_args[count], 10755 WMI_DIAG_TYPE_GET(val)); 10756 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count], 10757 log_level); 10758 wmi_debug("Idx:%d, val:%x", i, val); 10759 count++; 10760 } 10761 } 10762 10763 wmi_mtrace(WMI_DIAG_EVENT_LOG_CONFIG_CMDID, NO_SESSION, 0); 10764 if (wmi_unified_cmd_send(wmi_handle, buf, len, 10765 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) { 10766 wmi_err("WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed"); 10767 wmi_buf_free(buf); 10768 return QDF_STATUS_E_INVAL; 10769 } 10770 10771 return QDF_STATUS_SUCCESS; 10772 } 10773 10774 /** 10775 * send_flush_logs_to_fw_cmd_tlv() - Send log flush command to FW 10776 * @wmi_handle: WMI handle 10777 * 10778 * This function is used to send the flush command to the FW, 10779 * that will flush the fw logs that are residue in the FW 10780 * 10781 * Return: None 10782 */ 10783 static QDF_STATUS send_flush_logs_to_fw_cmd_tlv(wmi_unified_t wmi_handle) 10784 { 10785 wmi_debug_mesg_flush_fixed_param *cmd; 10786 wmi_buf_t buf; 10787 int len = sizeof(*cmd); 10788 QDF_STATUS ret; 10789 10790 buf = wmi_buf_alloc(wmi_handle, len); 10791 if (!buf) 10792 return QDF_STATUS_E_NOMEM; 10793 10794 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf); 10795 WMITLV_SET_HDR(&cmd->tlv_header, 10796 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, 10797 WMITLV_GET_STRUCT_TLVLEN( 10798 wmi_debug_mesg_flush_fixed_param)); 10799 cmd->reserved0 = 0; 10800 10801 wmi_mtrace(WMI_DEBUG_MESG_FLUSH_CMDID, NO_SESSION, 0); 10802 ret = wmi_unified_cmd_send(wmi_handle, 10803 buf, 10804 len, 10805 WMI_DEBUG_MESG_FLUSH_CMDID); 10806 if (QDF_IS_STATUS_ERROR(ret)) { 10807 wmi_err("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID"); 10808 wmi_buf_free(buf); 10809 return QDF_STATUS_E_INVAL; 10810 } 10811 wmi_debug("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW"); 10812 10813 return ret; 10814 } 10815 10816 #ifdef BIG_ENDIAN_HOST 10817 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 10818 /** 10819 * fips_extend_align_data_be() - LE to BE conversion of FIPS extend ev data 10820 * @wmi_handle: wmi handle 10821 * @param: fips extend param related parameters 10822 * 10823 * Return: QDF_STATUS - success or error status 10824 */ 10825 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 10826 struct fips_extend_params *param) 10827 { 10828 unsigned char *key_unaligned, *nonce_iv_unaligned, *data_unaligned; 10829 int c; 10830 u_int8_t *key_aligned = NULL; 10831 u_int8_t *nonce_iv_aligned = NULL; 10832 u_int8_t *data_aligned = NULL; 10833 int ret = QDF_STATUS_SUCCESS; 10834 10835 /* Assigning unaligned space to copy the key */ 10836 key_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10837 param->cmd_params.key_len + FIPS_ALIGN); 10838 /* Checking if kmalloc is successful to allocate space */ 10839 if (!key_unaligned) 10840 return QDF_STATUS_E_INVAL; 10841 10842 data_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * param->data_len + 10843 FIPS_ALIGN); 10844 /* Checking if kmalloc is successful to allocate space */ 10845 if (!data_unaligned) { 10846 ret = QDF_STATUS_E_INVAL; 10847 goto fips_align_fail_data; 10848 } 10849 10850 /* Checking if space is aligned */ 10851 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10852 /* align to 4 */ 10853 key_aligned = (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10854 FIPS_ALIGN); 10855 } else { 10856 key_aligned = (u_int8_t *)key_unaligned; 10857 } 10858 10859 /* memset and copy content from key to key aligned */ 10860 OS_MEMSET(key_aligned, 0, param->cmd_params.key_len); 10861 OS_MEMCPY(key_aligned, param->cmd_params.key, 10862 param->cmd_params.key_len); 10863 10864 /* print a hexdump for host debug */ 10865 wmi_debug("Aligned and Copied Key: "); 10866 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10867 key_aligned, param->cmd_params.key_len); 10868 10869 /* Checking of space is aligned */ 10870 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 10871 /* align to 4 */ 10872 data_aligned = 10873 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 10874 } else { 10875 data_aligned = (u_int8_t *)data_unaligned; 10876 } 10877 10878 /* memset and copy content from data to data aligned */ 10879 OS_MEMSET(data_aligned, 0, param->data_len); 10880 OS_MEMCPY(data_aligned, param->data, param->data_len); 10881 10882 /* print a hexdump for host debug */ 10883 wmi_debug("\t Properly Aligned and Copied Data: "); 10884 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10885 data_aligned, param->data_len); 10886 10887 /* converting to little Endian */ 10888 for (c = 0; c < param->cmd_params.key_len / 4; c++) { 10889 *((u_int32_t *)key_aligned + c) = 10890 qdf_cpu_to_le32(*((u_int32_t *)key_aligned + c)); 10891 } 10892 for (c = 0; c < param->data_len / 4; c++) { 10893 *((u_int32_t *)data_aligned + c) = 10894 qdf_cpu_to_le32(*((u_int32_t *)data_aligned + c)); 10895 } 10896 10897 /* update endian data */ 10898 OS_MEMCPY(param->cmd_params.key, key_aligned, 10899 param->cmd_params.key_len); 10900 OS_MEMCPY(param->data, data_aligned, param->data_len); 10901 10902 if (param->cmd_params.nonce_iv_len) { 10903 nonce_iv_unaligned = qdf_mem_malloc(sizeof(u_int8_t) * 10904 param->cmd_params.nonce_iv_len + 10905 FIPS_ALIGN); 10906 10907 /* Checking if kmalloc is successful to allocate space */ 10908 if (!nonce_iv_unaligned) { 10909 ret = QDF_STATUS_E_INVAL; 10910 goto fips_align_fail_nonce_iv; 10911 } 10912 /* Checking if space is aligned */ 10913 if (!FIPS_IS_ALIGNED(nonce_iv_unaligned, FIPS_ALIGN)) { 10914 /* align to 4 */ 10915 nonce_iv_aligned = 10916 (u_int8_t *)FIPS_ALIGNTO(nonce_iv_unaligned, 10917 FIPS_ALIGN); 10918 } else { 10919 nonce_iv_aligned = (u_int8_t *)nonce_iv_unaligned; 10920 } 10921 10922 /* memset and copy content from iv to iv aligned */ 10923 OS_MEMSET(nonce_iv_aligned, 0, param->cmd_params.nonce_iv_len); 10924 OS_MEMCPY(nonce_iv_aligned, param->cmd_params.nonce_iv, 10925 param->cmd_params.nonce_iv_len); 10926 10927 /* print a hexdump for host debug */ 10928 wmi_debug("\t Aligned and Copied Nonce_IV: "); 10929 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 10930 nonce_iv_aligned, 10931 param->cmd_params.nonce_iv_len); 10932 10933 for (c = 0; c < param->cmd_params.nonce_iv_len / 4; c++) { 10934 *((u_int32_t *)nonce_iv_aligned + c) = 10935 qdf_cpu_to_le32(*((u_int32_t *)nonce_iv_aligned + c)); 10936 } 10937 } 10938 10939 /* clean up allocated spaces */ 10940 qdf_mem_free(nonce_iv_unaligned); 10941 nonce_iv_unaligned = NULL; 10942 nonce_iv_aligned = NULL; 10943 10944 fips_align_fail_nonce_iv: 10945 qdf_mem_free(data_unaligned); 10946 data_unaligned = NULL; 10947 data_aligned = NULL; 10948 10949 fips_align_fail_data: 10950 qdf_mem_free(key_unaligned); 10951 key_unaligned = NULL; 10952 key_aligned = NULL; 10953 10954 return ret; 10955 } 10956 #endif 10957 10958 /** 10959 * fips_align_data_be() - LE to BE conversion of FIPS ev data 10960 * @wmi_handle: wmi handle 10961 * @param: fips param related parameters 10962 * 10963 * Return: QDF_STATUS - success or error status 10964 */ 10965 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 10966 struct fips_params *param) 10967 { 10968 unsigned char *key_unaligned, *data_unaligned; 10969 int c; 10970 u_int8_t *key_aligned = NULL; 10971 u_int8_t *data_aligned = NULL; 10972 10973 /* Assigning unaligned space to copy the key */ 10974 key_unaligned = qdf_mem_malloc( 10975 sizeof(u_int8_t)*param->key_len + FIPS_ALIGN); 10976 data_unaligned = qdf_mem_malloc( 10977 sizeof(u_int8_t)*param->data_len + FIPS_ALIGN); 10978 10979 /* Checking if kmalloc is successful to allocate space */ 10980 if (!key_unaligned) 10981 return QDF_STATUS_SUCCESS; 10982 /* Checking if space is aligned */ 10983 if (!FIPS_IS_ALIGNED(key_unaligned, FIPS_ALIGN)) { 10984 /* align to 4 */ 10985 key_aligned = 10986 (u_int8_t *)FIPS_ALIGNTO(key_unaligned, 10987 FIPS_ALIGN); 10988 } else { 10989 key_aligned = (u_int8_t *)key_unaligned; 10990 } 10991 10992 /* memset and copy content from key to key aligned */ 10993 OS_MEMSET(key_aligned, 0, param->key_len); 10994 OS_MEMCPY(key_aligned, param->key, param->key_len); 10995 10996 /* print a hexdump for host debug */ 10997 print_hex_dump(KERN_DEBUG, 10998 "\t Aligned and Copied Key:@@@@ ", 10999 DUMP_PREFIX_NONE, 11000 16, 1, key_aligned, param->key_len, true); 11001 11002 /* Checking if kmalloc is successful to allocate space */ 11003 if (!data_unaligned) 11004 return QDF_STATUS_SUCCESS; 11005 /* Checking of space is aligned */ 11006 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 11007 /* align to 4 */ 11008 data_aligned = 11009 (u_int8_t *)FIPS_ALIGNTO(data_unaligned, 11010 FIPS_ALIGN); 11011 } else { 11012 data_aligned = (u_int8_t *)data_unaligned; 11013 } 11014 11015 /* memset and copy content from data to data aligned */ 11016 OS_MEMSET(data_aligned, 0, param->data_len); 11017 OS_MEMCPY(data_aligned, param->data, param->data_len); 11018 11019 /* print a hexdump for host debug */ 11020 print_hex_dump(KERN_DEBUG, 11021 "\t Properly Aligned and Copied Data:@@@@ ", 11022 DUMP_PREFIX_NONE, 11023 16, 1, data_aligned, param->data_len, true); 11024 11025 /* converting to little Endian both key_aligned and 11026 * data_aligned*/ 11027 for (c = 0; c < param->key_len/4; c++) { 11028 *((u_int32_t *)key_aligned+c) = 11029 qdf_cpu_to_le32(*((u_int32_t *)key_aligned+c)); 11030 } 11031 for (c = 0; c < param->data_len/4; c++) { 11032 *((u_int32_t *)data_aligned+c) = 11033 qdf_cpu_to_le32(*((u_int32_t *)data_aligned+c)); 11034 } 11035 11036 /* update endian data to key and data vectors */ 11037 OS_MEMCPY(param->key, key_aligned, param->key_len); 11038 OS_MEMCPY(param->data, data_aligned, param->data_len); 11039 11040 /* clean up allocated spaces */ 11041 qdf_mem_free(key_unaligned); 11042 key_unaligned = NULL; 11043 key_aligned = NULL; 11044 11045 qdf_mem_free(data_unaligned); 11046 data_unaligned = NULL; 11047 data_aligned = NULL; 11048 11049 return QDF_STATUS_SUCCESS; 11050 } 11051 #else 11052 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 11053 static QDF_STATUS fips_extend_align_data_be(wmi_unified_t wmi_handle, 11054 struct fips_extend_params *param) 11055 { 11056 return QDF_STATUS_SUCCESS; 11057 } 11058 #endif 11059 11060 static QDF_STATUS fips_align_data_be(wmi_unified_t wmi_handle, 11061 struct fips_params *param) 11062 { 11063 return QDF_STATUS_SUCCESS; 11064 } 11065 #endif 11066 11067 #ifdef WLAN_FEATURE_DISA 11068 /** 11069 * send_encrypt_decrypt_send_cmd_tlv() - send encrypt/decrypt cmd to fw 11070 * @wmi_handle: wmi handle 11071 * @encrypt_decrypt_params: encrypt/decrypt params 11072 * 11073 * Return: QDF_STATUS_SUCCESS for success or error code 11074 */ 11075 static QDF_STATUS 11076 send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle, 11077 struct disa_encrypt_decrypt_req_params 11078 *encrypt_decrypt_params) 11079 { 11080 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd; 11081 wmi_buf_t wmi_buf; 11082 uint8_t *buf_ptr; 11083 QDF_STATUS ret; 11084 uint32_t len; 11085 11086 wmi_debug("Send encrypt decrypt cmd"); 11087 11088 len = sizeof(*cmd) + 11089 encrypt_decrypt_params->data_len + 11090 WMI_TLV_HDR_SIZE; 11091 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11092 if (!wmi_buf) 11093 return QDF_STATUS_E_NOMEM; 11094 11095 buf_ptr = wmi_buf_data(wmi_buf); 11096 cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr; 11097 11098 WMITLV_SET_HDR(&cmd->tlv_header, 11099 WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param, 11100 WMITLV_GET_STRUCT_TLVLEN( 11101 wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param)); 11102 11103 cmd->vdev_id = encrypt_decrypt_params->vdev_id; 11104 cmd->key_flag = encrypt_decrypt_params->key_flag; 11105 cmd->key_idx = encrypt_decrypt_params->key_idx; 11106 cmd->key_cipher = encrypt_decrypt_params->key_cipher; 11107 cmd->key_len = encrypt_decrypt_params->key_len; 11108 cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len; 11109 cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len; 11110 11111 qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data, 11112 encrypt_decrypt_params->key_len); 11113 11114 qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header, 11115 MAX_MAC_HEADER_LEN); 11116 11117 cmd->data_len = encrypt_decrypt_params->data_len; 11118 11119 if (cmd->data_len) { 11120 buf_ptr += sizeof(*cmd); 11121 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11122 roundup(encrypt_decrypt_params->data_len, 11123 sizeof(uint32_t))); 11124 buf_ptr += WMI_TLV_HDR_SIZE; 11125 qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data, 11126 encrypt_decrypt_params->data_len); 11127 } 11128 11129 /* This conversion is to facilitate data to FW in little endian */ 11130 cmd->pn[5] = encrypt_decrypt_params->pn[0]; 11131 cmd->pn[4] = encrypt_decrypt_params->pn[1]; 11132 cmd->pn[3] = encrypt_decrypt_params->pn[2]; 11133 cmd->pn[2] = encrypt_decrypt_params->pn[3]; 11134 cmd->pn[1] = encrypt_decrypt_params->pn[4]; 11135 cmd->pn[0] = encrypt_decrypt_params->pn[5]; 11136 11137 wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0); 11138 ret = wmi_unified_cmd_send(wmi_handle, 11139 wmi_buf, len, 11140 WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID); 11141 if (QDF_IS_STATUS_ERROR(ret)) { 11142 wmi_err("Failed to send ENCRYPT DECRYPT cmd: %d", ret); 11143 wmi_buf_free(wmi_buf); 11144 } 11145 11146 return ret; 11147 } 11148 #endif /* WLAN_FEATURE_DISA */ 11149 11150 /** 11151 * send_pdev_fips_cmd_tlv() - send pdev fips cmd to fw 11152 * @wmi_handle: wmi handle 11153 * @param: pointer to hold pdev fips param 11154 * 11155 * Return: QDF_STATUS_SUCCESS for success or error code 11156 */ 11157 static QDF_STATUS 11158 send_pdev_fips_cmd_tlv(wmi_unified_t wmi_handle, 11159 struct fips_params *param) 11160 { 11161 wmi_pdev_fips_cmd_fixed_param *cmd; 11162 wmi_buf_t buf; 11163 uint8_t *buf_ptr; 11164 uint32_t len = sizeof(wmi_pdev_fips_cmd_fixed_param); 11165 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11166 11167 /* Length TLV placeholder for array of bytes */ 11168 len += WMI_TLV_HDR_SIZE; 11169 if (param->data_len) 11170 len += (param->data_len*sizeof(uint8_t)); 11171 11172 /* 11173 * Data length must be multiples of 16 bytes - checked against 0xF - 11174 * and must be less than WMI_SVC_MSG_SIZE - static size of 11175 * wmi_pdev_fips_cmd structure 11176 */ 11177 11178 /* do sanity on the input */ 11179 if (!(((param->data_len & 0xF) == 0) && 11180 ((param->data_len > 0) && 11181 (param->data_len < (WMI_HOST_MAX_BUFFER_SIZE - 11182 sizeof(wmi_pdev_fips_cmd_fixed_param)))))) { 11183 return QDF_STATUS_E_INVAL; 11184 } 11185 11186 buf = wmi_buf_alloc(wmi_handle, len); 11187 if (!buf) 11188 return QDF_STATUS_E_FAILURE; 11189 11190 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11191 cmd = (wmi_pdev_fips_cmd_fixed_param *)buf_ptr; 11192 WMITLV_SET_HDR(&cmd->tlv_header, 11193 WMITLV_TAG_STRUC_wmi_pdev_fips_cmd_fixed_param, 11194 WMITLV_GET_STRUCT_TLVLEN 11195 (wmi_pdev_fips_cmd_fixed_param)); 11196 11197 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11198 wmi_handle, 11199 param->pdev_id); 11200 if (param->key && param->data) { 11201 cmd->key_len = param->key_len; 11202 cmd->data_len = param->data_len; 11203 cmd->fips_cmd = !!(param->op); 11204 11205 if (fips_align_data_be(wmi_handle, param) != QDF_STATUS_SUCCESS) 11206 return QDF_STATUS_E_FAILURE; 11207 11208 qdf_mem_copy(cmd->key, param->key, param->key_len); 11209 11210 if (param->mode == FIPS_ENGINE_AES_CTR || 11211 param->mode == FIPS_ENGINE_AES_MIC) { 11212 cmd->mode = param->mode; 11213 } else { 11214 cmd->mode = FIPS_ENGINE_AES_CTR; 11215 } 11216 11217 print_hex_dump(KERN_DEBUG, "Key: ", DUMP_PREFIX_NONE, 16, 1, 11218 cmd->key, cmd->key_len, true); 11219 buf_ptr += sizeof(*cmd); 11220 11221 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, param->data_len); 11222 11223 buf_ptr += WMI_TLV_HDR_SIZE; 11224 if (param->data_len) 11225 qdf_mem_copy(buf_ptr, 11226 (uint8_t *) param->data, param->data_len); 11227 11228 print_hex_dump(KERN_DEBUG, "Plain text: ", DUMP_PREFIX_NONE, 11229 16, 1, buf_ptr, cmd->data_len, true); 11230 11231 buf_ptr += param->data_len; 11232 11233 wmi_mtrace(WMI_PDEV_FIPS_CMDID, NO_SESSION, 0); 11234 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11235 WMI_PDEV_FIPS_CMDID); 11236 } else { 11237 qdf_print("\n%s:%d Key or Data is NULL", __func__, __LINE__); 11238 wmi_buf_free(buf); 11239 retval = -QDF_STATUS_E_BADMSG; 11240 } 11241 11242 return retval; 11243 } 11244 11245 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 11246 /** 11247 * send_pdev_fips_extend_cmd_tlv() - send pdev fips cmd to fw 11248 * @wmi_handle: wmi handle 11249 * @param: pointer to hold pdev fips param 11250 * 11251 * Return: QDF_STATUS_SUCCESS for success or error code 11252 */ 11253 static QDF_STATUS 11254 send_pdev_fips_extend_cmd_tlv(wmi_unified_t wmi_handle, 11255 struct fips_extend_params *param) 11256 { 11257 wmi_pdev_fips_extend_cmd_fixed_param *cmd; 11258 wmi_buf_t buf; 11259 uint8_t *buf_ptr; 11260 uint32_t len = sizeof(wmi_pdev_fips_extend_cmd_fixed_param); 11261 uint32_t data_len_aligned; 11262 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11263 11264 len += WMI_TLV_HDR_SIZE; 11265 if (param->frag_idx == 0) 11266 len += sizeof(wmi_fips_extend_cmd_init_params); 11267 11268 /* Length TLV placeholder for array of bytes */ 11269 len += WMI_TLV_HDR_SIZE; 11270 if (param->data_len) { 11271 data_len_aligned = roundup(param->data_len, sizeof(uint32_t)); 11272 len += (data_len_aligned * sizeof(uint8_t)); 11273 } 11274 11275 buf = wmi_buf_alloc(wmi_handle, len); 11276 if (!buf) 11277 return QDF_STATUS_E_FAILURE; 11278 11279 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11280 cmd = (wmi_pdev_fips_extend_cmd_fixed_param *)buf_ptr; 11281 WMITLV_SET_HDR(&cmd->tlv_header, 11282 WMITLV_TAG_STRUC_wmi_pdev_fips_extend_cmd_fixed_param, 11283 WMITLV_GET_STRUCT_TLVLEN 11284 (wmi_pdev_fips_extend_cmd_fixed_param)); 11285 11286 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11287 wmi_handle, 11288 param->pdev_id); 11289 11290 cmd->fips_cookie = param->cookie; 11291 cmd->frag_idx = param->frag_idx; 11292 cmd->more_bit = param->more_bit; 11293 cmd->data_len = param->data_len; 11294 11295 if (fips_extend_align_data_be(wmi_handle, param) != 11296 QDF_STATUS_SUCCESS) { 11297 wmi_buf_free(buf); 11298 return QDF_STATUS_E_FAILURE; 11299 } 11300 11301 buf_ptr = (uint8_t *)(cmd + 1); 11302 if (cmd->frag_idx == 0) { 11303 wmi_fips_extend_cmd_init_params *cmd_params; 11304 11305 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11306 sizeof(wmi_fips_extend_cmd_init_params)); 11307 buf_ptr += WMI_TLV_HDR_SIZE; 11308 cmd_params = (wmi_fips_extend_cmd_init_params *)buf_ptr; 11309 WMITLV_SET_HDR(buf_ptr, 11310 WMITLV_TAG_STRUC_wmi_fips_extend_cmd_init_params, 11311 WMITLV_GET_STRUCT_TLVLEN(wmi_fips_extend_cmd_init_params)); 11312 cmd_params->fips_cmd = param->cmd_params.fips_cmd; 11313 cmd_params->key_cipher = param->cmd_params.key_cipher; 11314 cmd_params->key_len = param->cmd_params.key_len; 11315 cmd_params->nonce_iv_len = param->cmd_params.nonce_iv_len; 11316 cmd_params->tag_len = param->cmd_params.tag_len; 11317 cmd_params->aad_len = param->cmd_params.aad_len; 11318 cmd_params->payload_len = param->cmd_params.payload_len; 11319 11320 qdf_mem_copy(cmd_params->key, param->cmd_params.key, 11321 param->cmd_params.key_len); 11322 qdf_mem_copy(cmd_params->nonce_iv, param->cmd_params.nonce_iv, 11323 param->cmd_params.nonce_iv_len); 11324 11325 wmi_debug("Key len = %d, IVNoncelen = %d, Tlen = %d, Alen = %d, Plen = %d", 11326 cmd_params->key_len, cmd_params->nonce_iv_len, 11327 cmd_params->tag_len, cmd_params->aad_len, 11328 cmd_params->payload_len); 11329 11330 buf_ptr += sizeof(wmi_fips_extend_cmd_init_params); 11331 } else { 11332 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11333 buf_ptr += WMI_TLV_HDR_SIZE; 11334 } 11335 11336 if (param->data_len && param->data) { 11337 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 11338 data_len_aligned); 11339 11340 buf_ptr += WMI_TLV_HDR_SIZE; 11341 if (param->data_len) 11342 qdf_mem_copy(buf_ptr, 11343 (uint8_t *)param->data, param->data_len); 11344 11345 wmi_debug("Data: "); 11346 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 11347 buf_ptr, cmd->data_len); 11348 11349 if (param->data_len) 11350 buf_ptr += param->data_len; 11351 } else { 11352 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); 11353 buf_ptr += WMI_TLV_HDR_SIZE; 11354 } 11355 11356 wmi_mtrace(WMI_PDEV_FIPS_EXTEND_CMDID, NO_SESSION, 0); 11357 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11358 WMI_PDEV_FIPS_EXTEND_CMDID); 11359 11360 if (retval) { 11361 wmi_err("Failed to send FIPS cmd"); 11362 wmi_buf_free(buf); 11363 } 11364 11365 return retval; 11366 } 11367 11368 /** 11369 * send_pdev_fips_mode_set_cmd_tlv() - send pdev fips cmd to fw 11370 * @wmi_handle: wmi handle 11371 * @param: pointer to hold pdev fips param 11372 * 11373 * Return: QDF_STATUS_SUCCESS for success or error code 11374 */ 11375 static QDF_STATUS 11376 send_pdev_fips_mode_set_cmd_tlv(wmi_unified_t wmi_handle, 11377 struct fips_mode_set_params *param) 11378 { 11379 wmi_pdev_fips_mode_set_cmd_fixed_param *cmd; 11380 wmi_buf_t buf; 11381 uint8_t *buf_ptr; 11382 uint32_t len = sizeof(wmi_pdev_fips_mode_set_cmd_fixed_param); 11383 QDF_STATUS retval = QDF_STATUS_SUCCESS; 11384 11385 buf = wmi_buf_alloc(wmi_handle, len); 11386 if (!buf) 11387 return QDF_STATUS_E_FAILURE; 11388 11389 buf_ptr = (uint8_t *)wmi_buf_data(buf); 11390 cmd = (wmi_pdev_fips_mode_set_cmd_fixed_param *)buf_ptr; 11391 WMITLV_SET_HDR(&cmd->tlv_header, 11392 WMITLV_TAG_STRUC_wmi_pdev_fips_mode_set_cmd_fixed_param, 11393 WMITLV_GET_STRUCT_TLVLEN 11394 (wmi_pdev_fips_mode_set_cmd_fixed_param)); 11395 11396 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11397 wmi_handle, 11398 param->pdev_id); 11399 11400 cmd->fips_mode_set = param->mode; 11401 wmi_mtrace(WMI_PDEV_FIPS_MODE_SET_CMDID, NO_SESSION, 0); 11402 retval = wmi_unified_cmd_send(wmi_handle, buf, len, 11403 WMI_PDEV_FIPS_MODE_SET_CMDID); 11404 if (retval) { 11405 wmi_err("Failed to send FIPS mode enable cmd"); 11406 wmi_buf_free(buf); 11407 } 11408 return retval; 11409 } 11410 #endif 11411 11412 /** 11413 * send_wlan_profile_enable_cmd_tlv() - send wlan profile enable command 11414 * to fw 11415 * @wmi_handle: wmi handle 11416 * @param: pointer to wlan profile param 11417 * 11418 * Return: QDF_STATUS_SUCCESS for success or error code 11419 */ 11420 static QDF_STATUS 11421 send_wlan_profile_enable_cmd_tlv(wmi_unified_t wmi_handle, 11422 struct wlan_profile_params *param) 11423 { 11424 wmi_buf_t buf; 11425 uint16_t len; 11426 QDF_STATUS ret; 11427 wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd; 11428 11429 len = sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param); 11430 buf = wmi_buf_alloc(wmi_handle, len); 11431 if (!buf) { 11432 wmi_err("Failed to send WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID"); 11433 return QDF_STATUS_E_NOMEM; 11434 } 11435 11436 profile_enable_cmd = 11437 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *) 11438 wmi_buf_data(buf); 11439 WMITLV_SET_HDR(&profile_enable_cmd->tlv_header, 11440 WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, 11441 WMITLV_GET_STRUCT_TLVLEN 11442 (wmi_wlan_profile_enable_profile_id_cmd_fixed_param)); 11443 11444 profile_enable_cmd->profile_id = param->profile_id; 11445 profile_enable_cmd->enable = param->enable; 11446 wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, 11447 NO_SESSION, 0); 11448 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11449 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); 11450 if (ret) { 11451 wmi_err("Failed to send PROFILE_ENABLE_PROFILE_ID_CMDID"); 11452 wmi_buf_free(buf); 11453 } 11454 return ret; 11455 } 11456 11457 /** 11458 * send_wlan_profile_trigger_cmd_tlv() - send wlan profile trigger command 11459 * to fw 11460 * @wmi_handle: wmi handle 11461 * @param: pointer to wlan profile param 11462 * 11463 * Return: QDF_STATUS_SUCCESS for success or error code 11464 */ 11465 static QDF_STATUS 11466 send_wlan_profile_trigger_cmd_tlv(wmi_unified_t wmi_handle, 11467 struct wlan_profile_params *param) 11468 { 11469 wmi_buf_t buf; 11470 uint16_t len; 11471 QDF_STATUS ret; 11472 wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd; 11473 11474 len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param); 11475 buf = wmi_buf_alloc(wmi_handle, len); 11476 if (!buf) { 11477 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11478 return QDF_STATUS_E_NOMEM; 11479 } 11480 11481 prof_trig_cmd = 11482 (wmi_wlan_profile_trigger_cmd_fixed_param *) 11483 wmi_buf_data(buf); 11484 11485 WMITLV_SET_HDR(&prof_trig_cmd->tlv_header, 11486 WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, 11487 WMITLV_GET_STRUCT_TLVLEN 11488 (wmi_wlan_profile_trigger_cmd_fixed_param)); 11489 11490 prof_trig_cmd->enable = param->enable; 11491 wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0); 11492 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11493 WMI_WLAN_PROFILE_TRIGGER_CMDID); 11494 if (ret) { 11495 wmi_err("Failed to send WMI_WLAN_PROFILE_TRIGGER_CMDID"); 11496 wmi_buf_free(buf); 11497 } 11498 return ret; 11499 } 11500 11501 /** 11502 * send_wlan_profile_hist_intvl_cmd_tlv() - send wlan profile interval command 11503 * to fw 11504 * @wmi_handle: wmi handle 11505 * @param: pointer to wlan profile param 11506 * 11507 * Return: QDF_STATUS_SUCCESS for success or error code 11508 */ 11509 static QDF_STATUS 11510 send_wlan_profile_hist_intvl_cmd_tlv(wmi_unified_t wmi_handle, 11511 struct wlan_profile_params *param) 11512 { 11513 wmi_buf_t buf; 11514 int32_t len = 0; 11515 QDF_STATUS ret; 11516 wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd; 11517 11518 len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param); 11519 buf = wmi_buf_alloc(wmi_handle, len); 11520 if (!buf) { 11521 wmi_err("Failed to send WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID"); 11522 return QDF_STATUS_E_NOMEM; 11523 } 11524 11525 hist_intvl_cmd = 11526 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *) 11527 wmi_buf_data(buf); 11528 11529 WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header, 11530 WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, 11531 WMITLV_GET_STRUCT_TLVLEN 11532 (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param)); 11533 11534 hist_intvl_cmd->profile_id = param->profile_id; 11535 hist_intvl_cmd->value = param->enable; 11536 wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, 11537 NO_SESSION, 0); 11538 11539 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11540 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); 11541 if (ret) { 11542 wmi_err("Failed to send PROFILE_SET_HIST_INTVL_CMDID"); 11543 wmi_buf_free(buf); 11544 } 11545 return ret; 11546 } 11547 11548 /** 11549 * send_fw_test_cmd_tlv() - send fw test command to fw. 11550 * @wmi_handle: wmi handle 11551 * @wmi_fwtest: fw test command 11552 * 11553 * This function sends fw test command to fw. 11554 * 11555 * Return: CDF STATUS 11556 */ 11557 static 11558 QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle, 11559 struct set_fwtest_params *wmi_fwtest) 11560 { 11561 wmi_fwtest_set_param_cmd_fixed_param *cmd; 11562 wmi_buf_t wmi_buf; 11563 uint16_t len; 11564 11565 len = sizeof(*cmd); 11566 11567 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11568 if (!wmi_buf) 11569 return QDF_STATUS_E_NOMEM; 11570 11571 cmd = (wmi_fwtest_set_param_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11572 WMITLV_SET_HDR(&cmd->tlv_header, 11573 WMITLV_TAG_STRUC_wmi_fwtest_set_param_cmd_fixed_param, 11574 WMITLV_GET_STRUCT_TLVLEN( 11575 wmi_fwtest_set_param_cmd_fixed_param)); 11576 cmd->param_id = wmi_fwtest->arg; 11577 cmd->param_value = wmi_fwtest->value; 11578 11579 wmi_mtrace(WMI_FWTEST_CMDID, NO_SESSION, 0); 11580 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11581 WMI_FWTEST_CMDID)) { 11582 wmi_err("Failed to send fw test command"); 11583 wmi_buf_free(wmi_buf); 11584 return QDF_STATUS_E_FAILURE; 11585 } 11586 11587 return QDF_STATUS_SUCCESS; 11588 } 11589 11590 static uint16_t wfa_config_param_len(enum wfa_test_cmds config) 11591 { 11592 uint16_t len = 0; 11593 11594 if (config == WFA_CONFIG_RXNE) 11595 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe); 11596 else 11597 len += WMI_TLV_HDR_SIZE; 11598 11599 if (config == WFA_CONFIG_CSA) 11600 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa); 11601 else 11602 len += WMI_TLV_HDR_SIZE; 11603 11604 if (config == WFA_CONFIG_OCV) 11605 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv); 11606 else 11607 len += WMI_TLV_HDR_SIZE; 11608 11609 if (config == WFA_CONFIG_SA_QUERY) 11610 len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery); 11611 else 11612 len += WMI_TLV_HDR_SIZE; 11613 11614 return len; 11615 } 11616 11617 /** 11618 * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type. 11619 * @host_frmtype: Host defined OCV frame type 11620 * @ocv_frmtype: Pointer to hold WMI OCV frame type 11621 * 11622 * This function converts and fills host defined OCV frame type into WMI OCV 11623 * frame type. 11624 * 11625 * Return: CDF STATUS 11626 */ 11627 static QDF_STATUS 11628 wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype) 11629 { 11630 switch (host_frmtype) { 11631 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: 11632 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ; 11633 break; 11634 11635 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: 11636 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP; 11637 break; 11638 11639 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: 11640 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ; 11641 break; 11642 11643 case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: 11644 *ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ; 11645 break; 11646 11647 default: 11648 wmi_err("Invalid command type cmd %d", host_frmtype); 11649 return QDF_STATUS_E_FAILURE; 11650 } 11651 11652 return QDF_STATUS_SUCCESS; 11653 } 11654 11655 /** 11656 * send_wfa_test_cmd_tlv() - send wfa test command to fw. 11657 * @wmi_handle: wmi handle 11658 * @wmi_wfatest: wfa test command 11659 * 11660 * This function sends wfa test command to fw. 11661 * 11662 * Return: CDF STATUS 11663 */ 11664 static 11665 QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle, 11666 struct set_wfatest_params *wmi_wfatest) 11667 { 11668 wmi_wfa_config_cmd_fixed_param *cmd; 11669 wmi_wfa_config_rsnxe *rxne; 11670 wmi_wfa_config_csa *csa; 11671 wmi_wfa_config_ocv *ocv; 11672 wmi_wfa_config_saquery *saquery; 11673 wmi_buf_t wmi_buf; 11674 uint16_t len = sizeof(*cmd); 11675 uint8_t *buf_ptr; 11676 11677 len += wfa_config_param_len(wmi_wfatest->cmd); 11678 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11679 if (!wmi_buf) 11680 return QDF_STATUS_E_NOMEM; 11681 11682 cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf); 11683 WMITLV_SET_HDR(&cmd->tlv_header, 11684 WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param, 11685 WMITLV_GET_STRUCT_TLVLEN( 11686 wmi_wfa_config_cmd_fixed_param)); 11687 11688 cmd->vdev_id = wmi_wfatest->vdev_id; 11689 buf_ptr = (uint8_t *)(cmd + 1); 11690 11691 if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) { 11692 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11693 sizeof(wmi_wfa_config_rsnxe)); 11694 buf_ptr += WMI_TLV_HDR_SIZE; 11695 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe, 11696 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe)); 11697 rxne = (wmi_wfa_config_rsnxe *)buf_ptr; 11698 rxne->rsnxe_param = wmi_wfatest->value; 11699 buf_ptr += sizeof(wmi_wfa_config_rsnxe); 11700 } else { 11701 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11702 buf_ptr += WMI_TLV_HDR_SIZE; 11703 } 11704 11705 if (wmi_wfatest->cmd == WFA_CONFIG_CSA) { 11706 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11707 sizeof(wmi_wfa_config_csa)); 11708 buf_ptr += WMI_TLV_HDR_SIZE; 11709 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa, 11710 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa)); 11711 csa = (wmi_wfa_config_csa *)buf_ptr; 11712 csa->ignore_csa = wmi_wfatest->value; 11713 buf_ptr += sizeof(wmi_wfa_config_csa); 11714 } else { 11715 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11716 buf_ptr += WMI_TLV_HDR_SIZE; 11717 } 11718 11719 if (wmi_wfatest->cmd == WFA_CONFIG_OCV) { 11720 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11721 sizeof(wmi_wfa_config_ocv)); 11722 buf_ptr += WMI_TLV_HDR_SIZE; 11723 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv, 11724 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv)); 11725 ocv = (wmi_wfa_config_ocv *)buf_ptr; 11726 11727 if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type, 11728 &ocv->frame_types)) 11729 goto error; 11730 11731 ocv->chan_freq = wmi_wfatest->ocv_param->freq; 11732 buf_ptr += sizeof(wmi_wfa_config_ocv); 11733 } else { 11734 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11735 buf_ptr += WMI_TLV_HDR_SIZE; 11736 } 11737 11738 if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) { 11739 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 11740 sizeof(wmi_wfa_config_saquery)); 11741 buf_ptr += WMI_TLV_HDR_SIZE; 11742 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery, 11743 WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery)); 11744 11745 saquery = (wmi_wfa_config_saquery *)buf_ptr; 11746 saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value; 11747 } else { 11748 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); 11749 buf_ptr += WMI_TLV_HDR_SIZE; 11750 } 11751 11752 wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0); 11753 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11754 WMI_WFA_CONFIG_CMDID)) { 11755 wmi_err("Failed to send wfa test command"); 11756 goto error; 11757 } 11758 11759 return QDF_STATUS_SUCCESS; 11760 11761 error: 11762 wmi_buf_free(wmi_buf); 11763 return QDF_STATUS_E_FAILURE; 11764 } 11765 11766 /** 11767 * send_unit_test_cmd_tlv() - send unit test command to fw. 11768 * @wmi_handle: wmi handle 11769 * @wmi_utest: unit test command 11770 * 11771 * This function send unit test command to fw. 11772 * 11773 * Return: CDF STATUS 11774 */ 11775 static QDF_STATUS send_unit_test_cmd_tlv(wmi_unified_t wmi_handle, 11776 struct wmi_unit_test_cmd *wmi_utest) 11777 { 11778 wmi_unit_test_cmd_fixed_param *cmd; 11779 wmi_buf_t wmi_buf; 11780 uint8_t *buf_ptr; 11781 int i; 11782 uint16_t len, args_tlv_len; 11783 uint32_t *unit_test_cmd_args; 11784 11785 args_tlv_len = 11786 WMI_TLV_HDR_SIZE + wmi_utest->num_args * sizeof(uint32_t); 11787 len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; 11788 11789 wmi_buf = wmi_buf_alloc(wmi_handle, len); 11790 if (!wmi_buf) 11791 return QDF_STATUS_E_NOMEM; 11792 11793 cmd = (wmi_unit_test_cmd_fixed_param *) wmi_buf_data(wmi_buf); 11794 buf_ptr = (uint8_t *) cmd; 11795 WMITLV_SET_HDR(&cmd->tlv_header, 11796 WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, 11797 WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); 11798 cmd->vdev_id = wmi_utest->vdev_id; 11799 cmd->module_id = wmi_utest->module_id; 11800 cmd->num_args = wmi_utest->num_args; 11801 cmd->diag_token = wmi_utest->diag_token; 11802 buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); 11803 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11804 (wmi_utest->num_args * sizeof(uint32_t))); 11805 unit_test_cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11806 wmi_debug("VDEV ID: %d MODULE ID: %d TOKEN: %d", 11807 cmd->vdev_id, cmd->module_id, cmd->diag_token); 11808 wmi_debug("%d num of args = ", wmi_utest->num_args); 11809 for (i = 0; (i < wmi_utest->num_args && i < WMI_UNIT_TEST_MAX_NUM_ARGS); i++) { 11810 unit_test_cmd_args[i] = wmi_utest->args[i]; 11811 wmi_debug("%d,", wmi_utest->args[i]); 11812 } 11813 wmi_mtrace(WMI_UNIT_TEST_CMDID, cmd->vdev_id, 0); 11814 if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, 11815 WMI_UNIT_TEST_CMDID)) { 11816 wmi_err("Failed to send unit test command"); 11817 wmi_buf_free(wmi_buf); 11818 return QDF_STATUS_E_FAILURE; 11819 } 11820 11821 return QDF_STATUS_SUCCESS; 11822 } 11823 11824 /** 11825 * send_power_dbg_cmd_tlv() - send power debug commands 11826 * @wmi_handle: wmi handle 11827 * @param: wmi power debug parameter 11828 * 11829 * Send WMI_POWER_DEBUG_CMDID parameters to fw. 11830 * 11831 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11832 */ 11833 static QDF_STATUS send_power_dbg_cmd_tlv(wmi_unified_t wmi_handle, 11834 struct wmi_power_dbg_params *param) 11835 { 11836 wmi_buf_t buf = NULL; 11837 QDF_STATUS status; 11838 int len, args_tlv_len; 11839 uint8_t *buf_ptr; 11840 uint8_t i; 11841 wmi_pdev_wal_power_debug_cmd_fixed_param *cmd; 11842 uint32_t *cmd_args; 11843 11844 /* Prepare and send power debug cmd parameters */ 11845 args_tlv_len = WMI_TLV_HDR_SIZE + param->num_args * sizeof(uint32_t); 11846 len = sizeof(*cmd) + args_tlv_len; 11847 buf = wmi_buf_alloc(wmi_handle, len); 11848 if (!buf) 11849 return QDF_STATUS_E_NOMEM; 11850 11851 buf_ptr = (uint8_t *) wmi_buf_data(buf); 11852 cmd = (wmi_pdev_wal_power_debug_cmd_fixed_param *) buf_ptr; 11853 WMITLV_SET_HDR(&cmd->tlv_header, 11854 WMITLV_TAG_STRUC_wmi_pdev_wal_power_debug_cmd_fixed_param, 11855 WMITLV_GET_STRUCT_TLVLEN 11856 (wmi_pdev_wal_power_debug_cmd_fixed_param)); 11857 11858 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11859 wmi_handle, 11860 param->pdev_id); 11861 cmd->module_id = param->module_id; 11862 cmd->num_args = param->num_args; 11863 buf_ptr += sizeof(*cmd); 11864 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 11865 (param->num_args * sizeof(uint32_t))); 11866 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); 11867 wmi_debug("%d num of args = ", param->num_args); 11868 for (i = 0; (i < param->num_args && i < WMI_MAX_POWER_DBG_ARGS); i++) { 11869 cmd_args[i] = param->args[i]; 11870 wmi_debug("%d,", param->args[i]); 11871 } 11872 11873 wmi_mtrace(WMI_PDEV_WAL_POWER_DEBUG_CMDID, NO_SESSION, 0); 11874 status = wmi_unified_cmd_send(wmi_handle, buf, 11875 len, WMI_PDEV_WAL_POWER_DEBUG_CMDID); 11876 if (QDF_IS_STATUS_ERROR(status)) { 11877 wmi_err("wmi_unified_cmd_send WMI_PDEV_WAL_POWER_DEBUG_CMDID returned Error %d", 11878 status); 11879 goto error; 11880 } 11881 11882 return QDF_STATUS_SUCCESS; 11883 error: 11884 wmi_buf_free(buf); 11885 11886 return status; 11887 } 11888 11889 /** 11890 * send_dfs_phyerr_offload_en_cmd_tlv() - send dfs phyerr offload enable cmd 11891 * @wmi_handle: wmi handle 11892 * @pdev_id: pdev id 11893 * 11894 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID command to firmware. 11895 * 11896 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11897 */ 11898 static QDF_STATUS send_dfs_phyerr_offload_en_cmd_tlv(wmi_unified_t wmi_handle, 11899 uint32_t pdev_id) 11900 { 11901 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *cmd; 11902 wmi_buf_t buf; 11903 uint16_t len; 11904 QDF_STATUS ret; 11905 11906 len = sizeof(*cmd); 11907 buf = wmi_buf_alloc(wmi_handle, len); 11908 11909 wmi_debug("pdev_id=%d", pdev_id); 11910 11911 if (!buf) 11912 return QDF_STATUS_E_NOMEM; 11913 11914 cmd = (wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param *) 11915 wmi_buf_data(buf); 11916 11917 WMITLV_SET_HDR(&cmd->tlv_header, 11918 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param, 11919 WMITLV_GET_STRUCT_TLVLEN( 11920 wmi_pdev_dfs_phyerr_offload_enable_cmd_fixed_param)); 11921 11922 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11923 wmi_handle, 11924 pdev_id); 11925 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID, NO_SESSION, 0); 11926 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11927 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID); 11928 if (QDF_IS_STATUS_ERROR(ret)) { 11929 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11930 ret, pdev_id); 11931 wmi_buf_free(buf); 11932 return QDF_STATUS_E_FAILURE; 11933 } 11934 11935 return QDF_STATUS_SUCCESS; 11936 } 11937 11938 /** 11939 * send_dfs_phyerr_offload_dis_cmd_tlv() - send dfs phyerr offload disable cmd 11940 * @wmi_handle: wmi handle 11941 * @pdev_id: pdev id 11942 * 11943 * Send WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID command to firmware. 11944 * 11945 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 11946 */ 11947 static QDF_STATUS send_dfs_phyerr_offload_dis_cmd_tlv(wmi_unified_t wmi_handle, 11948 uint32_t pdev_id) 11949 { 11950 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *cmd; 11951 wmi_buf_t buf; 11952 uint16_t len; 11953 QDF_STATUS ret; 11954 11955 len = sizeof(*cmd); 11956 buf = wmi_buf_alloc(wmi_handle, len); 11957 11958 wmi_debug("pdev_id=%d", pdev_id); 11959 11960 if (!buf) 11961 return QDF_STATUS_E_NOMEM; 11962 11963 cmd = (wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param *) 11964 wmi_buf_data(buf); 11965 11966 WMITLV_SET_HDR(&cmd->tlv_header, 11967 WMITLV_TAG_STRUC_wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param, 11968 WMITLV_GET_STRUCT_TLVLEN( 11969 wmi_pdev_dfs_phyerr_offload_disable_cmd_fixed_param)); 11970 11971 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 11972 wmi_handle, 11973 pdev_id); 11974 wmi_mtrace(WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID, NO_SESSION, 0); 11975 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 11976 WMI_PDEV_DFS_PHYERR_OFFLOAD_DISABLE_CMDID); 11977 if (QDF_IS_STATUS_ERROR(ret)) { 11978 wmi_err("Failed to send cmd to fw, ret=%d, pdev_id=%d", 11979 ret, pdev_id); 11980 wmi_buf_free(buf); 11981 return QDF_STATUS_E_FAILURE; 11982 } 11983 11984 return QDF_STATUS_SUCCESS; 11985 } 11986 11987 #ifdef QCA_SUPPORT_AGILE_DFS 11988 static 11989 QDF_STATUS send_adfs_ch_cfg_cmd_tlv(wmi_unified_t wmi_handle, 11990 struct vdev_adfs_ch_cfg_params *param) 11991 { 11992 /* wmi_unified_cmd_send set request of agile ADFS channel*/ 11993 wmi_vdev_adfs_ch_cfg_cmd_fixed_param *cmd; 11994 wmi_buf_t buf; 11995 QDF_STATUS ret; 11996 uint16_t len; 11997 11998 len = sizeof(*cmd); 11999 buf = wmi_buf_alloc(wmi_handle, len); 12000 12001 if (!buf) { 12002 wmi_err("wmi_buf_alloc failed"); 12003 return QDF_STATUS_E_NOMEM; 12004 } 12005 12006 cmd = (wmi_vdev_adfs_ch_cfg_cmd_fixed_param *) 12007 wmi_buf_data(buf); 12008 12009 WMITLV_SET_HDR(&cmd->tlv_header, 12010 WMITLV_TAG_STRUC_wmi_vdev_adfs_ch_cfg_cmd_fixed_param, 12011 WMITLV_GET_STRUCT_TLVLEN 12012 (wmi_vdev_adfs_ch_cfg_cmd_fixed_param)); 12013 12014 cmd->vdev_id = param->vdev_id; 12015 cmd->ocac_mode = param->ocac_mode; 12016 cmd->center_freq1 = param->center_freq1; 12017 cmd->center_freq2 = param->center_freq2; 12018 cmd->chan_freq = param->chan_freq; 12019 cmd->chan_width = param->chan_width; 12020 cmd->min_duration_ms = param->min_duration_ms; 12021 cmd->max_duration_ms = param->max_duration_ms; 12022 wmi_debug("cmd->vdev_id: %d ,cmd->ocac_mode: %d cmd->center_freq: %d", 12023 cmd->vdev_id, cmd->ocac_mode, 12024 cmd->center_freq); 12025 12026 wmi_mtrace(WMI_VDEV_ADFS_CH_CFG_CMDID, NO_SESSION, 0); 12027 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12028 WMI_VDEV_ADFS_CH_CFG_CMDID); 12029 12030 if (QDF_IS_STATUS_ERROR(ret)) { 12031 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12032 wmi_buf_free(buf); 12033 return QDF_STATUS_E_FAILURE; 12034 } 12035 12036 return QDF_STATUS_SUCCESS; 12037 } 12038 12039 static 12040 QDF_STATUS send_adfs_ocac_abort_cmd_tlv(wmi_unified_t wmi_handle, 12041 struct vdev_adfs_abort_params *param) 12042 { 12043 /*wmi_unified_cmd_send with ocac abort on ADFS channel*/ 12044 wmi_vdev_adfs_ocac_abort_cmd_fixed_param *cmd; 12045 wmi_buf_t buf; 12046 QDF_STATUS ret; 12047 uint16_t len; 12048 12049 len = sizeof(*cmd); 12050 buf = wmi_buf_alloc(wmi_handle, len); 12051 12052 if (!buf) { 12053 wmi_err("wmi_buf_alloc failed"); 12054 return QDF_STATUS_E_NOMEM; 12055 } 12056 12057 cmd = (wmi_vdev_adfs_ocac_abort_cmd_fixed_param *) 12058 wmi_buf_data(buf); 12059 12060 WMITLV_SET_HDR 12061 (&cmd->tlv_header, 12062 WMITLV_TAG_STRUC_wmi_vdev_adfs_ocac_abort_cmd_fixed_param, 12063 WMITLV_GET_STRUCT_TLVLEN 12064 (wmi_vdev_adfs_ocac_abort_cmd_fixed_param)); 12065 12066 cmd->vdev_id = param->vdev_id; 12067 12068 wmi_mtrace(WMI_VDEV_ADFS_OCAC_ABORT_CMDID, NO_SESSION, 0); 12069 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12070 WMI_VDEV_ADFS_OCAC_ABORT_CMDID); 12071 12072 if (QDF_IS_STATUS_ERROR(ret)) { 12073 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12074 wmi_buf_free(buf); 12075 return QDF_STATUS_E_FAILURE; 12076 } 12077 12078 return QDF_STATUS_SUCCESS; 12079 } 12080 #endif 12081 12082 /** 12083 * init_cmd_send_tlv() - send initialization cmd to fw 12084 * @wmi_handle: wmi handle 12085 * @param: pointer to wmi init param 12086 * 12087 * Return: QDF_STATUS_SUCCESS for success or error code 12088 */ 12089 static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle, 12090 struct wmi_init_cmd_param *param) 12091 { 12092 wmi_buf_t buf; 12093 wmi_init_cmd_fixed_param *cmd; 12094 uint8_t *buf_ptr; 12095 wmi_resource_config *resource_cfg; 12096 wlan_host_memory_chunk *host_mem_chunks; 12097 uint32_t mem_chunk_len = 0, hw_mode_len = 0; 12098 uint16_t idx; 12099 int len; 12100 QDF_STATUS ret; 12101 12102 len = sizeof(*cmd) + sizeof(wmi_resource_config) + 12103 WMI_TLV_HDR_SIZE; 12104 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); 12105 12106 if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) 12107 hw_mode_len = sizeof(wmi_pdev_set_hw_mode_cmd_fixed_param) + 12108 WMI_TLV_HDR_SIZE + 12109 (param->num_band_to_mac * sizeof(wmi_pdev_band_to_mac)); 12110 12111 buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len + hw_mode_len); 12112 if (!buf) 12113 return QDF_STATUS_E_FAILURE; 12114 12115 buf_ptr = (uint8_t *) wmi_buf_data(buf); 12116 cmd = (wmi_init_cmd_fixed_param *) buf_ptr; 12117 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); 12118 12119 host_mem_chunks = (wlan_host_memory_chunk *) 12120 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) 12121 + WMI_TLV_HDR_SIZE); 12122 12123 WMITLV_SET_HDR(&cmd->tlv_header, 12124 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, 12125 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); 12126 wmi_copy_resource_config(resource_cfg, param->res_cfg); 12127 WMITLV_SET_HDR(&resource_cfg->tlv_header, 12128 WMITLV_TAG_STRUC_wmi_resource_config, 12129 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); 12130 12131 for (idx = 0; idx < param->num_mem_chunks; ++idx) { 12132 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), 12133 WMITLV_TAG_STRUC_wlan_host_memory_chunk, 12134 WMITLV_GET_STRUCT_TLVLEN 12135 (wlan_host_memory_chunk)); 12136 host_mem_chunks[idx].ptr = param->mem_chunks[idx].paddr; 12137 host_mem_chunks[idx].size = param->mem_chunks[idx].len; 12138 host_mem_chunks[idx].req_id = param->mem_chunks[idx].req_id; 12139 if (is_service_enabled_tlv(wmi_handle, 12140 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS)) 12141 host_mem_chunks[idx].ptr_high = 12142 qdf_get_upper_32_bits( 12143 param->mem_chunks[idx].paddr); 12144 QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, 12145 "chunk %d len %d requested ,ptr 0x%x ", 12146 idx, host_mem_chunks[idx].size, 12147 host_mem_chunks[idx].ptr); 12148 } 12149 cmd->num_host_mem_chunks = param->num_mem_chunks; 12150 len += (param->num_mem_chunks * sizeof(wlan_host_memory_chunk)); 12151 12152 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), 12153 WMITLV_TAG_ARRAY_STRUC, 12154 (sizeof(wlan_host_memory_chunk) * 12155 param->num_mem_chunks)); 12156 12157 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", 12158 resource_cfg->num_peers, resource_cfg->num_offload_peers, 12159 resource_cfg->num_vdevs, resource_cfg->num_tids, 12160 resource_cfg->num_tdls_conn_table_entries, 12161 resource_cfg->num_tdls_vdevs); 12162 12163 /* Fill hw mode id config */ 12164 buf_ptr = copy_hw_mode_in_init_cmd(wmi_handle, buf_ptr, &len, param); 12165 12166 /* Fill fw_abi_vers */ 12167 copy_fw_abi_version_tlv(wmi_handle, cmd); 12168 12169 wmi_mtrace(WMI_INIT_CMDID, NO_SESSION, 0); 12170 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_INIT_CMDID); 12171 if (QDF_IS_STATUS_ERROR(ret)) { 12172 wmi_err("wmi_unified_cmd_send WMI_INIT_CMDID returned Error %d", 12173 ret); 12174 wmi_buf_free(buf); 12175 } 12176 12177 return ret; 12178 12179 } 12180 12181 /** 12182 * send_addba_send_cmd_tlv() - send addba send command to fw 12183 * @wmi_handle: wmi handle 12184 * @param: pointer to delba send params 12185 * @macaddr: peer mac address 12186 * 12187 * Send WMI_ADDBA_SEND_CMDID command to firmware 12188 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 12189 */ 12190 static QDF_STATUS 12191 send_addba_send_cmd_tlv(wmi_unified_t wmi_handle, 12192 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12193 struct addba_send_params *param) 12194 { 12195 wmi_addba_send_cmd_fixed_param *cmd; 12196 wmi_buf_t buf; 12197 uint16_t len; 12198 QDF_STATUS ret; 12199 12200 len = sizeof(*cmd); 12201 12202 buf = wmi_buf_alloc(wmi_handle, len); 12203 if (!buf) 12204 return QDF_STATUS_E_NOMEM; 12205 12206 cmd = (wmi_addba_send_cmd_fixed_param *)wmi_buf_data(buf); 12207 12208 WMITLV_SET_HDR(&cmd->tlv_header, 12209 WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, 12210 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_send_cmd_fixed_param)); 12211 12212 cmd->vdev_id = param->vdev_id; 12213 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12214 cmd->tid = param->tidno; 12215 cmd->buffersize = param->buffersize; 12216 12217 wmi_mtrace(WMI_ADDBA_SEND_CMDID, cmd->vdev_id, 0); 12218 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ADDBA_SEND_CMDID); 12219 if (QDF_IS_STATUS_ERROR(ret)) { 12220 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12221 wmi_buf_free(buf); 12222 return QDF_STATUS_E_FAILURE; 12223 } 12224 12225 return QDF_STATUS_SUCCESS; 12226 } 12227 12228 /** 12229 * send_delba_send_cmd_tlv() - send delba send command to fw 12230 * @wmi_handle: wmi handle 12231 * @param: pointer to delba send params 12232 * @macaddr: peer mac address 12233 * 12234 * Send WMI_DELBA_SEND_CMDID command to firmware 12235 * Return: QDF_STATUS_SUCCESS on success. QDF_STATUS_E** on error 12236 */ 12237 static QDF_STATUS 12238 send_delba_send_cmd_tlv(wmi_unified_t wmi_handle, 12239 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12240 struct delba_send_params *param) 12241 { 12242 wmi_delba_send_cmd_fixed_param *cmd; 12243 wmi_buf_t buf; 12244 uint16_t len; 12245 QDF_STATUS ret; 12246 12247 len = sizeof(*cmd); 12248 12249 buf = wmi_buf_alloc(wmi_handle, len); 12250 if (!buf) 12251 return QDF_STATUS_E_NOMEM; 12252 12253 cmd = (wmi_delba_send_cmd_fixed_param *)wmi_buf_data(buf); 12254 12255 WMITLV_SET_HDR(&cmd->tlv_header, 12256 WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, 12257 WMITLV_GET_STRUCT_TLVLEN(wmi_delba_send_cmd_fixed_param)); 12258 12259 cmd->vdev_id = param->vdev_id; 12260 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12261 cmd->tid = param->tidno; 12262 cmd->initiator = param->initiator; 12263 cmd->reasoncode = param->reasoncode; 12264 12265 wmi_mtrace(WMI_DELBA_SEND_CMDID, cmd->vdev_id, 0); 12266 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_DELBA_SEND_CMDID); 12267 if (QDF_IS_STATUS_ERROR(ret)) { 12268 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12269 wmi_buf_free(buf); 12270 return QDF_STATUS_E_FAILURE; 12271 } 12272 12273 return QDF_STATUS_SUCCESS; 12274 } 12275 12276 /** 12277 * send_addba_clearresponse_cmd_tlv() - send addba clear response command 12278 * to fw 12279 * @wmi_handle: wmi handle 12280 * @param: pointer to addba clearresp params 12281 * @macaddr: peer mac address 12282 * Return: QDF_STATUS_SUCCESS for success or error code 12283 */ 12284 static QDF_STATUS 12285 send_addba_clearresponse_cmd_tlv(wmi_unified_t wmi_handle, 12286 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 12287 struct addba_clearresponse_params *param) 12288 { 12289 wmi_addba_clear_resp_cmd_fixed_param *cmd; 12290 wmi_buf_t buf; 12291 uint16_t len; 12292 QDF_STATUS ret; 12293 12294 len = sizeof(*cmd); 12295 12296 buf = wmi_buf_alloc(wmi_handle, len); 12297 if (!buf) 12298 return QDF_STATUS_E_FAILURE; 12299 12300 cmd = (wmi_addba_clear_resp_cmd_fixed_param *)wmi_buf_data(buf); 12301 12302 WMITLV_SET_HDR(&cmd->tlv_header, 12303 WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, 12304 WMITLV_GET_STRUCT_TLVLEN(wmi_addba_clear_resp_cmd_fixed_param)); 12305 12306 cmd->vdev_id = param->vdev_id; 12307 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 12308 12309 wmi_mtrace(WMI_ADDBA_CLEAR_RESP_CMDID, cmd->vdev_id, 0); 12310 ret = wmi_unified_cmd_send(wmi_handle, 12311 buf, len, WMI_ADDBA_CLEAR_RESP_CMDID); 12312 if (QDF_IS_STATUS_ERROR(ret)) { 12313 wmi_err("Failed to send cmd to fw, ret=%d", ret); 12314 wmi_buf_free(buf); 12315 return QDF_STATUS_E_FAILURE; 12316 } 12317 12318 return QDF_STATUS_SUCCESS; 12319 } 12320 12321 #ifdef OBSS_PD 12322 /** 12323 * send_obss_spatial_reuse_set_def_thresh_cmd_tlv - send obss spatial reuse set 12324 * def thresh to fw 12325 * @wmi_handle: wmi handle 12326 * @thresh: pointer to obss_spatial_reuse_def_thresh 12327 * 12328 * Return: QDF_STATUS_SUCCESS for success or error code 12329 */ 12330 static 12331 QDF_STATUS send_obss_spatial_reuse_set_def_thresh_cmd_tlv( 12332 wmi_unified_t wmi_handle, 12333 struct wmi_host_obss_spatial_reuse_set_def_thresh 12334 *thresh) 12335 { 12336 wmi_buf_t buf; 12337 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *cmd; 12338 QDF_STATUS ret; 12339 uint32_t cmd_len; 12340 uint32_t tlv_len; 12341 12342 cmd_len = sizeof(*cmd); 12343 12344 buf = wmi_buf_alloc(wmi_handle, cmd_len); 12345 if (!buf) 12346 return QDF_STATUS_E_NOMEM; 12347 12348 cmd = (wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param *) 12349 wmi_buf_data(buf); 12350 12351 tlv_len = WMITLV_GET_STRUCT_TLVLEN( 12352 wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param); 12353 12354 WMITLV_SET_HDR(&cmd->tlv_header, 12355 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_def_obss_thresh_cmd_fixed_param, 12356 tlv_len); 12357 12358 cmd->obss_min = thresh->obss_min; 12359 cmd->obss_max = thresh->obss_max; 12360 cmd->vdev_type = thresh->vdev_type; 12361 ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, 12362 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID); 12363 if (QDF_IS_STATUS_ERROR(ret)) 12364 wmi_buf_free(buf); 12365 12366 return ret; 12367 } 12368 12369 /** 12370 * send_obss_spatial_reuse_set_cmd_tlv - send obss spatial reuse set cmd to fw 12371 * @wmi_handle: wmi handle 12372 * @obss_spatial_reuse_param: pointer to obss_spatial_reuse_param 12373 * 12374 * Return: QDF_STATUS_SUCCESS for success or error code 12375 */ 12376 static 12377 QDF_STATUS send_obss_spatial_reuse_set_cmd_tlv(wmi_unified_t wmi_handle, 12378 struct wmi_host_obss_spatial_reuse_set_param 12379 *obss_spatial_reuse_param) 12380 { 12381 wmi_buf_t buf; 12382 wmi_obss_spatial_reuse_set_cmd_fixed_param *cmd; 12383 QDF_STATUS ret; 12384 uint32_t len; 12385 12386 len = sizeof(*cmd); 12387 12388 buf = wmi_buf_alloc(wmi_handle, len); 12389 if (!buf) 12390 return QDF_STATUS_E_FAILURE; 12391 12392 cmd = (wmi_obss_spatial_reuse_set_cmd_fixed_param *)wmi_buf_data(buf); 12393 WMITLV_SET_HDR(&cmd->tlv_header, 12394 WMITLV_TAG_STRUC_wmi_obss_spatial_reuse_set_cmd_fixed_param, 12395 WMITLV_GET_STRUCT_TLVLEN 12396 (wmi_obss_spatial_reuse_set_cmd_fixed_param)); 12397 12398 cmd->enable = obss_spatial_reuse_param->enable; 12399 cmd->obss_min = obss_spatial_reuse_param->obss_min; 12400 cmd->obss_max = obss_spatial_reuse_param->obss_max; 12401 cmd->vdev_id = obss_spatial_reuse_param->vdev_id; 12402 12403 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12404 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); 12405 12406 if (QDF_IS_STATUS_ERROR(ret)) { 12407 wmi_err( 12408 "WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID send returned Error %d", 12409 ret); 12410 wmi_buf_free(buf); 12411 } 12412 12413 return ret; 12414 } 12415 12416 /** 12417 * send_self_srg_bss_color_bitmap_set_cmd_tlv() - Send 64-bit BSS color bitmap 12418 * to be used by SRG based Spatial Reuse feature to the FW 12419 * @wmi_handle: wmi handle 12420 * @bitmap_0: lower 32 bits in BSS color bitmap 12421 * @bitmap_1: upper 32 bits in BSS color bitmap 12422 * @pdev_id: pdev ID 12423 * 12424 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12425 */ 12426 static QDF_STATUS 12427 send_self_srg_bss_color_bitmap_set_cmd_tlv( 12428 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12429 uint32_t bitmap_1, uint8_t pdev_id) 12430 { 12431 wmi_buf_t buf; 12432 wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *cmd; 12433 QDF_STATUS ret; 12434 uint32_t len; 12435 12436 len = sizeof(*cmd); 12437 12438 buf = wmi_buf_alloc(wmi_handle, len); 12439 if (!buf) 12440 return QDF_STATUS_E_FAILURE; 12441 12442 cmd = (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param *) 12443 wmi_buf_data(buf); 12444 12445 WMITLV_SET_HDR( 12446 &cmd->tlv_header, 12447 WMITLV_TAG_STRUC_wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param, 12448 WMITLV_GET_STRUCT_TLVLEN 12449 (wmi_pdev_srg_bss_color_bitmap_cmd_fixed_param)); 12450 12451 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12452 wmi_handle, pdev_id); 12453 cmd->srg_bss_color_bitmap[0] = bitmap_0; 12454 cmd->srg_bss_color_bitmap[1] = bitmap_1; 12455 12456 ret = wmi_unified_cmd_send( 12457 wmi_handle, buf, len, 12458 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID); 12459 12460 if (QDF_IS_STATUS_ERROR(ret)) { 12461 wmi_err( 12462 "WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID send returned Error %d", 12463 ret); 12464 wmi_buf_free(buf); 12465 } 12466 12467 return ret; 12468 } 12469 12470 /** 12471 * send_self_srg_partial_bssid_bitmap_set_cmd_tlv() - Send 64-bit partial BSSID 12472 * bitmap to be used by SRG based Spatial Reuse feature to the FW 12473 * @wmi_handle: wmi handle 12474 * @bitmap_0: lower 32 bits in partial BSSID bitmap 12475 * @bitmap_1: upper 32 bits in partial BSSID bitmap 12476 * @pdev_id: pdev ID 12477 * 12478 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12479 */ 12480 static QDF_STATUS 12481 send_self_srg_partial_bssid_bitmap_set_cmd_tlv( 12482 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12483 uint32_t bitmap_1, uint8_t pdev_id) 12484 { 12485 wmi_buf_t buf; 12486 wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *cmd; 12487 QDF_STATUS ret; 12488 uint32_t len; 12489 12490 len = sizeof(*cmd); 12491 12492 buf = wmi_buf_alloc(wmi_handle, len); 12493 if (!buf) 12494 return QDF_STATUS_E_FAILURE; 12495 12496 cmd = (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param *) 12497 wmi_buf_data(buf); 12498 12499 WMITLV_SET_HDR( 12500 &cmd->tlv_header, 12501 WMITLV_TAG_STRUC_wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param, 12502 WMITLV_GET_STRUCT_TLVLEN 12503 (wmi_pdev_srg_partial_bssid_bitmap_cmd_fixed_param)); 12504 12505 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12506 wmi_handle, pdev_id); 12507 12508 cmd->srg_partial_bssid_bitmap[0] = bitmap_0; 12509 cmd->srg_partial_bssid_bitmap[1] = bitmap_1; 12510 12511 ret = wmi_unified_cmd_send( 12512 wmi_handle, buf, len, 12513 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID); 12514 12515 if (QDF_IS_STATUS_ERROR(ret)) { 12516 wmi_err( 12517 "WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID send returned Error %d", 12518 ret); 12519 wmi_buf_free(buf); 12520 } 12521 12522 return ret; 12523 } 12524 12525 /** 12526 * send_self_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12527 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12528 * @wmi_handle: wmi handle 12529 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12530 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12531 * @pdev_id: pdev ID 12532 * 12533 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12534 */ 12535 static QDF_STATUS 12536 send_self_srg_obss_color_enable_bitmap_cmd_tlv( 12537 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12538 uint32_t bitmap_1, uint8_t pdev_id) 12539 { 12540 wmi_buf_t buf; 12541 wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12542 QDF_STATUS ret; 12543 uint32_t len; 12544 12545 len = sizeof(*cmd); 12546 12547 buf = wmi_buf_alloc(wmi_handle, len); 12548 if (!buf) 12549 return QDF_STATUS_E_FAILURE; 12550 12551 cmd = (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12552 wmi_buf_data(buf); 12553 12554 WMITLV_SET_HDR( 12555 &cmd->tlv_header, 12556 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param, 12557 WMITLV_GET_STRUCT_TLVLEN 12558 (wmi_pdev_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12559 12560 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12561 wmi_handle, pdev_id); 12562 cmd->srg_obss_en_color_bitmap[0] = bitmap_0; 12563 cmd->srg_obss_en_color_bitmap[1] = bitmap_1; 12564 12565 ret = wmi_unified_cmd_send( 12566 wmi_handle, buf, len, 12567 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12568 12569 if (QDF_IS_STATUS_ERROR(ret)) { 12570 wmi_err( 12571 "WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12572 ret); 12573 wmi_buf_free(buf); 12574 } 12575 12576 return ret; 12577 } 12578 12579 /** 12580 * send_self_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12581 * enable bitmap to be used by SRG based Spatial Reuse feature to the FW 12582 * @wmi_handle: wmi handle 12583 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12584 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12585 * @pdev_id: pdev ID 12586 * 12587 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12588 */ 12589 static QDF_STATUS 12590 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv( 12591 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12592 uint32_t bitmap_1, uint8_t pdev_id) 12593 { 12594 wmi_buf_t buf; 12595 wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12596 QDF_STATUS ret; 12597 uint32_t len; 12598 12599 len = sizeof(*cmd); 12600 12601 buf = wmi_buf_alloc(wmi_handle, len); 12602 if (!buf) 12603 return QDF_STATUS_E_FAILURE; 12604 12605 cmd = (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12606 wmi_buf_data(buf); 12607 12608 WMITLV_SET_HDR( 12609 &cmd->tlv_header, 12610 WMITLV_TAG_STRUC_wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12611 WMITLV_GET_STRUCT_TLVLEN 12612 (wmi_pdev_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12613 12614 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12615 wmi_handle, pdev_id); 12616 cmd->srg_obss_en_bssid_bitmap[0] = bitmap_0; 12617 cmd->srg_obss_en_bssid_bitmap[1] = bitmap_1; 12618 12619 ret = wmi_unified_cmd_send( 12620 wmi_handle, buf, len, 12621 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12622 12623 if (QDF_IS_STATUS_ERROR(ret)) { 12624 wmi_err( 12625 "WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12626 ret); 12627 wmi_buf_free(buf); 12628 } 12629 12630 return ret; 12631 } 12632 12633 /** 12634 * send_self_non_srg_obss_color_enable_bitmap_cmd_tlv() - Send 64-bit BSS color 12635 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12636 * @wmi_handle: wmi handle 12637 * @bitmap_0: lower 32 bits in BSS color enable bitmap 12638 * @bitmap_1: upper 32 bits in BSS color enable bitmap 12639 * @pdev_id: pdev ID 12640 * 12641 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12642 */ 12643 static QDF_STATUS 12644 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv( 12645 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12646 uint32_t bitmap_1, uint8_t pdev_id) 12647 { 12648 wmi_buf_t buf; 12649 wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *cmd; 12650 QDF_STATUS ret; 12651 uint32_t len; 12652 12653 len = sizeof(*cmd); 12654 12655 buf = wmi_buf_alloc(wmi_handle, len); 12656 if (!buf) 12657 return QDF_STATUS_E_FAILURE; 12658 12659 cmd = (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param *) 12660 wmi_buf_data(buf); 12661 12662 WMITLV_SET_HDR( 12663 &cmd->tlv_header, 12664 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param, 12665 WMITLV_GET_STRUCT_TLVLEN 12666 (wmi_pdev_non_srg_obss_color_enable_bitmap_cmd_fixed_param)); 12667 12668 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12669 wmi_handle, pdev_id); 12670 cmd->non_srg_obss_en_color_bitmap[0] = bitmap_0; 12671 cmd->non_srg_obss_en_color_bitmap[1] = bitmap_1; 12672 12673 ret = wmi_unified_cmd_send( 12674 wmi_handle, buf, len, 12675 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID); 12676 12677 if (QDF_IS_STATUS_ERROR(ret)) { 12678 wmi_err( 12679 "WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID send returned Error %d", 12680 ret); 12681 wmi_buf_free(buf); 12682 } 12683 12684 return ret; 12685 } 12686 12687 /** 12688 * send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv() - Send 64-bit OBSS BSSID 12689 * enable bitmap to be used by Non-SRG based Spatial Reuse feature to the FW 12690 * @wmi_handle: wmi handle 12691 * @bitmap_0: lower 32 bits in BSSID enable bitmap 12692 * @bitmap_1: upper 32 bits in BSSID enable bitmap 12693 * @pdev_id: pdev ID 12694 * 12695 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 12696 */ 12697 static QDF_STATUS 12698 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv( 12699 wmi_unified_t wmi_handle, uint32_t bitmap_0, 12700 uint32_t bitmap_1, uint8_t pdev_id) 12701 { 12702 wmi_buf_t buf; 12703 wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *cmd; 12704 QDF_STATUS ret; 12705 uint32_t len; 12706 12707 len = sizeof(*cmd); 12708 12709 buf = wmi_buf_alloc(wmi_handle, len); 12710 if (!buf) 12711 return QDF_STATUS_E_FAILURE; 12712 12713 cmd = (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param *) 12714 wmi_buf_data(buf); 12715 12716 WMITLV_SET_HDR( 12717 &cmd->tlv_header, 12718 WMITLV_TAG_STRUC_wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param, 12719 WMITLV_GET_STRUCT_TLVLEN 12720 (wmi_pdev_non_srg_obss_bssid_enable_bitmap_cmd_fixed_param)); 12721 12722 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 12723 wmi_handle, pdev_id); 12724 cmd->non_srg_obss_en_bssid_bitmap[0] = bitmap_0; 12725 cmd->non_srg_obss_en_bssid_bitmap[1] = bitmap_1; 12726 12727 ret = wmi_unified_cmd_send( 12728 wmi_handle, buf, len, 12729 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID); 12730 12731 if (QDF_IS_STATUS_ERROR(ret)) { 12732 wmi_err( 12733 "WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID send returned Error %d", 12734 ret); 12735 wmi_buf_free(buf); 12736 } 12737 12738 return ret; 12739 } 12740 #endif 12741 12742 static 12743 QDF_STATUS send_injector_config_cmd_tlv(wmi_unified_t wmi_handle, 12744 struct wmi_host_injector_frame_params *inject_config_params) 12745 { 12746 wmi_buf_t buf; 12747 wmi_frame_inject_cmd_fixed_param *cmd; 12748 QDF_STATUS ret; 12749 uint32_t len; 12750 12751 len = sizeof(*cmd); 12752 12753 buf = wmi_buf_alloc(wmi_handle, len); 12754 if (!buf) 12755 return QDF_STATUS_E_NOMEM; 12756 12757 cmd = (wmi_frame_inject_cmd_fixed_param *)wmi_buf_data(buf); 12758 WMITLV_SET_HDR(&cmd->tlv_header, 12759 WMITLV_TAG_STRUC_wmi_frame_inject_cmd_fixed_param, 12760 WMITLV_GET_STRUCT_TLVLEN 12761 (wmi_frame_inject_cmd_fixed_param)); 12762 12763 cmd->vdev_id = inject_config_params->vdev_id; 12764 cmd->enable = inject_config_params->enable; 12765 cmd->frame_type = inject_config_params->frame_type; 12766 cmd->frame_inject_period = inject_config_params->frame_inject_period; 12767 cmd->fc_duration = inject_config_params->frame_duration; 12768 WMI_CHAR_ARRAY_TO_MAC_ADDR(inject_config_params->dstmac, 12769 &cmd->frame_addr1); 12770 cmd->bw = inject_config_params->frame_bw; 12771 12772 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 12773 WMI_PDEV_FRAME_INJECT_CMDID); 12774 12775 if (QDF_IS_STATUS_ERROR(ret)) { 12776 wmi_err( 12777 "WMI_PDEV_FRAME_INJECT_CMDID send returned Error %d", 12778 ret); 12779 wmi_buf_free(buf); 12780 } 12781 12782 return ret; 12783 } 12784 #ifdef QCA_SUPPORT_CP_STATS 12785 /** 12786 * extract_cca_stats_tlv - api to extract congestion stats from event buffer 12787 * @wmi_handle: wma handle 12788 * @evt_buf: event buffer 12789 * @out_buff: buffer to populated after stats extraction 12790 * 12791 * Return: status of operation 12792 */ 12793 static QDF_STATUS extract_cca_stats_tlv(wmi_unified_t wmi_handle, 12794 void *evt_buf, struct wmi_host_congestion_stats *out_buff) 12795 { 12796 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 12797 wmi_congestion_stats *congestion_stats; 12798 12799 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 12800 congestion_stats = param_buf->congestion_stats; 12801 if (!congestion_stats) 12802 return QDF_STATUS_E_INVAL; 12803 12804 out_buff->vdev_id = congestion_stats->vdev_id; 12805 out_buff->congestion = congestion_stats->congestion; 12806 12807 wmi_debug("cca stats event processed"); 12808 return QDF_STATUS_SUCCESS; 12809 } 12810 #endif /* QCA_SUPPORT_CP_STATS */ 12811 12812 /** 12813 * extract_ctl_failsafe_check_ev_param_tlv() - extract ctl data from 12814 * event 12815 * @wmi_handle: wmi handle 12816 * @evt_buf: pointer to event buffer 12817 * @param: Pointer to hold peer ctl data 12818 * 12819 * Return: QDF_STATUS_SUCCESS for success or error code 12820 */ 12821 static QDF_STATUS extract_ctl_failsafe_check_ev_param_tlv( 12822 wmi_unified_t wmi_handle, 12823 void *evt_buf, 12824 struct wmi_host_pdev_ctl_failsafe_event *param) 12825 { 12826 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *param_buf; 12827 wmi_pdev_ctl_failsafe_check_fixed_param *fix_param; 12828 12829 param_buf = (WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID_param_tlvs *)evt_buf; 12830 if (!param_buf) { 12831 wmi_err("Invalid ctl_failsafe event buffer"); 12832 return QDF_STATUS_E_INVAL; 12833 } 12834 12835 fix_param = param_buf->fixed_param; 12836 param->ctl_failsafe_status = fix_param->ctl_FailsafeStatus; 12837 12838 return QDF_STATUS_SUCCESS; 12839 } 12840 12841 /** 12842 * save_service_bitmap_tlv() - save service bitmap 12843 * @wmi_handle: wmi handle 12844 * @evt_buf: pointer to event buffer 12845 * @bitmap_buf: bitmap buffer, for converged legacy support 12846 * 12847 * Return: QDF_STATUS 12848 */ 12849 static 12850 QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12851 void *bitmap_buf) 12852 { 12853 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12854 struct wmi_soc *soc = wmi_handle->soc; 12855 12856 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12857 12858 /* If it is already allocated, use that buffer. This can happen 12859 * during target stop/start scenarios where host allocation is skipped. 12860 */ 12861 if (!soc->wmi_service_bitmap) { 12862 soc->wmi_service_bitmap = 12863 qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)); 12864 if (!soc->wmi_service_bitmap) 12865 return QDF_STATUS_E_NOMEM; 12866 } 12867 12868 qdf_mem_copy(soc->wmi_service_bitmap, 12869 param_buf->wmi_service_bitmap, 12870 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12871 12872 if (bitmap_buf) 12873 qdf_mem_copy(bitmap_buf, 12874 param_buf->wmi_service_bitmap, 12875 (WMI_SERVICE_BM_SIZE * sizeof(uint32_t))); 12876 12877 return QDF_STATUS_SUCCESS; 12878 } 12879 12880 /** 12881 * save_ext_service_bitmap_tlv() - save extendend service bitmap 12882 * @wmi_handle: wmi handle 12883 * @evt_buf: pointer to event buffer 12884 * @bitmap_buf: bitmap buffer, for converged legacy support 12885 * 12886 * Return: QDF_STATUS 12887 */ 12888 static 12889 QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf, 12890 void *bitmap_buf) 12891 { 12892 WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf; 12893 wmi_service_available_event_fixed_param *ev; 12894 struct wmi_soc *soc = wmi_handle->soc; 12895 uint32_t i = 0; 12896 12897 param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf; 12898 12899 ev = param_buf->fixed_param; 12900 12901 /* If it is already allocated, use that buffer. This can happen 12902 * during target stop/start scenarios where host allocation is skipped. 12903 */ 12904 if (!soc->wmi_ext_service_bitmap) { 12905 soc->wmi_ext_service_bitmap = qdf_mem_malloc( 12906 WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)); 12907 if (!soc->wmi_ext_service_bitmap) 12908 return QDF_STATUS_E_NOMEM; 12909 } 12910 12911 qdf_mem_copy(soc->wmi_ext_service_bitmap, 12912 ev->wmi_service_segment_bitmap, 12913 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12914 12915 wmi_debug("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", 12916 soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1], 12917 soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]); 12918 12919 if (bitmap_buf) 12920 qdf_mem_copy(bitmap_buf, 12921 soc->wmi_ext_service_bitmap, 12922 (WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t))); 12923 12924 if (!param_buf->wmi_service_ext_bitmap) { 12925 wmi_debug("wmi_service_ext_bitmap not available"); 12926 return QDF_STATUS_SUCCESS; 12927 } 12928 12929 if (!soc->wmi_ext2_service_bitmap || 12930 (param_buf->num_wmi_service_ext_bitmap > 12931 soc->wmi_ext2_service_bitmap_len)) { 12932 if (soc->wmi_ext2_service_bitmap) { 12933 qdf_mem_free(soc->wmi_ext2_service_bitmap); 12934 soc->wmi_ext2_service_bitmap = NULL; 12935 } 12936 soc->wmi_ext2_service_bitmap = 12937 qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap * 12938 sizeof(uint32_t)); 12939 if (!soc->wmi_ext2_service_bitmap) 12940 return QDF_STATUS_E_NOMEM; 12941 12942 soc->wmi_ext2_service_bitmap_len = 12943 param_buf->num_wmi_service_ext_bitmap; 12944 } 12945 12946 qdf_mem_copy(soc->wmi_ext2_service_bitmap, 12947 param_buf->wmi_service_ext_bitmap, 12948 (param_buf->num_wmi_service_ext_bitmap * 12949 sizeof(uint32_t))); 12950 12951 for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) { 12952 wmi_debug("wmi_ext2_service_bitmap %u:0x%x", 12953 i, soc->wmi_ext2_service_bitmap[i]); 12954 } 12955 12956 return QDF_STATUS_SUCCESS; 12957 } 12958 12959 static inline void copy_ht_cap_info(uint32_t ev_target_cap, 12960 struct wlan_psoc_target_capability_info *cap) 12961 { 12962 /* except LDPC all flags are common between legacy and here 12963 * also IBFEER is not defined for TLV 12964 */ 12965 cap->ht_cap_info |= ev_target_cap & ( 12966 WMI_HT_CAP_ENABLED 12967 | WMI_HT_CAP_HT20_SGI 12968 | WMI_HT_CAP_DYNAMIC_SMPS 12969 | WMI_HT_CAP_TX_STBC 12970 | WMI_HT_CAP_TX_STBC_MASK_SHIFT 12971 | WMI_HT_CAP_RX_STBC 12972 | WMI_HT_CAP_RX_STBC_MASK_SHIFT 12973 | WMI_HT_CAP_LDPC 12974 | WMI_HT_CAP_L_SIG_TXOP_PROT 12975 | WMI_HT_CAP_MPDU_DENSITY 12976 | WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 12977 | WMI_HT_CAP_HT40_SGI); 12978 if (ev_target_cap & WMI_HT_CAP_LDPC) 12979 cap->ht_cap_info |= WMI_HOST_HT_CAP_RX_LDPC | 12980 WMI_HOST_HT_CAP_TX_LDPC; 12981 } 12982 /** 12983 * extract_service_ready_tlv() - extract service ready event 12984 * @wmi_handle: wmi handle 12985 * @evt_buf: pointer to received event buffer 12986 * @cap: pointer to hold target capability information extracted from even 12987 * 12988 * Return: QDF_STATUS_SUCCESS for success or error code 12989 */ 12990 static QDF_STATUS extract_service_ready_tlv(wmi_unified_t wmi_handle, 12991 void *evt_buf, struct wlan_psoc_target_capability_info *cap) 12992 { 12993 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 12994 wmi_service_ready_event_fixed_param *ev; 12995 12996 12997 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 12998 12999 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13000 if (!ev) { 13001 qdf_print("%s: wmi_buf_alloc failed", __func__); 13002 return QDF_STATUS_E_FAILURE; 13003 } 13004 13005 cap->phy_capability = ev->phy_capability; 13006 cap->max_frag_entry = ev->max_frag_entry; 13007 cap->num_rf_chains = ev->num_rf_chains; 13008 copy_ht_cap_info(ev->ht_cap_info, cap); 13009 cap->vht_cap_info = ev->vht_cap_info; 13010 cap->vht_supp_mcs = ev->vht_supp_mcs; 13011 cap->hw_min_tx_power = ev->hw_min_tx_power; 13012 cap->hw_max_tx_power = ev->hw_max_tx_power; 13013 cap->sys_cap_info = ev->sys_cap_info; 13014 cap->min_pkt_size_enable = ev->min_pkt_size_enable; 13015 cap->max_bcn_ie_size = ev->max_bcn_ie_size; 13016 cap->max_num_scan_channels = ev->max_num_scan_channels; 13017 cap->max_supported_macs = ev->max_supported_macs; 13018 cap->wmi_fw_sub_feat_caps = ev->wmi_fw_sub_feat_caps; 13019 cap->txrx_chainmask = ev->txrx_chainmask; 13020 cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; 13021 cap->num_msdu_desc = ev->num_msdu_desc; 13022 cap->fw_version = ev->fw_build_vers; 13023 /* fw_version_1 is not available in TLV. */ 13024 cap->fw_version_1 = 0; 13025 13026 return QDF_STATUS_SUCCESS; 13027 } 13028 13029 /* convert_wireless_modes_tlv() - Convert REGDMN_MODE values sent by target 13030 * to host internal HOST_REGDMN_MODE values. 13031 * REGULATORY TODO : REGDMN_MODE_11AC_VHT*_2G values are not used by the 13032 * host currently. Add this in the future if required. 13033 * 11AX (Phase II) : 11ax related values are not currently 13034 * advertised separately by FW. As part of phase II regulatory bring-up, 13035 * finalize the advertisement mechanism. 13036 * @target_wireless_mode: target wireless mode received in message 13037 * 13038 * Return: returns the host internal wireless mode. 13039 */ 13040 static inline uint32_t convert_wireless_modes_tlv(uint32_t target_wireless_mode) 13041 { 13042 13043 uint32_t wireless_modes = 0; 13044 13045 wmi_debug("Target wireless mode: 0x%x", target_wireless_mode); 13046 13047 if (target_wireless_mode & REGDMN_MODE_11A) 13048 wireless_modes |= HOST_REGDMN_MODE_11A; 13049 13050 if (target_wireless_mode & REGDMN_MODE_TURBO) 13051 wireless_modes |= HOST_REGDMN_MODE_TURBO; 13052 13053 if (target_wireless_mode & REGDMN_MODE_11B) 13054 wireless_modes |= HOST_REGDMN_MODE_11B; 13055 13056 if (target_wireless_mode & REGDMN_MODE_PUREG) 13057 wireless_modes |= HOST_REGDMN_MODE_PUREG; 13058 13059 if (target_wireless_mode & REGDMN_MODE_11G) 13060 wireless_modes |= HOST_REGDMN_MODE_11G; 13061 13062 if (target_wireless_mode & REGDMN_MODE_108G) 13063 wireless_modes |= HOST_REGDMN_MODE_108G; 13064 13065 if (target_wireless_mode & REGDMN_MODE_108A) 13066 wireless_modes |= HOST_REGDMN_MODE_108A; 13067 13068 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20_2G) 13069 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20_2G; 13070 13071 if (target_wireless_mode & REGDMN_MODE_XR) 13072 wireless_modes |= HOST_REGDMN_MODE_XR; 13073 13074 if (target_wireless_mode & REGDMN_MODE_11A_HALF_RATE) 13075 wireless_modes |= HOST_REGDMN_MODE_11A_HALF_RATE; 13076 13077 if (target_wireless_mode & REGDMN_MODE_11A_QUARTER_RATE) 13078 wireless_modes |= HOST_REGDMN_MODE_11A_QUARTER_RATE; 13079 13080 if (target_wireless_mode & REGDMN_MODE_11NG_HT20) 13081 wireless_modes |= HOST_REGDMN_MODE_11NG_HT20; 13082 13083 if (target_wireless_mode & REGDMN_MODE_11NA_HT20) 13084 wireless_modes |= HOST_REGDMN_MODE_11NA_HT20; 13085 13086 if (target_wireless_mode & REGDMN_MODE_11NG_HT40PLUS) 13087 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40PLUS; 13088 13089 if (target_wireless_mode & REGDMN_MODE_11NG_HT40MINUS) 13090 wireless_modes |= HOST_REGDMN_MODE_11NG_HT40MINUS; 13091 13092 if (target_wireless_mode & REGDMN_MODE_11NA_HT40PLUS) 13093 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40PLUS; 13094 13095 if (target_wireless_mode & REGDMN_MODE_11NA_HT40MINUS) 13096 wireless_modes |= HOST_REGDMN_MODE_11NA_HT40MINUS; 13097 13098 if (target_wireless_mode & REGDMN_MODE_11AC_VHT20) 13099 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT20; 13100 13101 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40PLUS) 13102 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40PLUS; 13103 13104 if (target_wireless_mode & REGDMN_MODE_11AC_VHT40MINUS) 13105 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT40MINUS; 13106 13107 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80) 13108 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80; 13109 13110 if (target_wireless_mode & REGDMN_MODE_11AC_VHT160) 13111 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT160; 13112 13113 if (target_wireless_mode & REGDMN_MODE_11AC_VHT80_80) 13114 wireless_modes |= HOST_REGDMN_MODE_11AC_VHT80_80; 13115 13116 return wireless_modes; 13117 } 13118 13119 /** 13120 * convert_11be_phybitmap_to_reg_flags() - Convert 11BE phybitmap to 13121 * to regulatory flags. 13122 * @target_phybitmap: target phybitmap. 13123 * @phybitmap: host internal REGULATORY_PHYMODE set based on target 13124 * phybitmap. 13125 * 13126 * Return: None 13127 */ 13128 13129 #ifdef WLAN_FEATURE_11BE 13130 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 13131 uint32_t *phybitmap) 13132 { 13133 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11BE) 13134 *phybitmap |= REGULATORY_PHYMODE_NO11BE; 13135 } 13136 #else 13137 static void convert_11be_phybitmap_to_reg_flags(uint32_t target_phybitmap, 13138 uint32_t *phybitmap) 13139 { 13140 } 13141 #endif 13142 13143 /* convert_phybitmap_tlv() - Convert WMI_REGULATORY_PHYBITMAP values sent by 13144 * target to host internal REGULATORY_PHYMODE values. 13145 * 13146 * @target_target_phybitmap: target phybitmap received in the message. 13147 * 13148 * Return: returns the host internal REGULATORY_PHYMODE. 13149 */ 13150 static uint32_t convert_phybitmap_tlv(uint32_t target_phybitmap) 13151 { 13152 uint32_t phybitmap = 0; 13153 13154 wmi_debug("Target phybitmap: 0x%x", target_phybitmap); 13155 13156 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11A) 13157 phybitmap |= REGULATORY_PHYMODE_NO11A; 13158 13159 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11B) 13160 phybitmap |= REGULATORY_PHYMODE_NO11B; 13161 13162 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11G) 13163 phybitmap |= REGULATORY_PHYMODE_NO11G; 13164 13165 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11N) 13166 phybitmap |= REGULATORY_CHAN_NO11N; 13167 13168 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AC) 13169 phybitmap |= REGULATORY_PHYMODE_NO11AC; 13170 13171 if (target_phybitmap & WMI_REGULATORY_PHYMODE_NO11AX) 13172 phybitmap |= REGULATORY_PHYMODE_NO11AX; 13173 13174 convert_11be_phybitmap_to_reg_flags(target_phybitmap, &phybitmap); 13175 13176 return phybitmap; 13177 } 13178 13179 /** 13180 * convert_11be_flags_to_modes_ext() - Convert 11BE wireless mode flag 13181 * advertised by the target to wireless mode ext flags. 13182 * @target_wireless_modes_ext: Target wireless mode 13183 * @wireless_modes_ext: Variable to hold all the target wireless mode caps. 13184 * 13185 * Return: None 13186 */ 13187 #ifdef WLAN_FEATURE_11BE 13188 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 13189 uint64_t *wireless_modes_ext) 13190 { 13191 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT20) 13192 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT20; 13193 13194 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40PLUS) 13195 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40PLUS; 13196 13197 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEG_EHT40MINUS) 13198 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEG_EHT40MINUS; 13199 13200 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT20) 13201 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT20; 13202 13203 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40PLUS) 13204 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40PLUS; 13205 13206 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT40MINUS) 13207 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT40MINUS; 13208 13209 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT80) 13210 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT80; 13211 13212 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT160) 13213 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT160; 13214 13215 if (target_wireless_modes_ext & REGDMN_MODE_U32_11BEA_EHT320) 13216 *wireless_modes_ext |= HOST_REGDMN_MODE_11BEA_EHT320; 13217 } 13218 #else 13219 static void convert_11be_flags_to_modes_ext(uint32_t target_wireless_modes_ext, 13220 uint64_t *wireless_modes_ext) 13221 { 13222 } 13223 #endif 13224 13225 static inline uint64_t convert_wireless_modes_ext_tlv( 13226 uint32_t target_wireless_modes_ext) 13227 { 13228 uint64_t wireless_modes_ext = 0; 13229 13230 wmi_debug("Target wireless mode: 0x%x", target_wireless_modes_ext); 13231 13232 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE20) 13233 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE20; 13234 13235 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40PLUS) 13236 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40PLUS; 13237 13238 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXG_HE40MINUS) 13239 wireless_modes_ext |= HOST_REGDMN_MODE_11AXG_HE40MINUS; 13240 13241 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE20) 13242 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE20; 13243 13244 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40PLUS) 13245 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40PLUS; 13246 13247 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE40MINUS) 13248 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE40MINUS; 13249 13250 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80) 13251 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80; 13252 13253 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE160) 13254 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE160; 13255 13256 if (target_wireless_modes_ext & REGDMN_MODE_U32_11AXA_HE80_80) 13257 wireless_modes_ext |= HOST_REGDMN_MODE_11AXA_HE80_80; 13258 13259 convert_11be_flags_to_modes_ext(target_wireless_modes_ext, 13260 &wireless_modes_ext); 13261 13262 return wireless_modes_ext; 13263 } 13264 13265 /** 13266 * extract_hal_reg_cap_tlv() - extract HAL registered capabilities 13267 * @wmi_handle: wmi handle 13268 * @evt_buf: Pointer to event buffer 13269 * @cap: pointer to hold HAL reg capabilities 13270 * 13271 * Return: QDF_STATUS_SUCCESS for success or error code 13272 */ 13273 static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, 13274 void *evt_buf, struct wlan_psoc_hal_reg_capability *cap) 13275 { 13276 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13277 13278 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13279 if (!param_buf || !param_buf->hal_reg_capabilities) { 13280 wmi_err("Invalid arguments"); 13281 return QDF_STATUS_E_FAILURE; 13282 } 13283 qdf_mem_copy(cap, (((uint8_t *)param_buf->hal_reg_capabilities) + 13284 sizeof(uint32_t)), 13285 sizeof(struct wlan_psoc_hal_reg_capability)); 13286 13287 cap->wireless_modes = convert_wireless_modes_tlv( 13288 param_buf->hal_reg_capabilities->wireless_modes); 13289 13290 return QDF_STATUS_SUCCESS; 13291 } 13292 13293 /** 13294 * extract_hal_reg_cap_ext2_tlv() - extract HAL registered capability ext 13295 * @wmi_handle: wmi handle 13296 * @evt_buf: Pointer to event buffer 13297 * @phy_idx: Specific phy to extract 13298 * @param: pointer to hold HAL reg capabilities 13299 * 13300 * Return: QDF_STATUS_SUCCESS for success or error code 13301 */ 13302 static QDF_STATUS extract_hal_reg_cap_ext2_tlv( 13303 wmi_unified_t wmi_handle, void *evt_buf, uint8_t phy_idx, 13304 struct wlan_psoc_host_hal_reg_capabilities_ext2 *param) 13305 { 13306 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 13307 WMI_HAL_REG_CAPABILITIES_EXT2 *reg_caps; 13308 13309 if (!evt_buf) { 13310 wmi_err("null evt_buf"); 13311 return QDF_STATUS_E_INVAL; 13312 } 13313 13314 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)evt_buf; 13315 13316 if (!param_buf->num_hal_reg_caps) 13317 return QDF_STATUS_SUCCESS; 13318 13319 if (phy_idx >= param_buf->num_hal_reg_caps) 13320 return QDF_STATUS_E_INVAL; 13321 13322 reg_caps = ¶m_buf->hal_reg_caps[phy_idx]; 13323 13324 param->phy_id = reg_caps->phy_id; 13325 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 13326 reg_caps->wireless_modes_ext); 13327 param->low_2ghz_chan_ext = reg_caps->low_2ghz_chan_ext; 13328 param->high_2ghz_chan_ext = reg_caps->high_2ghz_chan_ext; 13329 param->low_5ghz_chan_ext = reg_caps->low_5ghz_chan_ext; 13330 param->high_5ghz_chan_ext = reg_caps->high_5ghz_chan_ext; 13331 13332 return QDF_STATUS_SUCCESS; 13333 } 13334 13335 /** 13336 * extract_num_mem_reqs_tlv() - Extract number of memory entries requested 13337 * @wmi_handle: wmi handle 13338 * @evt_buf: pointer to event buffer 13339 * 13340 * Return: Number of entries requested 13341 */ 13342 static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, 13343 void *evt_buf) 13344 { 13345 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13346 wmi_service_ready_event_fixed_param *ev; 13347 13348 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13349 13350 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13351 if (!ev) { 13352 qdf_print("%s: wmi_buf_alloc failed", __func__); 13353 return 0; 13354 } 13355 13356 if (ev->num_mem_reqs > param_buf->num_mem_reqs) { 13357 wmi_err("Invalid num_mem_reqs %d:%d", 13358 ev->num_mem_reqs, param_buf->num_mem_reqs); 13359 return 0; 13360 } 13361 13362 return ev->num_mem_reqs; 13363 } 13364 13365 /** 13366 * extract_host_mem_req_tlv() - Extract host memory required from 13367 * service ready event 13368 * @wmi_handle: wmi handle 13369 * @evt_buf: pointer to event buffer 13370 * @mem_reqs: pointer to host memory request structure 13371 * @num_active_peers: number of active peers for peer cache 13372 * @num_peers: number of peers 13373 * @fw_prio: FW priority 13374 * @idx: index for memory request 13375 * 13376 * Return: Host memory request parameters requested by target 13377 */ 13378 static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, 13379 void *evt_buf, 13380 host_mem_req *mem_reqs, 13381 uint32_t num_active_peers, 13382 uint32_t num_peers, 13383 enum wmi_fw_mem_prio fw_prio, 13384 uint16_t idx) 13385 { 13386 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13387 13388 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; 13389 13390 mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; 13391 mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; 13392 mem_reqs->num_unit_info = 13393 (uint32_t)param_buf->mem_reqs[idx].num_unit_info; 13394 mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; 13395 mem_reqs->tgt_num_units = 0; 13396 13397 if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && 13398 (mem_reqs->num_unit_info & 13399 REQ_TO_HOST_FOR_CONT_MEMORY)) || 13400 ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && 13401 (!(mem_reqs->num_unit_info & 13402 REQ_TO_HOST_FOR_CONT_MEMORY)))) { 13403 /* First allocate the memory that requires contiguous memory */ 13404 mem_reqs->tgt_num_units = mem_reqs->num_units; 13405 if (mem_reqs->num_unit_info) { 13406 if (mem_reqs->num_unit_info & 13407 NUM_UNITS_IS_NUM_PEERS) { 13408 /* 13409 * number of units allocated is equal to number 13410 * of peers, 1 extra for self peer on target. 13411 * this needs to be fixed, host and target can 13412 * get out of sync 13413 */ 13414 mem_reqs->tgt_num_units = num_peers + 1; 13415 } 13416 if (mem_reqs->num_unit_info & 13417 NUM_UNITS_IS_NUM_ACTIVE_PEERS) { 13418 /* 13419 * Requesting allocation of memory using 13420 * num_active_peers in qcache. if qcache is 13421 * disabled in host, then it should allocate 13422 * memory for num_peers instead of 13423 * num_active_peers. 13424 */ 13425 if (num_active_peers) 13426 mem_reqs->tgt_num_units = 13427 num_active_peers + 1; 13428 else 13429 mem_reqs->tgt_num_units = 13430 num_peers + 1; 13431 } 13432 } 13433 13434 wmi_debug("idx %d req %d num_units %d num_unit_info %d" 13435 "unit size %d actual units %d", 13436 idx, mem_reqs->req_id, 13437 mem_reqs->num_units, 13438 mem_reqs->num_unit_info, 13439 mem_reqs->unit_size, 13440 mem_reqs->tgt_num_units); 13441 } 13442 13443 return QDF_STATUS_SUCCESS; 13444 } 13445 13446 /** 13447 * save_fw_version_in_service_ready_tlv() - Save fw version in service 13448 * ready function 13449 * @wmi_handle: wmi handle 13450 * @evt_buf: pointer to event buffer 13451 * 13452 * Return: QDF_STATUS_SUCCESS for success or error code 13453 */ 13454 static QDF_STATUS 13455 save_fw_version_in_service_ready_tlv(wmi_unified_t wmi_handle, void *evt_buf) 13456 { 13457 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; 13458 wmi_service_ready_event_fixed_param *ev; 13459 13460 13461 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf; 13462 13463 ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; 13464 if (!ev) { 13465 qdf_print("%s: wmi_buf_alloc failed", __func__); 13466 return QDF_STATUS_E_FAILURE; 13467 } 13468 13469 /*Save fw version from service ready message */ 13470 /*This will be used while sending INIT message */ 13471 qdf_mem_copy(&wmi_handle->fw_abi_version, &ev->fw_abi_vers, 13472 sizeof(wmi_handle->fw_abi_version)); 13473 13474 return QDF_STATUS_SUCCESS; 13475 } 13476 13477 /** 13478 * ready_extract_init_status_tlv() - Extract init status from ready event 13479 * @wmi_handle: wmi handle 13480 * @evt_buf: Pointer to event buffer 13481 * 13482 * Return: ready status 13483 */ 13484 static uint32_t ready_extract_init_status_tlv(wmi_unified_t wmi_handle, 13485 void *evt_buf) 13486 { 13487 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13488 wmi_ready_event_fixed_param *ev = NULL; 13489 13490 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13491 ev = param_buf->fixed_param; 13492 13493 wmi_info("%s:%d", __func__, ev->status); 13494 13495 return ev->status; 13496 } 13497 13498 /** 13499 * ready_extract_mac_addr_tlv() - extract mac address from ready event 13500 * @wmi_handle: wmi handle 13501 * @evt_buf: pointer to event buffer 13502 * @macaddr: Pointer to hold MAC address 13503 * 13504 * Return: QDF_STATUS_SUCCESS for success or error code 13505 */ 13506 static QDF_STATUS ready_extract_mac_addr_tlv(wmi_unified_t wmi_handle, 13507 void *evt_buf, uint8_t *macaddr) 13508 { 13509 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13510 wmi_ready_event_fixed_param *ev = NULL; 13511 13512 13513 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13514 ev = param_buf->fixed_param; 13515 13516 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, macaddr); 13517 13518 return QDF_STATUS_SUCCESS; 13519 } 13520 13521 /** 13522 * ready_extract_mac_addr_list_tlv() - extract MAC address list from ready event 13523 * @wmi_handle: wmi handle 13524 * @evt_buf: pointer to event buffer 13525 * @num_mac: Pointer to hold number of MAC addresses 13526 * 13527 * Return: Pointer to addr list 13528 */ 13529 static wmi_host_mac_addr * 13530 ready_extract_mac_addr_list_tlv(wmi_unified_t wmi_handle, 13531 void *evt_buf, uint8_t *num_mac) 13532 { 13533 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13534 wmi_ready_event_fixed_param *ev = NULL; 13535 13536 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13537 ev = param_buf->fixed_param; 13538 13539 *num_mac = ev->num_extra_mac_addr; 13540 13541 return (wmi_host_mac_addr *) param_buf->mac_addr_list; 13542 } 13543 13544 /** 13545 * extract_ready_event_params_tlv() - Extract data from ready event apart from 13546 * status, macaddr and version. 13547 * @wmi_handle: Pointer to WMI handle. 13548 * @evt_buf: Pointer to Ready event buffer. 13549 * @ev_param: Pointer to host defined struct to copy the data from event. 13550 * 13551 * Return: QDF_STATUS_SUCCESS on success. 13552 */ 13553 static QDF_STATUS extract_ready_event_params_tlv(wmi_unified_t wmi_handle, 13554 void *evt_buf, struct wmi_host_ready_ev_param *ev_param) 13555 { 13556 WMI_READY_EVENTID_param_tlvs *param_buf = NULL; 13557 wmi_ready_event_fixed_param *ev = NULL; 13558 13559 param_buf = (WMI_READY_EVENTID_param_tlvs *) evt_buf; 13560 ev = param_buf->fixed_param; 13561 13562 ev_param->status = ev->status; 13563 ev_param->num_dscp_table = ev->num_dscp_table; 13564 ev_param->num_extra_mac_addr = ev->num_extra_mac_addr; 13565 ev_param->num_total_peer = ev->num_total_peers; 13566 ev_param->num_extra_peer = ev->num_extra_peers; 13567 /* Agile_capability in ready event is supported in TLV target, 13568 * as per aDFS FR 13569 */ 13570 ev_param->max_ast_index = ev->max_ast_index; 13571 ev_param->pktlog_defs_checksum = ev->pktlog_defs_checksum; 13572 ev_param->agile_capability = 1; 13573 ev_param->num_max_active_vdevs = ev->num_max_active_vdevs; 13574 13575 return QDF_STATUS_SUCCESS; 13576 } 13577 13578 /** 13579 * extract_dbglog_data_len_tlv() - extract debuglog data length 13580 * @wmi_handle: wmi handle 13581 * @evt_buf: pointer to event buffer 13582 * @len: length of the log 13583 * 13584 * Return: pointer to the debug log 13585 */ 13586 static uint8_t *extract_dbglog_data_len_tlv(wmi_unified_t wmi_handle, 13587 void *evt_buf, uint32_t *len) 13588 { 13589 WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; 13590 13591 param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) evt_buf; 13592 13593 *len = param_buf->num_bufp; 13594 13595 return param_buf->bufp; 13596 } 13597 13598 13599 #ifdef MGMT_FRAME_RX_DECRYPT_ERROR 13600 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) false 13601 #else 13602 #define IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(_status) \ 13603 ((_status) & WMI_RXERR_DECRYPT) 13604 #endif 13605 13606 /** 13607 * extract_mgmt_rx_params_tlv() - extract management rx params from event 13608 * @wmi_handle: wmi handle 13609 * @evt_buf: pointer to event buffer 13610 * @hdr: Pointer to hold header 13611 * @bufp: Pointer to hold pointer to rx param buffer 13612 * 13613 * Return: QDF_STATUS_SUCCESS for success or error code 13614 */ 13615 static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, 13616 void *evt_buf, struct mgmt_rx_event_params *hdr, 13617 uint8_t **bufp) 13618 { 13619 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; 13620 wmi_mgmt_rx_hdr *ev_hdr = NULL; 13621 int i; 13622 13623 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13624 if (!param_tlvs) { 13625 wmi_err_rl("Get NULL point message from FW"); 13626 return QDF_STATUS_E_INVAL; 13627 } 13628 13629 ev_hdr = param_tlvs->hdr; 13630 if (!hdr) { 13631 wmi_err_rl("Rx event is NULL"); 13632 return QDF_STATUS_E_INVAL; 13633 } 13634 13635 if (IS_WMI_RX_MGMT_FRAME_STATUS_INVALID(ev_hdr->status)) { 13636 wmi_err_rl("RX mgmt frame decrypt error, discard it"); 13637 return QDF_STATUS_E_INVAL; 13638 } 13639 if ((ev_hdr->status) & WMI_RXERR_MIC) { 13640 wmi_err_rl("RX mgmt frame MIC mismatch for beacon protected frame"); 13641 } 13642 13643 if (ev_hdr->buf_len > param_tlvs->num_bufp) { 13644 wmi_err_rl("Rx mgmt frame length mismatch, discard it"); 13645 return QDF_STATUS_E_INVAL; 13646 } 13647 13648 hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13649 wmi_handle, 13650 ev_hdr->pdev_id); 13651 hdr->chan_freq = ev_hdr->chan_freq; 13652 hdr->channel = ev_hdr->channel; 13653 hdr->snr = ev_hdr->snr; 13654 hdr->rate = ev_hdr->rate; 13655 hdr->phy_mode = ev_hdr->phy_mode; 13656 hdr->buf_len = ev_hdr->buf_len; 13657 hdr->status = ev_hdr->status; 13658 hdr->flags = ev_hdr->flags; 13659 hdr->rssi = ev_hdr->rssi; 13660 hdr->tsf_delta = ev_hdr->tsf_delta; 13661 hdr->tsf_l32 = ev_hdr->rx_tsf_l32; 13662 for (i = 0; i < ATH_MAX_ANTENNA; i++) 13663 hdr->rssi_ctl[i] = ev_hdr->rssi_ctl[i]; 13664 13665 *bufp = param_tlvs->bufp; 13666 13667 extract_mgmt_rx_mlo_link_removal_tlv_count( 13668 param_tlvs->num_link_removal_tbtt_count, hdr); 13669 13670 return QDF_STATUS_SUCCESS; 13671 } 13672 13673 static QDF_STATUS extract_mgmt_rx_ext_params_tlv(wmi_unified_t wmi_handle, 13674 void *evt_buf, struct mgmt_rx_event_ext_params *ext_params) 13675 { 13676 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13677 wmi_mgmt_rx_params_ext *ext_params_tlv; 13678 wmi_mgmt_rx_hdr *ev_hdr; 13679 wmi_mgmt_rx_params_ext_meta_t meta_id; 13680 uint8_t *ie_data; 13681 13682 /* initialize to zero and set it only if tlv has valid meta data */ 13683 ext_params->u.addba.ba_win_size = 0; 13684 ext_params->u.addba.reo_win_size = 0; 13685 13686 param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) evt_buf; 13687 if (!param_tlvs) { 13688 wmi_err("param_tlvs is NULL"); 13689 return QDF_STATUS_E_INVAL; 13690 } 13691 13692 ev_hdr = param_tlvs->hdr; 13693 if (!ev_hdr) { 13694 wmi_err("Rx event is NULL"); 13695 return QDF_STATUS_E_INVAL; 13696 } 13697 13698 ext_params_tlv = param_tlvs->mgmt_rx_params_ext; 13699 if (ext_params_tlv) { 13700 meta_id = WMI_RX_PARAM_EXT_META_ID_GET( 13701 ext_params_tlv->mgmt_rx_params_ext_dword0); 13702 if (meta_id == WMI_RX_PARAMS_EXT_META_ADDBA) { 13703 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_ADDBA; 13704 ext_params->u.addba.ba_win_size = 13705 WMI_RX_PARAM_EXT_BA_WIN_SIZE_GET( 13706 ext_params_tlv->mgmt_rx_params_ext_dword1); 13707 if (ext_params->u.addba.ba_win_size > 1024) { 13708 wmi_info("ba win size %d from TLV is Invalid", 13709 ext_params->u.addba.ba_win_size); 13710 return QDF_STATUS_E_INVAL; 13711 } 13712 13713 ext_params->u.addba.reo_win_size = 13714 WMI_RX_PARAM_EXT_REO_WIN_SIZE_GET( 13715 ext_params_tlv->mgmt_rx_params_ext_dword1); 13716 if (ext_params->u.addba.reo_win_size > 2048) { 13717 wmi_info("reo win size %d from TLV is Invalid", 13718 ext_params->u.addba.reo_win_size); 13719 return QDF_STATUS_E_INVAL; 13720 } 13721 } 13722 if (meta_id == WMI_RX_PARAMS_EXT_META_TWT) { 13723 ext_params->meta_id = MGMT_RX_PARAMS_EXT_META_TWT; 13724 ext_params->u.twt.ie_len = 13725 ext_params_tlv->twt_ie_buf_len; 13726 ie_data = param_tlvs->ie_data; 13727 if (ext_params->u.twt.ie_len && 13728 (ext_params->u.twt.ie_len < 13729 MAX_TWT_IE_RX_PARAMS_LEN)) { 13730 qdf_mem_copy(ext_params->u.twt.ie_data, 13731 ie_data, 13732 ext_params_tlv->twt_ie_buf_len); 13733 } 13734 } 13735 } 13736 13737 return QDF_STATUS_SUCCESS; 13738 } 13739 13740 #ifdef WLAN_MGMT_RX_REO_SUPPORT 13741 /** 13742 * extract_mgmt_rx_fw_consumed_tlv() - extract MGMT Rx FW consumed event 13743 * @wmi_handle: wmi handle 13744 * @evt_buf: pointer to event buffer 13745 * @params: Pointer to MGMT Rx REO parameters 13746 * 13747 * Return: QDF_STATUS_SUCCESS for success or error code 13748 */ 13749 static QDF_STATUS 13750 extract_mgmt_rx_fw_consumed_tlv(wmi_unified_t wmi_handle, 13751 void *evt_buf, 13752 struct mgmt_rx_reo_params *params) 13753 { 13754 WMI_MGMT_RX_FW_CONSUMED_EVENTID_param_tlvs *param_tlvs; 13755 wmi_mgmt_rx_fw_consumed_hdr *ev_hdr; 13756 13757 param_tlvs = evt_buf; 13758 if (!param_tlvs) { 13759 wmi_err("param_tlvs is NULL"); 13760 return QDF_STATUS_E_INVAL; 13761 } 13762 13763 ev_hdr = param_tlvs->hdr; 13764 if (!params) { 13765 wmi_err("Rx REO parameters is NULL"); 13766 return QDF_STATUS_E_INVAL; 13767 } 13768 13769 params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13770 wmi_handle, 13771 ev_hdr->pdev_id); 13772 params->valid = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_VALID_GET( 13773 ev_hdr->mgmt_pkt_ctr_info); 13774 params->global_timestamp = ev_hdr->global_timestamp; 13775 params->mgmt_pkt_ctr = WMI_MGMT_RX_FW_CONSUMED_PARAM_MGMT_PKT_CTR_GET( 13776 ev_hdr->mgmt_pkt_ctr_info); 13777 params->duration_us = ev_hdr->rx_ppdu_duration_us; 13778 params->start_timestamp = params->global_timestamp; 13779 params->end_timestamp = params->start_timestamp + 13780 params->duration_us; 13781 13782 return QDF_STATUS_SUCCESS; 13783 } 13784 13785 /** 13786 * extract_mgmt_rx_reo_params_tlv() - extract MGMT Rx REO params from 13787 * MGMT_RX_EVENT_ID 13788 * @wmi_handle: wmi handle 13789 * @evt_buf: pointer to event buffer 13790 * @reo_params: Pointer to MGMT Rx REO parameters 13791 * 13792 * Return: QDF_STATUS_SUCCESS for success or error code 13793 */ 13794 static QDF_STATUS extract_mgmt_rx_reo_params_tlv(wmi_unified_t wmi_handle, 13795 void *evt_buf, struct mgmt_rx_reo_params *reo_params) 13796 { 13797 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13798 wmi_mgmt_rx_reo_params *reo_params_tlv; 13799 wmi_mgmt_rx_hdr *ev_hdr; 13800 13801 param_tlvs = evt_buf; 13802 if (!param_tlvs) { 13803 wmi_err("param_tlvs is NULL"); 13804 return QDF_STATUS_E_INVAL; 13805 } 13806 13807 ev_hdr = param_tlvs->hdr; 13808 if (!ev_hdr) { 13809 wmi_err("Rx event is NULL"); 13810 return QDF_STATUS_E_INVAL; 13811 } 13812 13813 reo_params_tlv = param_tlvs->reo_params; 13814 if (!reo_params_tlv) { 13815 wmi_err("mgmt_rx_reo_params TLV is not sent by FW"); 13816 return QDF_STATUS_E_INVAL; 13817 } 13818 13819 if (!reo_params) { 13820 wmi_err("MGMT Rx REO params is NULL"); 13821 return QDF_STATUS_E_INVAL; 13822 } 13823 13824 reo_params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 13825 wmi_handle, 13826 ev_hdr->pdev_id); 13827 reo_params->valid = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_VALID_GET( 13828 reo_params_tlv->mgmt_pkt_ctr_link_info); 13829 reo_params->global_timestamp = reo_params_tlv->global_timestamp; 13830 reo_params->mgmt_pkt_ctr = WMI_MGMT_RX_REO_PARAM_MGMT_PKT_CTR_GET( 13831 reo_params_tlv->mgmt_pkt_ctr_link_info); 13832 reo_params->duration_us = reo_params_tlv->rx_ppdu_duration_us; 13833 reo_params->start_timestamp = reo_params->global_timestamp; 13834 reo_params->end_timestamp = reo_params->start_timestamp + 13835 reo_params->duration_us; 13836 13837 return QDF_STATUS_SUCCESS; 13838 } 13839 13840 /** 13841 * send_mgmt_rx_reo_filter_config_cmd_tlv() - Send MGMT Rx REO filter 13842 * configuration command 13843 * @wmi_handle: wmi handle 13844 * @pdev_id: pdev ID of the radio 13845 * @filter: Pointer to MGMT Rx REO filter 13846 * 13847 * Return: QDF_STATUS_SUCCESS for success or error code 13848 */ 13849 static QDF_STATUS send_mgmt_rx_reo_filter_config_cmd_tlv( 13850 wmi_unified_t wmi_handle, 13851 uint8_t pdev_id, 13852 struct mgmt_rx_reo_filter *filter) 13853 { 13854 QDF_STATUS ret; 13855 wmi_buf_t buf; 13856 wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *cmd; 13857 size_t len = sizeof(*cmd); 13858 13859 if (!filter) { 13860 wmi_err("mgmt_rx_reo_filter is NULL"); 13861 return QDF_STATUS_E_INVAL; 13862 } 13863 13864 buf = wmi_buf_alloc(wmi_handle, len); 13865 if (!buf) { 13866 wmi_err("wmi_buf_alloc failed"); 13867 return QDF_STATUS_E_NOMEM; 13868 } 13869 13870 cmd = (wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param *) 13871 wmi_buf_data(buf); 13872 13873 WMITLV_SET_HDR(&cmd->tlv_header, 13874 WMITLV_TAG_STRUC_wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param, 13875 WMITLV_GET_STRUCT_TLVLEN(wmi_mgmt_rx_reo_filter_configuration_cmd_fixed_param)); 13876 13877 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 13878 wmi_handle, 13879 pdev_id); 13880 cmd->filter_low = filter->low; 13881 cmd->filter_high = filter->high; 13882 13883 wmi_mtrace(WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID, NO_SESSION, 0); 13884 ret = wmi_unified_cmd_send( 13885 wmi_handle, buf, len, 13886 WMI_MGMT_RX_REO_FILTER_CONFIGURATION_CMDID); 13887 13888 if (QDF_IS_STATUS_ERROR(ret)) { 13889 wmi_err("Failed to send WMI command"); 13890 wmi_buf_free(buf); 13891 } 13892 13893 return ret; 13894 } 13895 #endif 13896 13897 /** 13898 * extract_frame_pn_params_tlv() - extract PN params from event 13899 * @wmi_handle: wmi handle 13900 * @evt_buf: pointer to event buffer 13901 * @pn_params: Pointer to Frame PN params 13902 * 13903 * Return: QDF_STATUS_SUCCESS for success or error code 13904 */ 13905 static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle, 13906 void *evt_buf, 13907 struct frame_pn_params *pn_params) 13908 { 13909 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13910 wmi_frame_pn_params *pn_params_tlv; 13911 13912 if (!is_service_enabled_tlv(wmi_handle, 13913 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) 13914 return QDF_STATUS_SUCCESS; 13915 13916 param_tlvs = evt_buf; 13917 if (!param_tlvs) { 13918 wmi_err("Got NULL point message from FW"); 13919 return QDF_STATUS_E_INVAL; 13920 } 13921 13922 if (!pn_params) { 13923 wmi_err("PN Params is NULL"); 13924 return QDF_STATUS_E_INVAL; 13925 } 13926 13927 /* PN Params TLV will be populated only if WMI_RXERR_PN error is 13928 * found by target 13929 */ 13930 pn_params_tlv = param_tlvs->pn_params; 13931 if (!pn_params_tlv) 13932 return QDF_STATUS_SUCCESS; 13933 13934 qdf_mem_copy(pn_params->curr_pn, pn_params_tlv->cur_pn, 13935 sizeof(pn_params->curr_pn)); 13936 qdf_mem_copy(pn_params->prev_pn, pn_params_tlv->prev_pn, 13937 sizeof(pn_params->prev_pn)); 13938 13939 return QDF_STATUS_SUCCESS; 13940 } 13941 13942 /** 13943 * extract_is_conn_ap_frm_param_tlv() - extract is_conn_ap_frame param from 13944 * event 13945 * @wmi_handle: wmi handle 13946 * @evt_buf: pointer to event buffer 13947 * @is_conn_ap: Pointer for is_conn_ap frame 13948 * 13949 * Return: QDF_STATUS_SUCCESS for success or error code 13950 */ 13951 static QDF_STATUS extract_is_conn_ap_frm_param_tlv( 13952 wmi_unified_t wmi_handle, 13953 void *evt_buf, 13954 struct frm_conn_ap *is_conn_ap) 13955 { 13956 WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; 13957 wmi_is_my_mgmt_frame *my_frame_tlv; 13958 13959 param_tlvs = evt_buf; 13960 if (!param_tlvs) { 13961 wmi_err("Got NULL point message from FW"); 13962 return QDF_STATUS_E_INVAL; 13963 } 13964 13965 if (!is_conn_ap) { 13966 wmi_err(" is connected ap param is NULL"); 13967 return QDF_STATUS_E_INVAL; 13968 } 13969 13970 my_frame_tlv = param_tlvs->my_frame; 13971 if (!my_frame_tlv) 13972 return QDF_STATUS_SUCCESS; 13973 13974 is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type; 13975 is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame; 13976 13977 return QDF_STATUS_SUCCESS; 13978 } 13979 13980 /** 13981 * extract_vdev_roam_param_tlv() - extract vdev roam param from event 13982 * @wmi_handle: wmi handle 13983 * @evt_buf: pointer to event buffer 13984 * @param: Pointer to hold roam param 13985 * 13986 * Return: QDF_STATUS_SUCCESS for success or error code 13987 */ 13988 static QDF_STATUS extract_vdev_roam_param_tlv(wmi_unified_t wmi_handle, 13989 void *evt_buf, wmi_host_roam_event *param) 13990 { 13991 WMI_ROAM_EVENTID_param_tlvs *param_buf; 13992 wmi_roam_event_fixed_param *evt; 13993 13994 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) evt_buf; 13995 if (!param_buf) { 13996 wmi_err("Invalid roam event buffer"); 13997 return QDF_STATUS_E_INVAL; 13998 } 13999 14000 evt = param_buf->fixed_param; 14001 qdf_mem_zero(param, sizeof(*param)); 14002 14003 param->vdev_id = evt->vdev_id; 14004 param->reason = evt->reason; 14005 param->rssi = evt->rssi; 14006 14007 return QDF_STATUS_SUCCESS; 14008 } 14009 14010 /** 14011 * extract_vdev_scan_ev_param_tlv() - extract vdev scan param from event 14012 * @wmi_handle: wmi handle 14013 * @evt_buf: pointer to event buffer 14014 * @param: Pointer to hold vdev scan param 14015 * 14016 * Return: QDF_STATUS_SUCCESS for success or error code 14017 */ 14018 static QDF_STATUS extract_vdev_scan_ev_param_tlv(wmi_unified_t wmi_handle, 14019 void *evt_buf, struct scan_event *param) 14020 { 14021 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; 14022 wmi_scan_event_fixed_param *evt = NULL; 14023 14024 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) evt_buf; 14025 evt = param_buf->fixed_param; 14026 14027 qdf_mem_zero(param, sizeof(*param)); 14028 14029 switch (evt->event) { 14030 case WMI_SCAN_EVENT_STARTED: 14031 param->type = SCAN_EVENT_TYPE_STARTED; 14032 break; 14033 case WMI_SCAN_EVENT_COMPLETED: 14034 param->type = SCAN_EVENT_TYPE_COMPLETED; 14035 break; 14036 case WMI_SCAN_EVENT_BSS_CHANNEL: 14037 param->type = SCAN_EVENT_TYPE_BSS_CHANNEL; 14038 break; 14039 case WMI_SCAN_EVENT_FOREIGN_CHANNEL: 14040 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL; 14041 break; 14042 case WMI_SCAN_EVENT_DEQUEUED: 14043 param->type = SCAN_EVENT_TYPE_DEQUEUED; 14044 break; 14045 case WMI_SCAN_EVENT_PREEMPTED: 14046 param->type = SCAN_EVENT_TYPE_PREEMPTED; 14047 break; 14048 case WMI_SCAN_EVENT_START_FAILED: 14049 param->type = SCAN_EVENT_TYPE_START_FAILED; 14050 break; 14051 case WMI_SCAN_EVENT_RESTARTED: 14052 param->type = SCAN_EVENT_TYPE_RESTARTED; 14053 break; 14054 case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT: 14055 param->type = SCAN_EVENT_TYPE_FOREIGN_CHANNEL_EXIT; 14056 break; 14057 case WMI_SCAN_EVENT_MAX: 14058 default: 14059 param->type = SCAN_EVENT_TYPE_MAX; 14060 break; 14061 }; 14062 14063 switch (evt->reason) { 14064 case WMI_SCAN_REASON_NONE: 14065 param->reason = SCAN_REASON_NONE; 14066 break; 14067 case WMI_SCAN_REASON_COMPLETED: 14068 param->reason = SCAN_REASON_COMPLETED; 14069 break; 14070 case WMI_SCAN_REASON_CANCELLED: 14071 param->reason = SCAN_REASON_CANCELLED; 14072 break; 14073 case WMI_SCAN_REASON_PREEMPTED: 14074 param->reason = SCAN_REASON_PREEMPTED; 14075 break; 14076 case WMI_SCAN_REASON_TIMEDOUT: 14077 param->reason = SCAN_REASON_TIMEDOUT; 14078 break; 14079 case WMI_SCAN_REASON_INTERNAL_FAILURE: 14080 param->reason = SCAN_REASON_INTERNAL_FAILURE; 14081 break; 14082 case WMI_SCAN_REASON_SUSPENDED: 14083 param->reason = SCAN_REASON_SUSPENDED; 14084 break; 14085 case WMI_SCAN_REASON_DFS_VIOLATION: 14086 param->reason = SCAN_REASON_DFS_VIOLATION; 14087 break; 14088 case WMI_SCAN_REASON_MAX: 14089 param->reason = SCAN_REASON_MAX; 14090 break; 14091 default: 14092 param->reason = SCAN_REASON_MAX; 14093 break; 14094 }; 14095 14096 param->chan_freq = evt->channel_freq; 14097 param->requester = evt->requestor; 14098 param->scan_id = evt->scan_id; 14099 param->vdev_id = evt->vdev_id; 14100 param->timestamp = evt->tsf_timestamp; 14101 14102 return QDF_STATUS_SUCCESS; 14103 } 14104 14105 #ifdef FEATURE_WLAN_SCAN_PNO 14106 /** 14107 * extract_nlo_match_ev_param_tlv() - extract NLO match param from event 14108 * @wmi_handle: pointer to WMI handle 14109 * @evt_buf: pointer to WMI event buffer 14110 * @param: pointer to scan event param for NLO match 14111 * 14112 * Return: QDF_STATUS_SUCCESS for success or error code 14113 */ 14114 static QDF_STATUS extract_nlo_match_ev_param_tlv(wmi_unified_t wmi_handle, 14115 void *evt_buf, 14116 struct scan_event *param) 14117 { 14118 WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = evt_buf; 14119 wmi_nlo_event *evt = param_buf->fixed_param; 14120 14121 qdf_mem_zero(param, sizeof(*param)); 14122 14123 param->type = SCAN_EVENT_TYPE_NLO_MATCH; 14124 param->vdev_id = evt->vdev_id; 14125 14126 return QDF_STATUS_SUCCESS; 14127 } 14128 14129 /** 14130 * extract_nlo_complete_ev_param_tlv() - extract NLO complete param from event 14131 * @wmi_handle: pointer to WMI handle 14132 * @evt_buf: pointer to WMI event buffer 14133 * @param: pointer to scan event param for NLO complete 14134 * 14135 * Return: QDF_STATUS_SUCCESS for success or error code 14136 */ 14137 static QDF_STATUS extract_nlo_complete_ev_param_tlv(wmi_unified_t wmi_handle, 14138 void *evt_buf, 14139 struct scan_event *param) 14140 { 14141 WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = evt_buf; 14142 wmi_nlo_event *evt = param_buf->fixed_param; 14143 14144 qdf_mem_zero(param, sizeof(*param)); 14145 14146 param->type = SCAN_EVENT_TYPE_NLO_COMPLETE; 14147 param->vdev_id = evt->vdev_id; 14148 14149 return QDF_STATUS_SUCCESS; 14150 } 14151 #endif 14152 14153 /** 14154 * extract_unit_test_tlv() - extract unit test data 14155 * @wmi_handle: wmi handle 14156 * @evt_buf: pointer to event buffer 14157 * @unit_test: pointer to hold unit test data 14158 * @maxspace: Amount of space in evt_buf 14159 * 14160 * Return: QDF_STATUS_SUCCESS for success or error code 14161 */ 14162 static QDF_STATUS extract_unit_test_tlv(wmi_unified_t wmi_handle, 14163 void *evt_buf, wmi_unit_test_event *unit_test, uint32_t maxspace) 14164 { 14165 WMI_UNIT_TEST_EVENTID_param_tlvs *param_buf; 14166 wmi_unit_test_event_fixed_param *ev_param; 14167 uint32_t num_bufp; 14168 uint32_t copy_size; 14169 uint8_t *bufp; 14170 14171 param_buf = (WMI_UNIT_TEST_EVENTID_param_tlvs *) evt_buf; 14172 ev_param = param_buf->fixed_param; 14173 bufp = param_buf->bufp; 14174 num_bufp = param_buf->num_bufp; 14175 unit_test->vdev_id = ev_param->vdev_id; 14176 unit_test->module_id = ev_param->module_id; 14177 unit_test->diag_token = ev_param->diag_token; 14178 unit_test->flag = ev_param->flag; 14179 unit_test->payload_len = ev_param->payload_len; 14180 wmi_debug("vdev_id:%d mod_id:%d diag_token:%d flag:%d", 14181 ev_param->vdev_id, 14182 ev_param->module_id, 14183 ev_param->diag_token, 14184 ev_param->flag); 14185 wmi_debug("Unit-test data given below %d", num_bufp); 14186 qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, 14187 bufp, num_bufp); 14188 copy_size = (num_bufp < maxspace) ? num_bufp : maxspace; 14189 qdf_mem_copy(unit_test->buffer, bufp, copy_size); 14190 unit_test->buffer_len = copy_size; 14191 14192 return QDF_STATUS_SUCCESS; 14193 } 14194 14195 /** 14196 * extract_pdev_ext_stats_tlv() - extract extended pdev stats from event 14197 * @wmi_handle: wmi handle 14198 * @evt_buf: pointer to event buffer 14199 * @index: Index into extended pdev stats 14200 * @pdev_ext_stats: Pointer to hold extended pdev stats 14201 * 14202 * Return: QDF_STATUS_SUCCESS for success or error code 14203 */ 14204 static QDF_STATUS extract_pdev_ext_stats_tlv(wmi_unified_t wmi_handle, 14205 void *evt_buf, uint32_t index, wmi_host_pdev_ext_stats *pdev_ext_stats) 14206 { 14207 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14208 wmi_pdev_extd_stats *ev; 14209 14210 param_buf = evt_buf; 14211 if (!param_buf) 14212 return QDF_STATUS_E_FAILURE; 14213 14214 if (!param_buf->pdev_extd_stats) 14215 return QDF_STATUS_E_FAILURE; 14216 14217 ev = param_buf->pdev_extd_stats + index; 14218 14219 pdev_ext_stats->pdev_id = 14220 wmi_handle->ops->convert_target_pdev_id_to_host( 14221 wmi_handle, 14222 ev->pdev_id); 14223 pdev_ext_stats->my_rx_count = ev->my_rx_count; 14224 pdev_ext_stats->rx_matched_11ax_msdu_cnt = ev->rx_matched_11ax_msdu_cnt; 14225 pdev_ext_stats->rx_other_11ax_msdu_cnt = ev->rx_other_11ax_msdu_cnt; 14226 14227 return QDF_STATUS_SUCCESS; 14228 } 14229 14230 /** 14231 * extract_bcn_stats_tlv() - extract bcn stats from event 14232 * @wmi_handle: wmi handle 14233 * @evt_buf: pointer to event buffer 14234 * @index: Index into vdev stats 14235 * @bcn_stats: Pointer to hold bcn stats 14236 * 14237 * Return: QDF_STATUS_SUCCESS for success or error code 14238 */ 14239 static QDF_STATUS extract_bcn_stats_tlv(wmi_unified_t wmi_handle, 14240 void *evt_buf, uint32_t index, wmi_host_bcn_stats *bcn_stats) 14241 { 14242 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14243 wmi_stats_event_fixed_param *ev_param; 14244 uint8_t *data; 14245 14246 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14247 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14248 data = (uint8_t *) param_buf->data; 14249 14250 if (index < ev_param->num_bcn_stats) { 14251 wmi_bcn_stats *ev = (wmi_bcn_stats *) ((data) + 14252 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14253 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14254 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14255 ((ev_param->num_chan_stats) * sizeof(wmi_chan_stats)) + 14256 ((ev_param->num_mib_stats) * sizeof(wmi_mib_stats)) + 14257 (index * sizeof(wmi_bcn_stats))); 14258 14259 bcn_stats->vdev_id = ev->vdev_id; 14260 bcn_stats->tx_bcn_succ_cnt = ev->tx_bcn_succ_cnt; 14261 bcn_stats->tx_bcn_outage_cnt = ev->tx_bcn_outage_cnt; 14262 } 14263 14264 return QDF_STATUS_SUCCESS; 14265 } 14266 14267 #ifdef WLAN_FEATURE_11BE_MLO 14268 /** 14269 * wmi_is_mlo_vdev_active() - get if mlo vdev is active or not 14270 * @flag: vdev link status info 14271 * 14272 * Return: True if active, else False 14273 */ 14274 static bool wmi_is_mlo_vdev_active(uint32_t flag) 14275 { 14276 if ((flag & WMI_VDEV_STATS_FLAGS_LINK_ACTIVE_FLAG_IS_VALID_MASK) && 14277 (flag & WMI_VDEV_STATS_FLAGS_IS_LINK_ACTIVE_MASK)) 14278 return true; 14279 14280 return false; 14281 } 14282 14283 static QDF_STATUS 14284 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14285 wmi_vdev_extd_stats *ev, 14286 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14287 { 14288 if (!param_buf->num_vdev_extd_stats) { 14289 wmi_err("No vdev_extd_stats in the event buffer"); 14290 return QDF_STATUS_E_INVAL; 14291 } 14292 14293 vdev_stats->is_mlo_vdev_active = wmi_is_mlo_vdev_active(ev->flags); 14294 return QDF_STATUS_SUCCESS; 14295 } 14296 #else 14297 static QDF_STATUS 14298 extract_mlo_vdev_status_info(WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf, 14299 wmi_vdev_extd_stats *ev, 14300 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14301 { 14302 return QDF_STATUS_SUCCESS; 14303 } 14304 #endif 14305 14306 /** 14307 * extract_vdev_prb_fils_stats_tlv() - extract vdev probe and fils 14308 * stats from event 14309 * @wmi_handle: wmi handle 14310 * @evt_buf: pointer to event buffer 14311 * @index: Index into vdev stats 14312 * @vdev_stats: Pointer to hold vdev probe and fils stats 14313 * 14314 * Return: QDF_STATUS_SUCCESS for success or error code 14315 */ 14316 static QDF_STATUS 14317 extract_vdev_prb_fils_stats_tlv(wmi_unified_t wmi_handle, 14318 void *evt_buf, uint32_t index, 14319 struct wmi_host_vdev_prb_fils_stats *vdev_stats) 14320 { 14321 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14322 wmi_vdev_extd_stats *ev; 14323 QDF_STATUS status = QDF_STATUS_SUCCESS; 14324 14325 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 14326 14327 if (param_buf->vdev_extd_stats) { 14328 ev = (wmi_vdev_extd_stats *)(param_buf->vdev_extd_stats + 14329 index); 14330 vdev_stats->vdev_id = ev->vdev_id; 14331 vdev_stats->fd_succ_cnt = ev->fd_succ_cnt; 14332 vdev_stats->fd_fail_cnt = ev->fd_fail_cnt; 14333 vdev_stats->unsolicited_prb_succ_cnt = 14334 ev->unsolicited_prb_succ_cnt; 14335 vdev_stats->unsolicited_prb_fail_cnt = 14336 ev->unsolicited_prb_fail_cnt; 14337 status = extract_mlo_vdev_status_info(param_buf, ev, 14338 vdev_stats); 14339 vdev_stats->vdev_tx_power = ev->vdev_tx_power; 14340 wmi_debug("vdev: %d, fd_s: %d, fd_f: %d, prb_s: %d, prb_f: %d", 14341 ev->vdev_id, ev->fd_succ_cnt, ev->fd_fail_cnt, 14342 ev->unsolicited_prb_succ_cnt, 14343 ev->unsolicited_prb_fail_cnt); 14344 wmi_debug("vdev txpwr: %d", ev->vdev_tx_power); 14345 } 14346 14347 return status; 14348 } 14349 14350 /** 14351 * extract_bcnflt_stats_tlv() - extract bcn fault stats from event 14352 * @wmi_handle: wmi handle 14353 * @evt_buf: pointer to event buffer 14354 * @index: Index into bcn fault stats 14355 * @bcnflt_stats: Pointer to hold bcn fault stats 14356 * 14357 * Return: QDF_STATUS_SUCCESS for success or error code 14358 */ 14359 static QDF_STATUS extract_bcnflt_stats_tlv(wmi_unified_t wmi_handle, 14360 void *evt_buf, uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats) 14361 { 14362 return QDF_STATUS_SUCCESS; 14363 } 14364 14365 /** 14366 * extract_chan_stats_tlv() - extract chan stats from event 14367 * @wmi_handle: wmi handle 14368 * @evt_buf: pointer to event buffer 14369 * @index: Index into chan stats 14370 * @chan_stats: Pointer to hold chan stats 14371 * 14372 * Return: QDF_STATUS_SUCCESS for success or error code 14373 */ 14374 static QDF_STATUS extract_chan_stats_tlv(wmi_unified_t wmi_handle, 14375 void *evt_buf, uint32_t index, wmi_host_chan_stats *chan_stats) 14376 { 14377 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 14378 wmi_stats_event_fixed_param *ev_param; 14379 uint8_t *data; 14380 14381 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 14382 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 14383 data = (uint8_t *) param_buf->data; 14384 14385 if (index < ev_param->num_chan_stats) { 14386 wmi_chan_stats *ev = (wmi_chan_stats *) ((data) + 14387 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 14388 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 14389 ((ev_param->num_peer_stats) * sizeof(wmi_peer_stats)) + 14390 (index * sizeof(wmi_chan_stats))); 14391 14392 14393 /* Non-TLV doesn't have num_chan_stats */ 14394 chan_stats->chan_mhz = ev->chan_mhz; 14395 chan_stats->sampling_period_us = ev->sampling_period_us; 14396 chan_stats->rx_clear_count = ev->rx_clear_count; 14397 chan_stats->tx_duration_us = ev->tx_duration_us; 14398 chan_stats->rx_duration_us = ev->rx_duration_us; 14399 } 14400 14401 return QDF_STATUS_SUCCESS; 14402 } 14403 14404 /** 14405 * extract_profile_ctx_tlv() - extract profile context from event 14406 * @wmi_handle: wmi handle 14407 * @evt_buf: pointer to event buffer 14408 * @profile_ctx: Pointer to hold profile context 14409 * 14410 * Return: QDF_STATUS_SUCCESS for success or error code 14411 */ 14412 static QDF_STATUS extract_profile_ctx_tlv(wmi_unified_t wmi_handle, 14413 void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx) 14414 { 14415 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14416 14417 wmi_wlan_profile_ctx_t *ev; 14418 14419 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14420 if (!param_buf) { 14421 wmi_err("Invalid profile data event buf"); 14422 return QDF_STATUS_E_INVAL; 14423 } 14424 14425 ev = param_buf->profile_ctx; 14426 14427 profile_ctx->tot = ev->tot; 14428 profile_ctx->tx_msdu_cnt = ev->tx_msdu_cnt; 14429 profile_ctx->tx_mpdu_cnt = ev->tx_mpdu_cnt; 14430 profile_ctx->tx_ppdu_cnt = ev->tx_ppdu_cnt; 14431 profile_ctx->rx_msdu_cnt = ev->rx_msdu_cnt; 14432 profile_ctx->rx_mpdu_cnt = ev->rx_mpdu_cnt; 14433 profile_ctx->bin_count = ev->bin_count; 14434 14435 return QDF_STATUS_SUCCESS; 14436 } 14437 14438 /** 14439 * extract_profile_data_tlv() - extract profile data from event 14440 * @wmi_handle: wmi handle 14441 * @evt_buf: pointer to event buffer 14442 * @idx: profile stats index to extract 14443 * @profile_data: Pointer to hold profile data 14444 * 14445 * Return: QDF_STATUS_SUCCESS for success or error code 14446 */ 14447 static QDF_STATUS extract_profile_data_tlv(wmi_unified_t wmi_handle, 14448 void *evt_buf, uint8_t idx, wmi_host_wlan_profile_t *profile_data) 14449 { 14450 WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *param_buf; 14451 wmi_wlan_profile_t *ev; 14452 14453 param_buf = (WMI_WLAN_PROFILE_DATA_EVENTID_param_tlvs *)evt_buf; 14454 if (!param_buf) { 14455 wmi_err("Invalid profile data event buf"); 14456 return QDF_STATUS_E_INVAL; 14457 } 14458 14459 ev = ¶m_buf->profile_data[idx]; 14460 profile_data->id = ev->id; 14461 profile_data->cnt = ev->cnt; 14462 profile_data->tot = ev->tot; 14463 profile_data->min = ev->min; 14464 profile_data->max = ev->max; 14465 profile_data->hist_intvl = ev->hist_intvl; 14466 qdf_mem_copy(profile_data->hist, ev->hist, sizeof(profile_data->hist)); 14467 14468 return QDF_STATUS_SUCCESS; 14469 } 14470 14471 /** 14472 * extract_pdev_utf_event_tlv() - extract UTF data info from event 14473 * @wmi_handle: WMI handle 14474 * @evt_buf: Pointer to event buffer 14475 * @event: Pointer to hold data 14476 * 14477 * Return: QDF_STATUS_SUCCESS for success or error code 14478 */ 14479 static QDF_STATUS extract_pdev_utf_event_tlv(wmi_unified_t wmi_handle, 14480 uint8_t *evt_buf, 14481 struct wmi_host_pdev_utf_event *event) 14482 { 14483 WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; 14484 struct wmi_host_utf_seg_header_info *seg_hdr; 14485 wmi_pdev_utf_event_fixed_param *ev_param; 14486 bool is_pdev_id_over_utf; 14487 14488 param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *)evt_buf; 14489 event->data = param_buf->data; 14490 event->datalen = param_buf->num_data; 14491 14492 if (event->datalen < sizeof(struct wmi_host_utf_seg_header_info)) { 14493 wmi_err("Invalid datalen: %d", event->datalen); 14494 return QDF_STATUS_E_INVAL; 14495 } 14496 14497 is_pdev_id_over_utf = is_service_enabled_tlv(wmi_handle, 14498 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI); 14499 if (is_pdev_id_over_utf && param_buf->fixed_param && 14500 param_buf->num_fixed_param) { 14501 ev_param = 14502 (wmi_pdev_utf_event_fixed_param *)param_buf->fixed_param; 14503 event->pdev_id = 14504 wmi_handle->ops->convert_pdev_id_target_to_host( 14505 wmi_handle, 14506 ev_param->pdev_id); 14507 } else { 14508 seg_hdr = 14509 (struct wmi_host_utf_seg_header_info *)param_buf->data; 14510 event->pdev_id = 14511 wmi_handle->ops->convert_pdev_id_target_to_host( 14512 wmi_handle, 14513 seg_hdr->pdev_id); 14514 } 14515 14516 return QDF_STATUS_SUCCESS; 14517 } 14518 14519 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 14520 static QDF_STATUS extract_num_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14521 uint8_t *event, 14522 uint32_t *num_rf_characterization_entries) 14523 { 14524 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14525 14526 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14527 if (!param_buf) 14528 return QDF_STATUS_E_INVAL; 14529 14530 *num_rf_characterization_entries = 14531 param_buf->num_wmi_chan_rf_characterization_info; 14532 14533 return QDF_STATUS_SUCCESS; 14534 } 14535 14536 static QDF_STATUS extract_rf_characterization_entries_tlv(wmi_unified_t wmi_handle, 14537 uint8_t *event, 14538 uint32_t num_rf_characterization_entries, 14539 struct wmi_host_rf_characterization_event_param *rf_characterization_entries) 14540 { 14541 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *param_buf; 14542 WMI_CHAN_RF_CHARACTERIZATION_INFO *wmi_rf_characterization_entry; 14543 uint8_t ix; 14544 14545 param_buf = (WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID_param_tlvs *)event; 14546 if (!param_buf) 14547 return QDF_STATUS_E_INVAL; 14548 14549 wmi_rf_characterization_entry = 14550 param_buf->wmi_chan_rf_characterization_info; 14551 if (!wmi_rf_characterization_entry) 14552 return QDF_STATUS_E_INVAL; 14553 14554 /* 14555 * Using num_wmi_chan_rf_characterization instead of param_buf value 14556 * since memory for rf_characterization_entries was allocated using 14557 * the former. 14558 */ 14559 for (ix = 0; ix < num_rf_characterization_entries; ix++) { 14560 rf_characterization_entries[ix].freq = 14561 WMI_CHAN_RF_CHARACTERIZATION_FREQ_GET( 14562 &wmi_rf_characterization_entry[ix]); 14563 14564 rf_characterization_entries[ix].bw = 14565 WMI_CHAN_RF_CHARACTERIZATION_BW_GET( 14566 &wmi_rf_characterization_entry[ix]); 14567 14568 rf_characterization_entries[ix].chan_metric = 14569 WMI_CHAN_RF_CHARACTERIZATION_CHAN_METRIC_GET( 14570 &wmi_rf_characterization_entry[ix]); 14571 14572 wmi_nofl_debug("rf_characterization_entries[%u]: freq: %u, " 14573 "bw: %u, chan_metric: %u", 14574 ix, rf_characterization_entries[ix].freq, 14575 rf_characterization_entries[ix].bw, 14576 rf_characterization_entries[ix].chan_metric); 14577 } 14578 14579 return QDF_STATUS_SUCCESS; 14580 } 14581 #endif 14582 14583 #ifdef WLAN_FEATURE_11BE 14584 static void 14585 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14586 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14587 { 14588 cap->supports_chan_width_320 = 14589 WMI_SUPPORT_CHAN_WIDTH_320_GET(chainmask_caps->supported_flags); 14590 cap->supports_aDFS_320 = 14591 WMI_SUPPORT_ADFS_320_GET(chainmask_caps->supported_flags); 14592 } 14593 #else 14594 static void 14595 extract_11be_chainmask(struct wlan_psoc_host_chainmask_capabilities *cap, 14596 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps) 14597 { 14598 } 14599 #endif /* WLAN_FEATURE_11BE */ 14600 14601 /** 14602 * extract_chainmask_tables_tlv() - extract chain mask tables from event 14603 * @wmi_handle: wmi handle 14604 * @event: pointer to event buffer 14605 * @chainmask_table: Pointer to hold extracted chainmask tables 14606 * 14607 * Return: QDF_STATUS_SUCCESS for success or error code 14608 */ 14609 static QDF_STATUS extract_chainmask_tables_tlv(wmi_unified_t wmi_handle, 14610 uint8_t *event, struct wlan_psoc_host_chainmask_table *chainmask_table) 14611 { 14612 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14613 WMI_MAC_PHY_CHAINMASK_CAPABILITY *chainmask_caps; 14614 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14615 uint8_t i = 0, j = 0; 14616 uint32_t num_mac_phy_chainmask_caps = 0; 14617 14618 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14619 if (!param_buf) 14620 return QDF_STATUS_E_INVAL; 14621 14622 hw_caps = param_buf->soc_hw_mode_caps; 14623 if (!hw_caps) 14624 return QDF_STATUS_E_INVAL; 14625 14626 if ((!hw_caps->num_chainmask_tables) || 14627 (hw_caps->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES) || 14628 (hw_caps->num_chainmask_tables > 14629 param_buf->num_mac_phy_chainmask_combo)) 14630 return QDF_STATUS_E_INVAL; 14631 14632 chainmask_caps = param_buf->mac_phy_chainmask_caps; 14633 14634 if (!chainmask_caps) 14635 return QDF_STATUS_E_INVAL; 14636 14637 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14638 if (chainmask_table[i].num_valid_chainmasks > 14639 (UINT_MAX - num_mac_phy_chainmask_caps)) { 14640 wmi_err_rl("integer overflow, num_mac_phy_chainmask_caps:%d, i:%d, um_valid_chainmasks:%d", 14641 num_mac_phy_chainmask_caps, i, 14642 chainmask_table[i].num_valid_chainmasks); 14643 return QDF_STATUS_E_INVAL; 14644 } 14645 num_mac_phy_chainmask_caps += 14646 chainmask_table[i].num_valid_chainmasks; 14647 } 14648 14649 if (num_mac_phy_chainmask_caps > 14650 param_buf->num_mac_phy_chainmask_caps) { 14651 wmi_err_rl("invalid chainmask caps num, num_mac_phy_chainmask_caps:%d, param_buf->num_mac_phy_chainmask_caps:%d", 14652 num_mac_phy_chainmask_caps, 14653 param_buf->num_mac_phy_chainmask_caps); 14654 return QDF_STATUS_E_INVAL; 14655 } 14656 14657 for (i = 0; i < hw_caps->num_chainmask_tables; i++) { 14658 14659 wmi_nofl_debug("Dumping chain mask combo data for table : %d", 14660 i); 14661 for (j = 0; j < chainmask_table[i].num_valid_chainmasks; j++) { 14662 14663 chainmask_table[i].cap_list[j].chainmask = 14664 chainmask_caps->chainmask; 14665 14666 chainmask_table[i].cap_list[j].supports_chan_width_20 = 14667 WMI_SUPPORT_CHAN_WIDTH_20_GET(chainmask_caps->supported_flags); 14668 14669 chainmask_table[i].cap_list[j].supports_chan_width_40 = 14670 WMI_SUPPORT_CHAN_WIDTH_40_GET(chainmask_caps->supported_flags); 14671 14672 chainmask_table[i].cap_list[j].supports_chan_width_80 = 14673 WMI_SUPPORT_CHAN_WIDTH_80_GET(chainmask_caps->supported_flags); 14674 14675 chainmask_table[i].cap_list[j].supports_chan_width_160 = 14676 WMI_SUPPORT_CHAN_WIDTH_160_GET(chainmask_caps->supported_flags); 14677 14678 chainmask_table[i].cap_list[j].supports_chan_width_80P80 = 14679 WMI_SUPPORT_CHAN_WIDTH_80P80_GET(chainmask_caps->supported_flags); 14680 14681 chainmask_table[i].cap_list[j].chain_mask_2G = 14682 WMI_SUPPORT_CHAIN_MASK_2G_GET(chainmask_caps->supported_flags); 14683 14684 chainmask_table[i].cap_list[j].chain_mask_5G = 14685 WMI_SUPPORT_CHAIN_MASK_5G_GET(chainmask_caps->supported_flags); 14686 14687 chainmask_table[i].cap_list[j].chain_mask_tx = 14688 WMI_SUPPORT_CHAIN_MASK_TX_GET(chainmask_caps->supported_flags); 14689 14690 chainmask_table[i].cap_list[j].chain_mask_rx = 14691 WMI_SUPPORT_CHAIN_MASK_RX_GET(chainmask_caps->supported_flags); 14692 14693 chainmask_table[i].cap_list[j].supports_aDFS = 14694 WMI_SUPPORT_CHAIN_MASK_ADFS_GET(chainmask_caps->supported_flags); 14695 14696 chainmask_table[i].cap_list[j].supports_aSpectral = 14697 WMI_SUPPORT_AGILE_SPECTRAL_GET(chainmask_caps->supported_flags); 14698 14699 chainmask_table[i].cap_list[j].supports_aSpectral_160 = 14700 WMI_SUPPORT_AGILE_SPECTRAL_160_GET(chainmask_caps->supported_flags); 14701 14702 chainmask_table[i].cap_list[j].supports_aDFS_160 = 14703 WMI_SUPPORT_ADFS_160_GET(chainmask_caps->supported_flags); 14704 14705 extract_11be_chainmask(&chainmask_table[i].cap_list[j], 14706 chainmask_caps); 14707 14708 wmi_nofl_debug("supported_flags: 0x%08x chainmasks: 0x%08x", 14709 chainmask_caps->supported_flags, 14710 chainmask_caps->chainmask); 14711 chainmask_caps++; 14712 } 14713 } 14714 14715 return QDF_STATUS_SUCCESS; 14716 } 14717 14718 /** 14719 * extract_service_ready_ext_tlv() - extract basic extended service ready params 14720 * from event 14721 * @wmi_handle: wmi handle 14722 * @event: pointer to event buffer 14723 * @param: Pointer to hold evt buf 14724 * 14725 * Return: QDF_STATUS_SUCCESS for success or error code 14726 */ 14727 static QDF_STATUS extract_service_ready_ext_tlv(wmi_unified_t wmi_handle, 14728 uint8_t *event, struct wlan_psoc_host_service_ext_param *param) 14729 { 14730 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 14731 wmi_service_ready_ext_event_fixed_param *ev; 14732 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 14733 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 14734 WMI_MAC_PHY_CHAINMASK_COMBO *chain_mask_combo; 14735 uint8_t i = 0; 14736 14737 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 14738 if (!param_buf) 14739 return QDF_STATUS_E_INVAL; 14740 14741 ev = param_buf->fixed_param; 14742 if (!ev) 14743 return QDF_STATUS_E_INVAL; 14744 14745 /* Move this to host based bitmap */ 14746 param->default_conc_scan_config_bits = 14747 ev->default_conc_scan_config_bits; 14748 param->default_fw_config_bits = ev->default_fw_config_bits; 14749 param->he_cap_info = ev->he_cap_info; 14750 param->mpdu_density = ev->mpdu_density; 14751 param->max_bssid_rx_filters = ev->max_bssid_rx_filters; 14752 param->fw_build_vers_ext = ev->fw_build_vers_ext; 14753 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14754 param->num_bin_scaling_params = param_buf->num_wmi_bin_scaling_params; 14755 param->max_bssid_indicator = ev->max_bssid_indicator; 14756 qdf_mem_copy(¶m->ppet, &ev->ppet, sizeof(param->ppet)); 14757 14758 hw_caps = param_buf->soc_hw_mode_caps; 14759 if (hw_caps) 14760 param->num_hw_modes = hw_caps->num_hw_modes; 14761 else 14762 param->num_hw_modes = 0; 14763 14764 reg_caps = param_buf->soc_hal_reg_caps; 14765 if (reg_caps) 14766 param->num_phy = reg_caps->num_phy; 14767 else 14768 param->num_phy = 0; 14769 14770 if (hw_caps) { 14771 param->num_chainmask_tables = hw_caps->num_chainmask_tables; 14772 wmi_nofl_debug("Num chain mask tables: %d", 14773 hw_caps->num_chainmask_tables); 14774 } else 14775 param->num_chainmask_tables = 0; 14776 14777 if (param->num_chainmask_tables > PSOC_MAX_CHAINMASK_TABLES || 14778 param->num_chainmask_tables > 14779 param_buf->num_mac_phy_chainmask_combo) { 14780 wmi_err_rl("num_chainmask_tables is OOB: %u", 14781 param->num_chainmask_tables); 14782 return QDF_STATUS_E_INVAL; 14783 } 14784 chain_mask_combo = param_buf->mac_phy_chainmask_combo; 14785 14786 if (!chain_mask_combo) 14787 return QDF_STATUS_SUCCESS; 14788 14789 wmi_nofl_info_high("Dumping chain mask combo data"); 14790 14791 for (i = 0; i < param->num_chainmask_tables; i++) { 14792 14793 wmi_nofl_info_high("table_id : %d Num valid chainmasks: %d", 14794 chain_mask_combo->chainmask_table_id, 14795 chain_mask_combo->num_valid_chainmask); 14796 14797 param->chainmask_table[i].table_id = 14798 chain_mask_combo->chainmask_table_id; 14799 param->chainmask_table[i].num_valid_chainmasks = 14800 chain_mask_combo->num_valid_chainmask; 14801 chain_mask_combo++; 14802 } 14803 wmi_nofl_info_high("chain mask combo end"); 14804 14805 return QDF_STATUS_SUCCESS; 14806 } 14807 14808 #if defined(CONFIG_AFC_SUPPORT) 14809 /** 14810 * extract_svc_rdy_ext2_afc_tlv() - extract service ready ext2 afc deployment 14811 * type from event 14812 * @ev: pointer to event fixed param 14813 * @param: Pointer to hold the params 14814 * 14815 * Return: void 14816 */ 14817 static void 14818 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14819 struct wlan_psoc_host_service_ext2_param *param) 14820 { 14821 WMI_AFC_FEATURE_6G_DEPLOYMENT_TYPE tgt_afc_dev_type; 14822 enum reg_afc_dev_deploy_type reg_afc_dev_type; 14823 14824 tgt_afc_dev_type = ev->afc_deployment_type; 14825 switch (tgt_afc_dev_type) { 14826 case WMI_AFC_FEATURE_6G_DEPLOYMENT_UNSPECIFIED: 14827 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14828 break; 14829 case WMI_AFC_FEATURE_6G_DEPLOYMENT_INDOOR_ONLY: 14830 reg_afc_dev_type = AFC_DEPLOYMENT_INDOOR; 14831 break; 14832 case WMI_AFC_FEATURE_6G_DEPLOYMENT_OUTDOOR_ONLY: 14833 reg_afc_dev_type = AFC_DEPLOYMENT_OUTDOOR; 14834 break; 14835 default: 14836 wmi_err("invalid afc deployment %d", tgt_afc_dev_type); 14837 reg_afc_dev_type = AFC_DEPLOYMENT_UNKNOWN; 14838 break; 14839 } 14840 param->afc_dev_type = reg_afc_dev_type; 14841 14842 wmi_debug("afc dev type:%d", ev->afc_deployment_type); 14843 } 14844 #else 14845 static inline void 14846 extract_svc_rdy_ext2_afc_tlv(wmi_service_ready_ext2_event_fixed_param *ev, 14847 struct wlan_psoc_host_service_ext2_param *param) 14848 { 14849 } 14850 #endif 14851 14852 /** 14853 * extract_ul_mumimo_support() - extract UL-MUMIMO capability from target cap 14854 * @param: Pointer to hold the params 14855 * 14856 * Return: Void 14857 */ 14858 static void 14859 extract_ul_mumimo_support(struct wlan_psoc_host_service_ext2_param *param) 14860 { 14861 uint32_t tgt_cap = param->target_cap_flags; 14862 14863 param->ul_mumimo_rx_2g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_2GHZ_GET(tgt_cap); 14864 param->ul_mumimo_rx_5g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_5GHZ_GET(tgt_cap); 14865 param->ul_mumimo_rx_6g = WMI_TARGET_CAP_UL_MU_MIMO_RX_SUPPORT_6GHZ_GET(tgt_cap); 14866 param->ul_mumimo_tx_2g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_2GHZ_GET(tgt_cap); 14867 param->ul_mumimo_tx_5g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_5GHZ_GET(tgt_cap); 14868 param->ul_mumimo_tx_6g = WMI_TARGET_CAP_UL_MU_MIMO_TX_SUPPORT_6GHZ_GET(tgt_cap); 14869 } 14870 14871 /** 14872 * extract_hw_bdf_status() - extract service ready ext2 BDF hw status 14873 * type from event 14874 * @ev: pointer to event fixed param 14875 * 14876 * Return: void 14877 */ 14878 14879 static void 14880 extract_hw_bdf_status(wmi_service_ready_ext2_event_fixed_param *ev) 14881 { 14882 uint8_t hw_bdf_s; 14883 14884 hw_bdf_s = ev->hw_bd_status; 14885 switch (hw_bdf_s) { 14886 case WMI_BDF_VERSION_CHECK_DISABLED: 14887 wmi_info("BDF VER is %d, FW and BDF ver check skipped", 14888 hw_bdf_s); 14889 break; 14890 case WMI_BDF_VERSION_CHECK_GOOD: 14891 wmi_info("BDF VER is %d, FW and BDF ver check good", 14892 hw_bdf_s); 14893 break; 14894 case WMI_BDF_VERSION_TEMPLATE_TOO_OLD: 14895 wmi_info("BDF VER is %d, BDF ver is older than the oldest version supported by FW", 14896 hw_bdf_s); 14897 break; 14898 case WMI_BDF_VERSION_TEMPLATE_TOO_NEW: 14899 wmi_info("BDF VER is %d, BDF ver is newer than the newest version supported by FW", 14900 hw_bdf_s); 14901 break; 14902 case WMI_BDF_VERSION_FW_TOO_OLD: 14903 wmi_info("BDF VER is %d, FW ver is older than the major version supported by BDF", 14904 hw_bdf_s); 14905 break; 14906 case WMI_BDF_VERSION_FW_TOO_NEW: 14907 wmi_info("BDF VER is %d, FW ver is newer than the minor version supported by BDF", 14908 hw_bdf_s); 14909 break; 14910 default: 14911 wmi_info("unknown BDF VER %d", hw_bdf_s); 14912 break; 14913 } 14914 } 14915 14916 #ifdef QCA_MULTIPASS_SUPPORT 14917 static void 14918 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14919 uint32_t target_cap_flag) 14920 { 14921 param->is_multipass_sap = 14922 WMI_TARGET_CAP_MULTIPASS_SAP_SUPPORT_GET(target_cap_flag); 14923 } 14924 #else 14925 static void 14926 extract_multipass_sap_cap(struct wlan_psoc_host_service_ext2_param *param, 14927 uint32_t target_cap_flag) 14928 { 14929 } 14930 #endif 14931 14932 #if defined(WLAN_FEATURE_11BE_MLO_ADV_FEATURE) 14933 static inline void 14934 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14935 struct wlan_psoc_host_service_ext2_param *param) 14936 { 14937 param->num_max_mlo_link_per_ml_bss_supp = 14938 ev->num_max_mlo_link_per_ml_bss_supp; 14939 14940 wmi_debug("Firmware Max MLO link support: %d", 14941 param->num_max_mlo_link_per_ml_bss_supp); 14942 } 14943 #else 14944 static inline void 14945 extract_num_max_mlo_link(wmi_service_ready_ext2_event_fixed_param *ev, 14946 struct wlan_psoc_host_service_ext2_param *param) 14947 { 14948 } 14949 #endif 14950 14951 /** 14952 * extract_service_ready_ext2_tlv() - extract service ready ext2 params from 14953 * event 14954 * @wmi_handle: wmi handle 14955 * @event: pointer to event buffer 14956 * @param: Pointer to hold the params 14957 * 14958 * Return: QDF_STATUS_SUCCESS for success or error code 14959 */ 14960 static QDF_STATUS 14961 extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event, 14962 struct wlan_psoc_host_service_ext2_param *param) 14963 { 14964 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 14965 wmi_service_ready_ext2_event_fixed_param *ev; 14966 14967 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 14968 if (!param_buf) 14969 return QDF_STATUS_E_INVAL; 14970 14971 ev = param_buf->fixed_param; 14972 if (!ev) 14973 return QDF_STATUS_E_INVAL; 14974 14975 param->reg_db_version_major = 14976 WMI_REG_DB_VERSION_MAJOR_GET( 14977 ev->reg_db_version); 14978 param->reg_db_version_minor = 14979 WMI_REG_DB_VERSION_MINOR_GET( 14980 ev->reg_db_version); 14981 param->bdf_reg_db_version_major = 14982 WMI_BDF_REG_DB_VERSION_MAJOR_GET( 14983 ev->reg_db_version); 14984 param->bdf_reg_db_version_minor = 14985 WMI_BDF_REG_DB_VERSION_MINOR_GET( 14986 ev->reg_db_version); 14987 param->chwidth_num_peer_caps = ev->chwidth_num_peer_caps; 14988 14989 param->num_dbr_ring_caps = param_buf->num_dma_ring_caps; 14990 14991 param->num_msdu_idx_qtype_map = 14992 param_buf->num_htt_msdu_idx_to_qtype_map; 14993 14994 if (param_buf->nan_cap) { 14995 param->max_ndp_sessions = 14996 param_buf->nan_cap->max_ndp_sessions; 14997 param->max_nan_pairing_sessions = 14998 param_buf->nan_cap->max_pairing_sessions; 14999 } else { 15000 param->max_ndp_sessions = 0; 15001 param->max_nan_pairing_sessions = 0; 15002 } 15003 15004 param->preamble_puncture_bw_cap = ev->preamble_puncture_bw; 15005 param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps; 15006 param->max_users_dl_ofdma = WMI_MAX_USER_PER_PPDU_DL_OFDMA_GET( 15007 ev->max_user_per_ppdu_ofdma); 15008 param->max_users_ul_ofdma = WMI_MAX_USER_PER_PPDU_UL_OFDMA_GET( 15009 ev->max_user_per_ppdu_ofdma); 15010 param->max_users_dl_mumimo = WMI_MAX_USER_PER_PPDU_DL_MUMIMO_GET( 15011 ev->max_user_per_ppdu_mumimo); 15012 param->max_users_ul_mumimo = WMI_MAX_USER_PER_PPDU_UL_MUMIMO_GET( 15013 ev->max_user_per_ppdu_mumimo); 15014 param->target_cap_flags = ev->target_cap_flags; 15015 15016 param->dp_peer_meta_data_ver = 15017 WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION_GET( 15018 ev->target_cap_flags); 15019 15020 extract_multipass_sap_cap(param, ev->target_cap_flags); 15021 15022 extract_ul_mumimo_support(param); 15023 wmi_debug("htt peer data :%d", ev->target_cap_flags); 15024 15025 extract_svc_rdy_ext2_afc_tlv(ev, param); 15026 15027 extract_hw_bdf_status(ev); 15028 15029 extract_num_max_mlo_link(ev, param); 15030 15031 param->num_aux_dev_caps = param_buf->num_aux_dev_caps; 15032 15033 return QDF_STATUS_SUCCESS; 15034 } 15035 15036 /* 15037 * extract_dbs_or_sbs_cap_service_ready_ext2_tlv() - extract dbs_or_sbs cap from 15038 * service ready ext 2 15039 * 15040 * @wmi_handle: wmi handle 15041 * @event: pointer to event buffer 15042 * @sbs_lower_band_end_freq: If sbs_lower_band_end_freq is set to non-zero, 15043 * it indicates async SBS mode is supported, and 15044 * lower-band/higher band to MAC mapping is 15045 * switch-able. unit: mhz. examples 5180, 5320 15046 * 15047 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error 15048 */ 15049 static QDF_STATUS extract_dbs_or_sbs_cap_service_ready_ext2_tlv( 15050 wmi_unified_t wmi_handle, uint8_t *event, 15051 uint32_t *sbs_lower_band_end_freq) 15052 { 15053 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15054 wmi_dbs_or_sbs_cap_ext *dbs_or_sbs_caps; 15055 15056 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15057 if (!param_buf) 15058 return QDF_STATUS_E_INVAL; 15059 15060 dbs_or_sbs_caps = param_buf->dbs_or_sbs_cap_ext; 15061 if (!dbs_or_sbs_caps) 15062 return QDF_STATUS_E_INVAL; 15063 15064 *sbs_lower_band_end_freq = dbs_or_sbs_caps->sbs_lower_band_end_freq; 15065 15066 return QDF_STATUS_SUCCESS; 15067 } 15068 15069 /** 15070 * extract_sar_cap_service_ready_ext_tlv() - 15071 * extract SAR cap from service ready event 15072 * @wmi_handle: wmi handle 15073 * @event: pointer to event buffer 15074 * @ext_param: extended target info 15075 * 15076 * Return: QDF_STATUS_SUCCESS for success or error code 15077 */ 15078 static QDF_STATUS extract_sar_cap_service_ready_ext_tlv( 15079 wmi_unified_t wmi_handle, 15080 uint8_t *event, 15081 struct wlan_psoc_host_service_ext_param *ext_param) 15082 { 15083 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15084 WMI_SAR_CAPABILITIES *sar_caps; 15085 15086 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15087 15088 if (!param_buf) 15089 return QDF_STATUS_E_INVAL; 15090 15091 sar_caps = param_buf->sar_caps; 15092 if (sar_caps) 15093 ext_param->sar_version = sar_caps->active_version; 15094 else 15095 ext_param->sar_version = 0; 15096 15097 return QDF_STATUS_SUCCESS; 15098 } 15099 15100 /** 15101 * extract_hw_mode_cap_service_ready_ext_tlv() - 15102 * extract HW mode cap from service ready event 15103 * @wmi_handle: wmi handle 15104 * @event: pointer to event buffer 15105 * @hw_mode_idx: hw mode idx should be less than num_mode 15106 * @param: Pointer to hold evt buf 15107 * 15108 * Return: QDF_STATUS_SUCCESS for success or error code 15109 */ 15110 static QDF_STATUS extract_hw_mode_cap_service_ready_ext_tlv( 15111 wmi_unified_t wmi_handle, 15112 uint8_t *event, uint8_t hw_mode_idx, 15113 struct wlan_psoc_host_hw_mode_caps *param) 15114 { 15115 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15116 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 15117 15118 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15119 if (!param_buf) 15120 return QDF_STATUS_E_INVAL; 15121 15122 hw_caps = param_buf->soc_hw_mode_caps; 15123 if (!hw_caps) 15124 return QDF_STATUS_E_INVAL; 15125 15126 if (!hw_caps->num_hw_modes || 15127 !param_buf->hw_mode_caps || 15128 hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 15129 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) 15130 return QDF_STATUS_E_INVAL; 15131 15132 if (hw_mode_idx >= hw_caps->num_hw_modes) 15133 return QDF_STATUS_E_INVAL; 15134 15135 param->hw_mode_id = param_buf->hw_mode_caps[hw_mode_idx].hw_mode_id; 15136 param->phy_id_map = param_buf->hw_mode_caps[hw_mode_idx].phy_id_map; 15137 15138 param->hw_mode_config_type = 15139 param_buf->hw_mode_caps[hw_mode_idx].hw_mode_config_type; 15140 15141 return QDF_STATUS_SUCCESS; 15142 } 15143 15144 /** 15145 * extract_service_ready_11be_support() - api to extract 11be support 15146 * @param: host mac phy capabilities 15147 * @mac_phy_caps: mac phy capabilities 15148 * 15149 * Return: void 15150 */ 15151 #ifdef WLAN_FEATURE_11BE 15152 static void 15153 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 15154 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15155 { 15156 param->supports_11be = 15157 WMI_SUPPORT_11BE_GET(mac_phy_caps->supported_flags); 15158 15159 wmi_debug("11be support %d", param->supports_11be); 15160 } 15161 #else 15162 static void 15163 extract_service_ready_11be_support(struct wlan_psoc_host_mac_phy_caps *param, 15164 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15165 { 15166 } 15167 #endif 15168 15169 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 15170 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 15171 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15172 { 15173 param->hw_link_id = WMI_PHY_GET_HW_LINK_ID(mac_phy_caps->pdev_id); 15174 } 15175 #else 15176 static void extract_hw_link_id(struct wlan_psoc_host_mac_phy_caps *param, 15177 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps) 15178 { 15179 } 15180 #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ 15181 15182 /** 15183 * extract_mac_phy_cap_service_ready_ext_tlv() - 15184 * extract MAC phy cap from service ready event 15185 * @wmi_handle: wmi handle 15186 * @event: pointer to event buffer 15187 * @hw_mode_id: hw mode idx should be less than num_mode 15188 * @phy_id: phy id within hw_mode 15189 * @param: Pointer to hold evt buf 15190 * 15191 * Return: QDF_STATUS_SUCCESS for success or error code 15192 */ 15193 static QDF_STATUS extract_mac_phy_cap_service_ready_ext_tlv( 15194 wmi_unified_t wmi_handle, 15195 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15196 struct wlan_psoc_host_mac_phy_caps *param) 15197 { 15198 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15199 WMI_MAC_PHY_CAPABILITIES *mac_phy_caps; 15200 WMI_SOC_MAC_PHY_HW_MODE_CAPS *hw_caps; 15201 uint32_t phy_map; 15202 uint8_t hw_idx, phy_idx = 0, pdev_id; 15203 15204 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15205 if (!param_buf) 15206 return QDF_STATUS_E_INVAL; 15207 15208 hw_caps = param_buf->soc_hw_mode_caps; 15209 if (!hw_caps) 15210 return QDF_STATUS_E_INVAL; 15211 if (hw_caps->num_hw_modes > PSOC_MAX_HW_MODE || 15212 hw_caps->num_hw_modes > param_buf->num_hw_mode_caps) { 15213 wmi_err_rl("invalid num_hw_modes %d, num_hw_mode_caps %d", 15214 hw_caps->num_hw_modes, param_buf->num_hw_mode_caps); 15215 return QDF_STATUS_E_INVAL; 15216 } 15217 15218 for (hw_idx = 0; hw_idx < hw_caps->num_hw_modes; hw_idx++) { 15219 if (hw_mode_id == param_buf->hw_mode_caps[hw_idx].hw_mode_id) 15220 break; 15221 15222 phy_map = param_buf->hw_mode_caps[hw_idx].phy_id_map; 15223 while (phy_map) { 15224 phy_map >>= 1; 15225 phy_idx++; 15226 } 15227 } 15228 15229 if (hw_idx == hw_caps->num_hw_modes) 15230 return QDF_STATUS_E_INVAL; 15231 15232 phy_idx += phy_id; 15233 if (phy_idx >= param_buf->num_mac_phy_caps) 15234 return QDF_STATUS_E_INVAL; 15235 15236 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15237 15238 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15239 param->phy_idx = phy_idx; 15240 pdev_id = WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id); 15241 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15242 wmi_handle, 15243 pdev_id); 15244 param->tgt_pdev_id = pdev_id; 15245 extract_hw_link_id(param, mac_phy_caps); 15246 param->phy_id = mac_phy_caps->phy_id; 15247 param->supports_11b = 15248 WMI_SUPPORT_11B_GET(mac_phy_caps->supported_flags); 15249 param->supports_11g = 15250 WMI_SUPPORT_11G_GET(mac_phy_caps->supported_flags); 15251 param->supports_11a = 15252 WMI_SUPPORT_11A_GET(mac_phy_caps->supported_flags); 15253 param->supports_11n = 15254 WMI_SUPPORT_11N_GET(mac_phy_caps->supported_flags); 15255 param->supports_11ac = 15256 WMI_SUPPORT_11AC_GET(mac_phy_caps->supported_flags); 15257 param->supports_11ax = 15258 WMI_SUPPORT_11AX_GET(mac_phy_caps->supported_flags); 15259 15260 extract_service_ready_11be_support(param, mac_phy_caps); 15261 15262 param->supported_bands = mac_phy_caps->supported_bands; 15263 param->ampdu_density = mac_phy_caps->ampdu_density; 15264 param->max_bw_supported_2G = mac_phy_caps->max_bw_supported_2G; 15265 param->ht_cap_info_2G = mac_phy_caps->ht_cap_info_2G; 15266 param->vht_cap_info_2G = mac_phy_caps->vht_cap_info_2G; 15267 param->vht_supp_mcs_2G = mac_phy_caps->vht_supp_mcs_2G; 15268 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD1] = 15269 mac_phy_caps->he_cap_info_2G; 15270 param->he_cap_info_2G[WMI_HOST_HECAP_MAC_WORD2] = 15271 mac_phy_caps->he_cap_info_2G_ext; 15272 param->he_supp_mcs_2G = mac_phy_caps->he_supp_mcs_2G; 15273 param->tx_chain_mask_2G = mac_phy_caps->tx_chain_mask_2G; 15274 param->rx_chain_mask_2G = mac_phy_caps->rx_chain_mask_2G; 15275 param->max_bw_supported_5G = mac_phy_caps->max_bw_supported_5G; 15276 param->ht_cap_info_5G = mac_phy_caps->ht_cap_info_5G; 15277 param->vht_cap_info_5G = mac_phy_caps->vht_cap_info_5G; 15278 param->vht_supp_mcs_5G = mac_phy_caps->vht_supp_mcs_5G; 15279 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD1] = 15280 mac_phy_caps->he_cap_info_5G; 15281 param->he_cap_info_5G[WMI_HOST_HECAP_MAC_WORD2] = 15282 mac_phy_caps->he_cap_info_5G_ext; 15283 param->he_supp_mcs_5G = mac_phy_caps->he_supp_mcs_5G; 15284 param->he_cap_info_internal = mac_phy_caps->he_cap_info_internal; 15285 param->tx_chain_mask_5G = mac_phy_caps->tx_chain_mask_5G; 15286 param->rx_chain_mask_5G = mac_phy_caps->rx_chain_mask_5G; 15287 qdf_mem_copy(¶m->he_cap_phy_info_2G, 15288 &mac_phy_caps->he_cap_phy_info_2G, 15289 sizeof(param->he_cap_phy_info_2G)); 15290 qdf_mem_copy(¶m->he_cap_phy_info_5G, 15291 &mac_phy_caps->he_cap_phy_info_5G, 15292 sizeof(param->he_cap_phy_info_5G)); 15293 qdf_mem_copy(¶m->he_ppet2G, &mac_phy_caps->he_ppet2G, 15294 sizeof(param->he_ppet2G)); 15295 qdf_mem_copy(¶m->he_ppet5G, &mac_phy_caps->he_ppet5G, 15296 sizeof(param->he_ppet5G)); 15297 param->chainmask_table_id = mac_phy_caps->chainmask_table_id; 15298 param->lmac_id = mac_phy_caps->lmac_id; 15299 param->reg_cap_ext.wireless_modes = convert_wireless_modes_tlv 15300 (mac_phy_caps->wireless_modes); 15301 param->reg_cap_ext.low_2ghz_chan = mac_phy_caps->low_2ghz_chan_freq; 15302 param->reg_cap_ext.high_2ghz_chan = mac_phy_caps->high_2ghz_chan_freq; 15303 param->reg_cap_ext.low_5ghz_chan = mac_phy_caps->low_5ghz_chan_freq; 15304 param->reg_cap_ext.high_5ghz_chan = mac_phy_caps->high_5ghz_chan_freq; 15305 param->nss_ratio_enabled = WMI_NSS_RATIO_ENABLE_DISABLE_GET( 15306 mac_phy_caps->nss_ratio); 15307 param->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); 15308 15309 return QDF_STATUS_SUCCESS; 15310 } 15311 15312 #ifdef WLAN_FEATURE_11BE_MLO 15313 /** 15314 * extract_mac_phy_emlcap() - API to extract EML Capabilities 15315 * @param: host ext2 mac phy capabilities 15316 * @mac_phy_caps: ext mac phy capabilities 15317 * 15318 * Return: void 15319 */ 15320 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15321 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15322 { 15323 if (!param || !mac_phy_caps) 15324 return; 15325 15326 param->emlcap.emlsr_supp = WMI_SUPPORT_EMLSR_GET(mac_phy_caps->eml_capability); 15327 param->emlcap.emlsr_pad_delay = WMI_EMLSR_PADDING_DELAY_GET(mac_phy_caps->eml_capability); 15328 param->emlcap.emlsr_trans_delay = WMI_EMLSR_TRANSITION_DELAY_GET(mac_phy_caps->eml_capability); 15329 param->emlcap.emlmr_supp = WMI_SUPPORT_EMLMR_GET(mac_phy_caps->eml_capability); 15330 param->emlcap.emlmr_delay = WMI_EMLMR_DELAY_GET(mac_phy_caps->eml_capability); 15331 param->emlcap.trans_timeout = WMI_TRANSITION_TIMEOUT_GET(mac_phy_caps->eml_capability); 15332 } 15333 15334 /** 15335 * extract_mac_phy_mldcap() - API to extract MLD Capabilities 15336 * @param: host ext2 mac phy capabilities 15337 * @mac_phy_caps: ext mac phy capabilities 15338 * 15339 * Return: void 15340 */ 15341 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15342 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15343 { 15344 if (!param || !mac_phy_caps) 15345 return; 15346 15347 param->mldcap.max_simult_link = WMI_MAX_NUM_SIMULTANEOUS_LINKS_GET(mac_phy_caps->mld_capability); 15348 param->mldcap.srs_support = WMI_SUPPORT_SRS_GET(mac_phy_caps->mld_capability); 15349 param->mldcap.tid2link_neg_support = WMI_TID_TO_LINK_NEGOTIATION_GET(mac_phy_caps->mld_capability); 15350 param->mldcap.str_freq_sep = WMI_FREQ_SEPERATION_STR_GET(mac_phy_caps->mld_capability); 15351 param->mldcap.aar_support = WMI_SUPPORT_AAR_GET(mac_phy_caps->mld_capability); 15352 } 15353 15354 /** 15355 * extract_mac_phy_msdcap() - API to extract MSD Capabilities 15356 * @param: host ext2 mac phy capabilities 15357 * @mac_phy_caps: ext mac phy capabilities 15358 * 15359 * Return: void 15360 */ 15361 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15362 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15363 { 15364 if (!param || !mac_phy_caps) 15365 return; 15366 15367 param->msdcap.medium_sync_duration = WMI_MEDIUM_SYNC_DURATION_GET(mac_phy_caps->msd_capability); 15368 param->msdcap.medium_sync_ofdm_ed_thresh = WMI_MEDIUM_SYNC_OFDM_ED_THRESHOLD_GET(mac_phy_caps->msd_capability); 15369 param->msdcap.medium_sync_max_txop_num = WMI_MEDIUM_SYNC_MAX_NO_TXOPS_GET(mac_phy_caps->msd_capability); 15370 } 15371 #else 15372 static void extract_mac_phy_emlcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15373 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15374 { 15375 } 15376 15377 static void extract_mac_phy_mldcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15378 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15379 { 15380 } 15381 15382 static void extract_mac_phy_msdcap(struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15383 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15384 { 15385 } 15386 #endif 15387 15388 /** 15389 * extract_mac_phy_cap_ehtcaps- api to extract eht mac phy caps 15390 * @param: host ext2 mac phy capabilities 15391 * @mac_phy_caps: ext mac phy capabilities 15392 * 15393 * Return: void 15394 */ 15395 #ifdef WLAN_FEATURE_11BE 15396 static void extract_mac_phy_cap_ehtcaps( 15397 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15398 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15399 { 15400 uint32_t i; 15401 15402 param->eht_supp_mcs_2G = mac_phy_caps->eht_supp_mcs_2G; 15403 param->eht_supp_mcs_5G = mac_phy_caps->eht_supp_mcs_5G; 15404 param->eht_cap_info_internal = mac_phy_caps->eht_cap_info_internal; 15405 15406 qdf_mem_copy(¶m->eht_cap_info_2G, 15407 &mac_phy_caps->eht_cap_mac_info_2G, 15408 sizeof(param->eht_cap_info_2G)); 15409 qdf_mem_copy(¶m->eht_cap_info_5G, 15410 &mac_phy_caps->eht_cap_mac_info_5G, 15411 sizeof(param->eht_cap_info_5G)); 15412 15413 qdf_mem_copy(¶m->eht_cap_phy_info_2G, 15414 &mac_phy_caps->eht_cap_phy_info_2G, 15415 sizeof(param->eht_cap_phy_info_2G)); 15416 qdf_mem_copy(¶m->eht_cap_phy_info_5G, 15417 &mac_phy_caps->eht_cap_phy_info_5G, 15418 sizeof(param->eht_cap_phy_info_5G)); 15419 15420 qdf_mem_copy(¶m->eht_supp_mcs_ext_2G, 15421 &mac_phy_caps->eht_supp_mcs_ext_2G, 15422 sizeof(param->eht_supp_mcs_ext_2G)); 15423 qdf_mem_copy(¶m->eht_supp_mcs_ext_5G, 15424 &mac_phy_caps->eht_supp_mcs_ext_5G, 15425 sizeof(param->eht_supp_mcs_ext_5G)); 15426 15427 qdf_mem_copy(¶m->eht_ppet2G, &mac_phy_caps->eht_ppet2G, 15428 sizeof(param->eht_ppet2G)); 15429 qdf_mem_copy(¶m->eht_ppet5G, &mac_phy_caps->eht_ppet5G, 15430 sizeof(param->eht_ppet5G)); 15431 15432 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", 15433 mac_phy_caps->eht_cap_mac_info_2G[0], 15434 mac_phy_caps->eht_cap_mac_info_5G[0], 15435 mac_phy_caps->eht_supp_mcs_2G, mac_phy_caps->eht_supp_mcs_5G, 15436 mac_phy_caps->eht_cap_info_internal); 15437 15438 wmi_nofl_debug("EHT phy caps: "); 15439 15440 wmi_nofl_debug("2G:"); 15441 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15442 wmi_nofl_debug("index %d value %x", 15443 i, param->eht_cap_phy_info_2G[i]); 15444 } 15445 wmi_nofl_debug("5G:"); 15446 for (i = 0; i < PSOC_HOST_MAX_EHT_PHY_SIZE; i++) { 15447 wmi_nofl_debug("index %d value %x", 15448 i, param->eht_cap_phy_info_5G[i]); 15449 } 15450 wmi_nofl_debug("2G MCS ext Map:"); 15451 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_2G_SIZE; i++) { 15452 wmi_nofl_debug("index %d value %x", 15453 i, param->eht_supp_mcs_ext_2G[i]); 15454 } 15455 wmi_nofl_debug("5G MCS ext Map:"); 15456 for (i = 0; i < PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE; i++) { 15457 wmi_nofl_debug("index %d value %x", 15458 i, param->eht_supp_mcs_ext_5G[i]); 15459 } 15460 wmi_nofl_debug("2G PPET: numss_m1 %x ru_bit_mask %x", 15461 param->eht_ppet2G.numss_m1, 15462 param->eht_ppet2G.ru_bit_mask); 15463 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15464 wmi_nofl_debug("index %d value %x", 15465 i, param->eht_ppet2G.ppet16_ppet8_ru3_ru0[i]); 15466 } 15467 wmi_nofl_debug("5G PPET: numss_m1 %x ru_bit_mask %x", 15468 param->eht_ppet5G.numss_m1, 15469 param->eht_ppet5G.ru_bit_mask); 15470 for (i = 0; i < PSOC_HOST_MAX_NUM_SS; i++) { 15471 wmi_nofl_debug("index %d value %x", 15472 i, param->eht_ppet5G.ppet16_ppet8_ru3_ru0[i]); 15473 } 15474 } 15475 #else 15476 static void extract_mac_phy_cap_ehtcaps( 15477 struct wlan_psoc_host_mac_phy_caps_ext2 *param, 15478 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps) 15479 { 15480 } 15481 #endif 15482 15483 static QDF_STATUS extract_mac_phy_cap_service_ready_ext2_tlv( 15484 wmi_unified_t wmi_handle, 15485 uint8_t *event, uint8_t hw_mode_id, uint8_t phy_id, 15486 uint8_t phy_idx, 15487 struct wlan_psoc_host_mac_phy_caps_ext2 *param) 15488 { 15489 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15490 WMI_MAC_PHY_CAPABILITIES_EXT *mac_phy_caps; 15491 15492 if (!event) { 15493 wmi_err("null evt_buf"); 15494 return QDF_STATUS_E_INVAL; 15495 } 15496 15497 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15498 15499 if (!param_buf->num_mac_phy_caps) 15500 return QDF_STATUS_SUCCESS; 15501 15502 if (phy_idx >= param_buf->num_mac_phy_caps) 15503 return QDF_STATUS_E_INVAL; 15504 15505 mac_phy_caps = ¶m_buf->mac_phy_caps[phy_idx]; 15506 15507 if ((hw_mode_id != mac_phy_caps->hw_mode_id) || 15508 (phy_id != mac_phy_caps->phy_id)) 15509 return QDF_STATUS_E_INVAL; 15510 15511 param->hw_mode_id = mac_phy_caps->hw_mode_id; 15512 param->phy_id = mac_phy_caps->phy_id; 15513 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15514 wmi_handle, WMI_PHY_GET_PDEV_ID(mac_phy_caps->pdev_id)); 15515 param->wireless_modes_ext = convert_wireless_modes_ext_tlv( 15516 mac_phy_caps->wireless_modes_ext); 15517 15518 extract_mac_phy_cap_ehtcaps(param, mac_phy_caps); 15519 extract_mac_phy_emlcap(param, mac_phy_caps); 15520 extract_mac_phy_mldcap(param, mac_phy_caps); 15521 extract_mac_phy_msdcap(param, mac_phy_caps); 15522 15523 return QDF_STATUS_SUCCESS; 15524 } 15525 15526 /** 15527 * extract_reg_cap_service_ready_ext_tlv() - 15528 * extract REG cap from service ready event 15529 * @wmi_handle: wmi handle 15530 * @event: pointer to event buffer 15531 * @phy_idx: phy idx should be less than num_mode 15532 * @param: Pointer to hold evt buf 15533 * 15534 * Return: QDF_STATUS_SUCCESS for success or error code 15535 */ 15536 static QDF_STATUS extract_reg_cap_service_ready_ext_tlv( 15537 wmi_unified_t wmi_handle, 15538 uint8_t *event, uint8_t phy_idx, 15539 struct wlan_psoc_host_hal_reg_capabilities_ext *param) 15540 { 15541 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15542 WMI_SOC_HAL_REG_CAPABILITIES *reg_caps; 15543 WMI_HAL_REG_CAPABILITIES_EXT *ext_reg_cap; 15544 15545 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event; 15546 if (!param_buf) 15547 return QDF_STATUS_E_INVAL; 15548 15549 reg_caps = param_buf->soc_hal_reg_caps; 15550 if (!reg_caps) 15551 return QDF_STATUS_E_INVAL; 15552 15553 if (reg_caps->num_phy > param_buf->num_hal_reg_caps) 15554 return QDF_STATUS_E_INVAL; 15555 15556 if (phy_idx >= reg_caps->num_phy) 15557 return QDF_STATUS_E_INVAL; 15558 15559 if (!param_buf->hal_reg_caps) 15560 return QDF_STATUS_E_INVAL; 15561 15562 ext_reg_cap = ¶m_buf->hal_reg_caps[phy_idx]; 15563 15564 param->phy_id = ext_reg_cap->phy_id; 15565 param->eeprom_reg_domain = ext_reg_cap->eeprom_reg_domain; 15566 param->eeprom_reg_domain_ext = ext_reg_cap->eeprom_reg_domain_ext; 15567 param->regcap1 = ext_reg_cap->regcap1; 15568 param->regcap2 = ext_reg_cap->regcap2; 15569 param->wireless_modes = convert_wireless_modes_tlv( 15570 ext_reg_cap->wireless_modes); 15571 param->low_2ghz_chan = ext_reg_cap->low_2ghz_chan; 15572 param->high_2ghz_chan = ext_reg_cap->high_2ghz_chan; 15573 param->low_5ghz_chan = ext_reg_cap->low_5ghz_chan; 15574 param->high_5ghz_chan = ext_reg_cap->high_5ghz_chan; 15575 15576 return QDF_STATUS_SUCCESS; 15577 } 15578 15579 static QDF_STATUS validate_dbr_ring_caps_idx(uint8_t idx, 15580 uint8_t num_dma_ring_caps) 15581 { 15582 /* If dma_ring_caps is populated, num_dbr_ring_caps is non-zero */ 15583 if (!num_dma_ring_caps) { 15584 wmi_err("dma_ring_caps %d", num_dma_ring_caps); 15585 return QDF_STATUS_E_INVAL; 15586 } 15587 if (idx >= num_dma_ring_caps) { 15588 wmi_err("Index %d exceeds range", idx); 15589 return QDF_STATUS_E_INVAL; 15590 } 15591 return QDF_STATUS_SUCCESS; 15592 } 15593 15594 static void 15595 populate_dbr_ring_cap_elems(wmi_unified_t wmi_handle, 15596 struct wlan_psoc_host_dbr_ring_caps *param, 15597 WMI_DMA_RING_CAPABILITIES *dbr_ring_caps) 15598 { 15599 param->pdev_id = wmi_handle->ops->convert_target_pdev_id_to_host( 15600 wmi_handle, 15601 dbr_ring_caps->pdev_id); 15602 param->mod_id = dbr_ring_caps->mod_id; 15603 param->ring_elems_min = dbr_ring_caps->ring_elems_min; 15604 param->min_buf_size = dbr_ring_caps->min_buf_size; 15605 param->min_buf_align = dbr_ring_caps->min_buf_align; 15606 } 15607 15608 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext_tlv( 15609 wmi_unified_t wmi_handle, 15610 uint8_t *event, uint8_t idx, 15611 struct wlan_psoc_host_dbr_ring_caps *param) 15612 { 15613 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf; 15614 QDF_STATUS status; 15615 15616 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *)event; 15617 if (!param_buf) 15618 return QDF_STATUS_E_INVAL; 15619 15620 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15621 if (status != QDF_STATUS_SUCCESS) 15622 return status; 15623 15624 populate_dbr_ring_cap_elems(wmi_handle, param, 15625 ¶m_buf->dma_ring_caps[idx]); 15626 return QDF_STATUS_SUCCESS; 15627 } 15628 15629 static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv( 15630 wmi_unified_t wmi_handle, 15631 uint8_t *event, uint8_t idx, 15632 struct wlan_psoc_host_dbr_ring_caps *param) 15633 { 15634 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15635 QDF_STATUS status; 15636 15637 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15638 if (!param_buf) 15639 return QDF_STATUS_E_INVAL; 15640 15641 status = validate_dbr_ring_caps_idx(idx, param_buf->num_dma_ring_caps); 15642 if (status != QDF_STATUS_SUCCESS) 15643 return status; 15644 15645 populate_dbr_ring_cap_elems(wmi_handle, param, 15646 ¶m_buf->dma_ring_caps[idx]); 15647 return QDF_STATUS_SUCCESS; 15648 } 15649 15650 static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv( 15651 wmi_unified_t wmi_handle, 15652 uint8_t *event, uint8_t idx, 15653 struct wlan_psoc_host_scan_radio_caps *param) 15654 { 15655 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15656 WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps; 15657 15658 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15659 if (!param_buf) 15660 return QDF_STATUS_E_INVAL; 15661 15662 if (idx >= param_buf->num_wmi_scan_radio_caps) 15663 return QDF_STATUS_E_INVAL; 15664 15665 scan_radio_caps = ¶m_buf->wmi_scan_radio_caps[idx]; 15666 param->phy_id = scan_radio_caps->phy_id; 15667 param->scan_radio_supported = 15668 WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags); 15669 param->dfs_en = 15670 WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags); 15671 param->blanking_en = 15672 WMI_SCAN_RADIO_CAP_BLANKING_SUPPORT_GET(scan_radio_caps->flags); 15673 15674 return QDF_STATUS_SUCCESS; 15675 } 15676 15677 static QDF_STATUS extract_msdu_idx_qtype_map_service_ready_ext2_tlv( 15678 wmi_unified_t wmi_handle, 15679 uint8_t *event, uint8_t idx, 15680 uint8_t *msdu_qtype) 15681 { 15682 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15683 wmi_htt_msdu_idx_to_htt_msdu_qtype *msdu_idx_to_qtype; 15684 uint8_t wmi_htt_msdu_idx; 15685 15686 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15687 if (!param_buf) 15688 return QDF_STATUS_E_INVAL; 15689 15690 if (idx >= param_buf->num_htt_msdu_idx_to_qtype_map) 15691 return QDF_STATUS_E_INVAL; 15692 15693 msdu_idx_to_qtype = ¶m_buf->htt_msdu_idx_to_qtype_map[idx]; 15694 wmi_htt_msdu_idx = 15695 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_INDEX_GET( 15696 msdu_idx_to_qtype->index_and_type); 15697 if (wmi_htt_msdu_idx != idx) { 15698 wmi_err("wmi_htt_msdu_idx 0x%x is not same as idx 0x%x", 15699 wmi_htt_msdu_idx, idx); 15700 return QDF_STATUS_E_INVAL; 15701 } 15702 15703 *msdu_qtype = 15704 WMI_HTT_MSDUQ_IDX_TO_MSDUQ_QTYPE_TYPE_GET( 15705 msdu_idx_to_qtype->index_and_type); 15706 15707 return QDF_STATUS_SUCCESS; 15708 } 15709 15710 static QDF_STATUS extract_sw_cal_ver_ext2_tlv(wmi_unified_t wmi_handle, 15711 uint8_t *event, 15712 struct wmi_host_sw_cal_ver *cal) 15713 { 15714 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15715 wmi_sw_cal_ver_cap *fw_cap; 15716 15717 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15718 if (!param_buf) 15719 return QDF_STATUS_E_INVAL; 15720 15721 fw_cap = param_buf->sw_cal_ver_cap; 15722 if (!fw_cap) 15723 return QDF_STATUS_E_INVAL; 15724 15725 cal->bdf_cal_ver = fw_cap->bdf_cal_ver; 15726 cal->ftm_cal_ver = fw_cap->ftm_cal_ver; 15727 cal->status = fw_cap->status; 15728 15729 return QDF_STATUS_SUCCESS; 15730 } 15731 15732 static QDF_STATUS extract_aux_dev_cap_service_ready_ext2_tlv( 15733 wmi_unified_t wmi_handle, 15734 uint8_t *event, uint8_t idx, 15735 struct wlan_psoc_host_aux_dev_caps *param) 15736 15737 { 15738 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 15739 wmi_aux_dev_capabilities *aux_dev_caps; 15740 15741 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 15742 15743 if (!param_buf->num_aux_dev_caps) 15744 return QDF_STATUS_E_INVAL; 15745 15746 if (!param_buf->aux_dev_caps) { 15747 wmi_err("aux_dev_caps is NULL"); 15748 return QDF_STATUS_E_INVAL; 15749 } 15750 15751 if (idx >= param_buf->num_aux_dev_caps) 15752 return QDF_STATUS_E_INVAL; 15753 15754 aux_dev_caps = ¶m_buf->aux_dev_caps[idx]; 15755 15756 param->aux_index = aux_dev_caps->aux_index; 15757 param->hw_mode_id = aux_dev_caps->hw_mode_id; 15758 param->supported_modes_bitmap = aux_dev_caps->supported_modes_bitmap; 15759 param->listen_pdev_id_map = aux_dev_caps->listen_pdev_id_map; 15760 param->emlsr_pdev_id_map = aux_dev_caps->emlsr_pdev_id_map; 15761 15762 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", 15763 idx, aux_dev_caps->aux_index, 15764 aux_dev_caps->hw_mode_id, 15765 aux_dev_caps->supported_modes_bitmap, 15766 aux_dev_caps->listen_pdev_id_map, 15767 aux_dev_caps->emlsr_pdev_id_map); 15768 15769 return QDF_STATUS_SUCCESS; 15770 } 15771 15772 /** 15773 * wmi_tgt_thermal_level_to_host() - Convert target thermal level to host enum 15774 * @level: target thermal level from WMI_THERM_THROT_STATS_EVENTID event 15775 * 15776 * Return: host thermal throt level 15777 */ 15778 static enum thermal_throttle_level 15779 wmi_tgt_thermal_level_to_host(uint32_t level) 15780 { 15781 switch (level) { 15782 case WMI_THERMAL_FULLPERF: 15783 return THERMAL_FULLPERF; 15784 case WMI_THERMAL_MITIGATION: 15785 return THERMAL_MITIGATION; 15786 case WMI_THERMAL_SHUTOFF: 15787 return THERMAL_SHUTOFF; 15788 case WMI_THERMAL_SHUTDOWN_TGT: 15789 return THERMAL_SHUTDOWN_TARGET; 15790 default: 15791 return THERMAL_UNKNOWN; 15792 } 15793 } 15794 15795 #ifdef THERMAL_STATS_SUPPORT 15796 static void 15797 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15798 uint32_t *therm_throt_levels, 15799 struct thermal_throt_level_stats *tt_temp_range_stats) 15800 { 15801 uint8_t lvl_idx; 15802 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15803 wmi_thermal_throt_temp_range_stats *wmi_tt_stats; 15804 15805 tt_stats_event = param_buf->fixed_param; 15806 *therm_throt_levels = (tt_stats_event->therm_throt_levels > 15807 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX) ? 15808 WMI_THERMAL_STATS_TEMP_THRESH_LEVEL_MAX : 15809 tt_stats_event->therm_throt_levels; 15810 15811 if (*therm_throt_levels > param_buf->num_temp_range_stats) { 15812 wmi_err("therm_throt_levels:%u oob num_temp_range_stats:%u", 15813 *therm_throt_levels, 15814 param_buf->num_temp_range_stats); 15815 return; 15816 } 15817 15818 wmi_tt_stats = param_buf->temp_range_stats; 15819 if (!wmi_tt_stats) { 15820 wmi_err("wmi_tt_stats Null"); 15821 return; 15822 } 15823 15824 for (lvl_idx = 0; lvl_idx < *therm_throt_levels; lvl_idx++) { 15825 tt_temp_range_stats[lvl_idx].start_temp_level = 15826 wmi_tt_stats[lvl_idx].start_temp_level; 15827 tt_temp_range_stats[lvl_idx].end_temp_level = 15828 wmi_tt_stats[lvl_idx].end_temp_level; 15829 tt_temp_range_stats[lvl_idx].total_time_ms_lo = 15830 wmi_tt_stats[lvl_idx].total_time_ms_lo; 15831 tt_temp_range_stats[lvl_idx].total_time_ms_hi = 15832 wmi_tt_stats[lvl_idx].total_time_ms_hi; 15833 tt_temp_range_stats[lvl_idx].num_entry = 15834 wmi_tt_stats[lvl_idx].num_entry; 15835 wmi_debug("level %d, start temp %d, end temp %d, total time low %d, total time high %d, counter %d", 15836 lvl_idx, wmi_tt_stats[lvl_idx].start_temp_level, 15837 wmi_tt_stats[lvl_idx].end_temp_level, 15838 wmi_tt_stats[lvl_idx].total_time_ms_lo, 15839 wmi_tt_stats[lvl_idx].total_time_ms_hi, 15840 wmi_tt_stats[lvl_idx].num_entry); 15841 } 15842 } 15843 #else 15844 static void 15845 populate_thermal_stats(WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf, 15846 uint32_t *therm_throt_levels, 15847 struct thermal_throt_level_stats *tt_temp_range_stats) 15848 { 15849 } 15850 #endif 15851 15852 /** 15853 * extract_thermal_stats_tlv() - extract thermal stats from event 15854 * @wmi_handle: wmi handle 15855 * @evt_buf: Pointer to event buffer 15856 * @temp: Pointer to hold extracted temperature 15857 * @level: Pointer to hold extracted level in host enum 15858 * @therm_throt_levels: Pointer to hold extracted thermal throttle temp 15859 * range 15860 * @tt_temp_range_stats_event: Pointer to hold extracted thermal stats for 15861 * every level 15862 * @pdev_id: Pointer to hold extracted pdev id 15863 * 15864 * Return: QDF_STATUS_SUCCESS for success or error code 15865 */ 15866 static QDF_STATUS 15867 extract_thermal_stats_tlv(wmi_unified_t wmi_handle, 15868 void *evt_buf, uint32_t *temp, 15869 enum thermal_throttle_level *level, 15870 uint32_t *therm_throt_levels, 15871 struct thermal_throt_level_stats *tt_temp_range_stats_event, 15872 uint32_t *pdev_id) 15873 { 15874 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15875 wmi_therm_throt_stats_event_fixed_param *tt_stats_event; 15876 15877 param_buf = 15878 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15879 if (!param_buf) 15880 return QDF_STATUS_E_INVAL; 15881 15882 tt_stats_event = param_buf->fixed_param; 15883 wmi_debug("thermal temperature %d level %d", 15884 tt_stats_event->temp, tt_stats_event->level); 15885 *pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 15886 wmi_handle, 15887 tt_stats_event->pdev_id); 15888 *temp = tt_stats_event->temp; 15889 *level = wmi_tgt_thermal_level_to_host(tt_stats_event->level); 15890 15891 if (tt_stats_event->therm_throt_levels) 15892 populate_thermal_stats(param_buf, therm_throt_levels, 15893 tt_temp_range_stats_event); 15894 15895 return QDF_STATUS_SUCCESS; 15896 } 15897 15898 /** 15899 * extract_thermal_level_stats_tlv() - extract thermal level stats from event 15900 * @wmi_handle: wmi handle 15901 * @evt_buf: pointer to event buffer 15902 * @idx: Index to level stats 15903 * @levelcount: Pointer to hold levelcount 15904 * @dccount: Pointer to hold dccount 15905 * 15906 * Return: QDF_STATUS_SUCCESS for success or error code 15907 */ 15908 static QDF_STATUS 15909 extract_thermal_level_stats_tlv(wmi_unified_t wmi_handle, 15910 void *evt_buf, uint8_t idx, uint32_t *levelcount, 15911 uint32_t *dccount) 15912 { 15913 WMI_THERM_THROT_STATS_EVENTID_param_tlvs *param_buf; 15914 wmi_therm_throt_level_stats_info *tt_level_info; 15915 15916 param_buf = 15917 (WMI_THERM_THROT_STATS_EVENTID_param_tlvs *) evt_buf; 15918 if (!param_buf) 15919 return QDF_STATUS_E_INVAL; 15920 15921 tt_level_info = param_buf->therm_throt_level_stats_info; 15922 15923 if (idx < THERMAL_LEVELS) { 15924 *levelcount = tt_level_info[idx].level_count; 15925 *dccount = tt_level_info[idx].dc_count; 15926 return QDF_STATUS_SUCCESS; 15927 } 15928 15929 return QDF_STATUS_E_FAILURE; 15930 } 15931 15932 /** 15933 * fips_conv_data_be() - LE to BE conversion of FIPS ev data 15934 * @data_len: data length 15935 * @data: pointer to data 15936 * 15937 * Return: QDF_STATUS - success or error status 15938 */ 15939 #ifdef BIG_ENDIAN_HOST 15940 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15941 { 15942 uint8_t *data_aligned = NULL; 15943 int c; 15944 unsigned char *data_unaligned; 15945 15946 data_unaligned = qdf_mem_malloc(((sizeof(uint8_t) * data_len) + 15947 FIPS_ALIGN)); 15948 /* Assigning unaligned space to copy the data */ 15949 /* Checking if kmalloc does successful allocation */ 15950 if (!data_unaligned) 15951 return QDF_STATUS_E_FAILURE; 15952 15953 /* Checking if space is aligned */ 15954 if (!FIPS_IS_ALIGNED(data_unaligned, FIPS_ALIGN)) { 15955 /* align the data space */ 15956 data_aligned = 15957 (uint8_t *)FIPS_ALIGNTO(data_unaligned, FIPS_ALIGN); 15958 } else { 15959 data_aligned = (u_int8_t *)data_unaligned; 15960 } 15961 15962 /* memset and copy content from data to data aligned */ 15963 OS_MEMSET(data_aligned, 0, data_len); 15964 OS_MEMCPY(data_aligned, data, data_len); 15965 /* Endianness to LE */ 15966 for (c = 0; c < data_len/4; c++) { 15967 *((u_int32_t *)data_aligned + c) = 15968 qdf_le32_to_cpu(*((u_int32_t *)data_aligned + c)); 15969 } 15970 15971 /* Copy content to event->data */ 15972 OS_MEMCPY(data, data_aligned, data_len); 15973 15974 /* clean up allocated space */ 15975 qdf_mem_free(data_unaligned); 15976 data_aligned = NULL; 15977 data_unaligned = NULL; 15978 15979 /*************************************************************/ 15980 15981 return QDF_STATUS_SUCCESS; 15982 } 15983 #else 15984 static QDF_STATUS fips_conv_data_be(uint32_t data_len, uint8_t *data) 15985 { 15986 return QDF_STATUS_SUCCESS; 15987 } 15988 #endif 15989 15990 /** 15991 * send_pdev_get_pn_cmd_tlv() - send get PN request params to fw 15992 * @wmi_handle: wmi handle 15993 * @params: PN request params for peer 15994 * 15995 * Return: QDF_STATUS - success or error status 15996 */ 15997 static QDF_STATUS 15998 send_pdev_get_pn_cmd_tlv(wmi_unified_t wmi_handle, 15999 struct peer_request_pn_param *params) 16000 { 16001 wmi_peer_tx_pn_request_cmd_fixed_param *cmd; 16002 wmi_buf_t buf; 16003 uint8_t *buf_ptr; 16004 uint32_t len = sizeof(wmi_peer_tx_pn_request_cmd_fixed_param); 16005 16006 buf = wmi_buf_alloc(wmi_handle, len); 16007 if (!buf) { 16008 wmi_err("wmi_buf_alloc failed"); 16009 return QDF_STATUS_E_FAILURE; 16010 } 16011 16012 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16013 cmd = (wmi_peer_tx_pn_request_cmd_fixed_param *)buf_ptr; 16014 16015 WMITLV_SET_HDR(&cmd->tlv_header, 16016 WMITLV_TAG_STRUC_wmi_peer_tx_pn_request_cmd_fixed_param, 16017 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_tx_pn_request_cmd_fixed_param)); 16018 16019 cmd->vdev_id = params->vdev_id; 16020 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 16021 cmd->key_type = params->key_type; 16022 cmd->key_ix = params->keyix; 16023 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16024 WMI_PEER_TX_PN_REQUEST_CMDID)) { 16025 wmi_err("Failed to send WMI command"); 16026 wmi_buf_free(buf); 16027 return QDF_STATUS_E_FAILURE; 16028 } 16029 return QDF_STATUS_SUCCESS; 16030 } 16031 16032 /** 16033 * extract_get_pn_data_tlv() - extract pn resp 16034 * @wmi_handle: wmi handle 16035 * @evt_buf: pointer to event buffer 16036 * @param: PN response params for peer 16037 * 16038 * Return: QDF_STATUS - success or error status 16039 */ 16040 static QDF_STATUS 16041 extract_get_pn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16042 struct wmi_host_get_pn_event *param) 16043 { 16044 WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 16045 wmi_peer_tx_pn_response_event_fixed_param *event = NULL; 16046 16047 param_buf = (WMI_PEER_TX_PN_RESPONSE_EVENTID_param_tlvs *)evt_buf; 16048 event = 16049 (wmi_peer_tx_pn_response_event_fixed_param *)param_buf->fixed_param; 16050 16051 param->vdev_id = event->vdev_id; 16052 param->key_type = event->key_type; 16053 param->key_ix = event->key_ix; 16054 qdf_mem_copy(param->pn, event->pn, sizeof(event->pn)); 16055 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, param->mac_addr); 16056 16057 return QDF_STATUS_SUCCESS; 16058 } 16059 16060 /** 16061 * send_pdev_get_rxpn_cmd_tlv() - send get Rx PN request params to fw 16062 * @wmi_handle: wmi handle 16063 * @params: Rx PN request params for peer 16064 * 16065 * Return: QDF_STATUS - success or error status 16066 */ 16067 static QDF_STATUS 16068 send_pdev_get_rxpn_cmd_tlv(wmi_unified_t wmi_handle, 16069 struct peer_request_rxpn_param *params) 16070 { 16071 wmi_peer_rx_pn_request_cmd_fixed_param *cmd; 16072 wmi_buf_t buf; 16073 uint8_t *buf_ptr; 16074 uint32_t len = sizeof(wmi_peer_rx_pn_request_cmd_fixed_param); 16075 16076 if (!is_service_enabled_tlv(wmi_handle, 16077 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 16078 wmi_err("Rx PN Replay Check not supported by target"); 16079 return QDF_STATUS_E_NOSUPPORT; 16080 } 16081 16082 buf = wmi_buf_alloc(wmi_handle, len); 16083 if (!buf) { 16084 wmi_err("wmi_buf_alloc failed"); 16085 return QDF_STATUS_E_FAILURE; 16086 } 16087 16088 buf_ptr = (uint8_t *)wmi_buf_data(buf); 16089 cmd = (wmi_peer_rx_pn_request_cmd_fixed_param *)buf_ptr; 16090 16091 WMITLV_SET_HDR(&cmd->tlv_header, 16092 WMITLV_TAG_STRUC_wmi_peer_rx_pn_request_cmd_fixed_param, 16093 WMITLV_GET_STRUCT_TLVLEN(wmi_peer_rx_pn_request_cmd_fixed_param)); 16094 16095 cmd->vdev_id = params->vdev_id; 16096 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->peer_macaddr, &cmd->peer_macaddr); 16097 cmd->key_ix = params->keyix; 16098 if (wmi_unified_cmd_send(wmi_handle, buf, len, 16099 WMI_PEER_RX_PN_REQUEST_CMDID)) { 16100 wmi_err("Failed to send WMI command"); 16101 wmi_buf_free(buf); 16102 return QDF_STATUS_E_FAILURE; 16103 } 16104 return QDF_STATUS_SUCCESS; 16105 } 16106 16107 /** 16108 * extract_get_rxpn_data_tlv() - extract Rx PN resp 16109 * @wmi_handle: wmi handle 16110 * @evt_buf: pointer to event buffer 16111 * @params: Rx PN response params for peer 16112 * 16113 * Return: QDF_STATUS - success or error status 16114 */ 16115 static QDF_STATUS 16116 extract_get_rxpn_data_tlv(wmi_unified_t wmi_handle, void *evt_buf, 16117 struct wmi_host_get_rxpn_event *params) 16118 { 16119 WMI_PEER_RX_PN_RESPONSE_EVENTID_param_tlvs *param_buf; 16120 wmi_peer_rx_pn_response_event_fixed_param *event; 16121 16122 param_buf = evt_buf; 16123 event = param_buf->fixed_param; 16124 16125 params->vdev_id = event->vdev_id; 16126 params->keyix = event->key_idx; 16127 qdf_mem_copy(params->pn, event->pn, sizeof(event->pn)); 16128 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, params->mac_addr); 16129 16130 return QDF_STATUS_SUCCESS; 16131 } 16132 16133 /** 16134 * extract_fips_event_data_tlv() - extract fips event data 16135 * @wmi_handle: wmi handle 16136 * @evt_buf: pointer to event buffer 16137 * @param: pointer FIPS event params 16138 * 16139 * Return: QDF_STATUS_SUCCESS for success or error code 16140 */ 16141 static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, 16142 void *evt_buf, struct wmi_host_fips_event_param *param) 16143 { 16144 WMI_PDEV_FIPS_EVENTID_param_tlvs *param_buf; 16145 wmi_pdev_fips_event_fixed_param *event; 16146 16147 param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; 16148 event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; 16149 16150 if (event->data_len > param_buf->num_data) 16151 return QDF_STATUS_E_FAILURE; 16152 16153 if (fips_conv_data_be(event->data_len, param_buf->data) != 16154 QDF_STATUS_SUCCESS) 16155 return QDF_STATUS_E_FAILURE; 16156 16157 param->data = (uint32_t *)param_buf->data; 16158 param->data_len = event->data_len; 16159 param->error_status = event->error_status; 16160 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16161 wmi_handle, 16162 event->pdev_id); 16163 16164 return QDF_STATUS_SUCCESS; 16165 } 16166 16167 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 16168 /** 16169 * extract_fips_extend_event_data_tlv() - extract fips event data 16170 * @wmi_handle: wmi handle 16171 * @evt_buf: pointer to event buffer 16172 * @param: pointer FIPS event params 16173 * 16174 * Return: QDF_STATUS_SUCCESS for success or error code 16175 */ 16176 static QDF_STATUS 16177 extract_fips_extend_event_data_tlv(wmi_unified_t wmi_handle, 16178 void *evt_buf, 16179 struct wmi_host_fips_extend_event_param 16180 *param) 16181 { 16182 WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *param_buf; 16183 wmi_pdev_fips_extend_event_fixed_param *event; 16184 16185 param_buf = (WMI_PDEV_FIPS_EXTEND_EVENTID_param_tlvs *)evt_buf; 16186 event = (wmi_pdev_fips_extend_event_fixed_param *)param_buf->fixed_param; 16187 16188 if (fips_conv_data_be(event->data_len, param_buf->data) != 16189 QDF_STATUS_SUCCESS) 16190 return QDF_STATUS_E_FAILURE; 16191 16192 param->data = (uint32_t *)param_buf->data; 16193 param->data_len = event->data_len; 16194 param->error_status = event->error_status; 16195 param->fips_cookie = event->fips_cookie; 16196 param->cmd_frag_idx = event->cmd_frag_idx; 16197 param->more_bit = event->more_bit; 16198 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 16199 wmi_handle, 16200 event->pdev_id); 16201 16202 return QDF_STATUS_SUCCESS; 16203 } 16204 #endif 16205 16206 #ifdef WLAN_FEATURE_DISA 16207 /** 16208 * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp 16209 * params from event 16210 * @wmi_handle: wmi handle 16211 * @evt_buf: pointer to event buffer 16212 * @resp: Pointer to hold resp parameters 16213 * 16214 * Return: QDF_STATUS_SUCCESS for success or error code 16215 */ 16216 static QDF_STATUS 16217 extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle, 16218 void *evt_buf, 16219 struct disa_encrypt_decrypt_resp_params 16220 *resp) 16221 { 16222 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf; 16223 wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event; 16224 16225 param_buf = evt_buf; 16226 if (!param_buf) { 16227 wmi_err("encrypt decrypt resp evt_buf is NULL"); 16228 return QDF_STATUS_E_INVAL; 16229 } 16230 16231 data_event = param_buf->fixed_param; 16232 16233 resp->vdev_id = data_event->vdev_id; 16234 resp->status = data_event->status; 16235 16236 if ((data_event->data_length > param_buf->num_enc80211_frame) || 16237 (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - 16238 WMI_TLV_HDR_SIZE - sizeof(*data_event))) { 16239 wmi_err("FW msg data_len %d more than TLV hdr %d", 16240 data_event->data_length, 16241 param_buf->num_enc80211_frame); 16242 return QDF_STATUS_E_INVAL; 16243 } 16244 16245 resp->data_len = data_event->data_length; 16246 16247 if (resp->data_len) 16248 resp->data = (uint8_t *)param_buf->enc80211_frame; 16249 16250 return QDF_STATUS_SUCCESS; 16251 } 16252 #endif /* WLAN_FEATURE_DISA */ 16253 16254 static bool is_management_record_tlv(uint32_t cmd_id) 16255 { 16256 switch (cmd_id) { 16257 case WMI_MGMT_TX_SEND_CMDID: 16258 case WMI_MGMT_TX_COMPLETION_EVENTID: 16259 case WMI_OFFCHAN_DATA_TX_SEND_CMDID: 16260 case WMI_MGMT_RX_EVENTID: 16261 return true; 16262 default: 16263 return false; 16264 } 16265 } 16266 16267 static bool is_force_fw_hang_cmd_tlv(uint32_t cmd_id) 16268 { 16269 if (cmd_id == WMI_FORCE_FW_HANG_CMDID) 16270 return true; 16271 16272 return false; 16273 } 16274 16275 static bool is_diag_event_tlv(uint32_t event_id) 16276 { 16277 if (WMI_DIAG_EVENTID == event_id) 16278 return true; 16279 16280 return false; 16281 } 16282 16283 static uint16_t wmi_tag_fw_hang_cmd(wmi_unified_t wmi_handle) 16284 { 16285 uint16_t tag = 0; 16286 16287 if (qdf_atomic_read(&wmi_handle->is_target_suspended)) { 16288 qdf_nofl_err("%s: Target is already suspended, Ignore FW Hang Command", 16289 __func__); 16290 return tag; 16291 } 16292 16293 if (wmi_handle->tag_crash_inject) 16294 tag = HTC_TX_PACKET_TAG_AUTO_PM; 16295 16296 wmi_handle->tag_crash_inject = false; 16297 return tag; 16298 } 16299 16300 /** 16301 * wmi_set_htc_tx_tag_tlv() - set HTC TX tag for WMI commands 16302 * @wmi_handle: WMI handle 16303 * @buf: WMI buffer 16304 * @cmd_id: WMI command Id 16305 * 16306 * Return: htc_tx_tag 16307 */ 16308 static uint16_t wmi_set_htc_tx_tag_tlv(wmi_unified_t wmi_handle, 16309 wmi_buf_t buf, 16310 uint32_t cmd_id) 16311 { 16312 uint16_t htc_tx_tag = 0; 16313 16314 switch (cmd_id) { 16315 case WMI_WOW_ENABLE_CMDID: 16316 case WMI_PDEV_SUSPEND_CMDID: 16317 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: 16318 case WMI_PDEV_RESUME_CMDID: 16319 case WMI_HB_SET_ENABLE_CMDID: 16320 case WMI_WOW_SET_ACTION_WAKE_UP_CMDID: 16321 #ifdef FEATURE_WLAN_D0WOW 16322 case WMI_D0_WOW_ENABLE_DISABLE_CMDID: 16323 #endif 16324 htc_tx_tag = HTC_TX_PACKET_TAG_AUTO_PM; 16325 break; 16326 case WMI_FORCE_FW_HANG_CMDID: 16327 htc_tx_tag = wmi_tag_fw_hang_cmd(wmi_handle); 16328 break; 16329 default: 16330 break; 16331 } 16332 16333 return htc_tx_tag; 16334 } 16335 16336 #ifdef CONFIG_BAND_6GHZ 16337 16338 static struct cur_reg_rule 16339 *create_ext_reg_rules_from_wmi(uint32_t num_reg_rules, 16340 wmi_regulatory_rule_ext_struct *wmi_reg_rule) 16341 { 16342 struct cur_reg_rule *reg_rule_ptr; 16343 uint32_t count; 16344 16345 if (!num_reg_rules) 16346 return NULL; 16347 16348 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16349 sizeof(*reg_rule_ptr)); 16350 16351 if (!reg_rule_ptr) 16352 return NULL; 16353 16354 for (count = 0; count < num_reg_rules; count++) { 16355 reg_rule_ptr[count].start_freq = 16356 WMI_REG_RULE_START_FREQ_GET( 16357 wmi_reg_rule[count].freq_info); 16358 reg_rule_ptr[count].end_freq = 16359 WMI_REG_RULE_END_FREQ_GET( 16360 wmi_reg_rule[count].freq_info); 16361 reg_rule_ptr[count].max_bw = 16362 WMI_REG_RULE_MAX_BW_GET( 16363 wmi_reg_rule[count].bw_pwr_info); 16364 reg_rule_ptr[count].reg_power = 16365 WMI_REG_RULE_REG_POWER_GET( 16366 wmi_reg_rule[count].bw_pwr_info); 16367 reg_rule_ptr[count].ant_gain = 16368 WMI_REG_RULE_ANTENNA_GAIN_GET( 16369 wmi_reg_rule[count].bw_pwr_info); 16370 reg_rule_ptr[count].flags = 16371 WMI_REG_RULE_FLAGS_GET( 16372 wmi_reg_rule[count].flag_info); 16373 reg_rule_ptr[count].psd_flag = 16374 WMI_REG_RULE_PSD_FLAG_GET( 16375 wmi_reg_rule[count].psd_power_info); 16376 reg_rule_ptr[count].psd_eirp = 16377 WMI_REG_RULE_PSD_EIRP_GET( 16378 wmi_reg_rule[count].psd_power_info); 16379 } 16380 16381 return reg_rule_ptr; 16382 } 16383 #endif 16384 16385 static struct cur_reg_rule 16386 *create_reg_rules_from_wmi(uint32_t num_reg_rules, 16387 wmi_regulatory_rule_struct *wmi_reg_rule) 16388 { 16389 struct cur_reg_rule *reg_rule_ptr; 16390 uint32_t count; 16391 16392 if (!num_reg_rules) 16393 return NULL; 16394 16395 reg_rule_ptr = qdf_mem_malloc(num_reg_rules * 16396 sizeof(*reg_rule_ptr)); 16397 16398 if (!reg_rule_ptr) 16399 return NULL; 16400 16401 for (count = 0; count < num_reg_rules; count++) { 16402 reg_rule_ptr[count].start_freq = 16403 WMI_REG_RULE_START_FREQ_GET( 16404 wmi_reg_rule[count].freq_info); 16405 reg_rule_ptr[count].end_freq = 16406 WMI_REG_RULE_END_FREQ_GET( 16407 wmi_reg_rule[count].freq_info); 16408 reg_rule_ptr[count].max_bw = 16409 WMI_REG_RULE_MAX_BW_GET( 16410 wmi_reg_rule[count].bw_pwr_info); 16411 reg_rule_ptr[count].reg_power = 16412 WMI_REG_RULE_REG_POWER_GET( 16413 wmi_reg_rule[count].bw_pwr_info); 16414 reg_rule_ptr[count].ant_gain = 16415 WMI_REG_RULE_ANTENNA_GAIN_GET( 16416 wmi_reg_rule[count].bw_pwr_info); 16417 reg_rule_ptr[count].flags = 16418 WMI_REG_RULE_FLAGS_GET( 16419 wmi_reg_rule[count].flag_info); 16420 } 16421 16422 return reg_rule_ptr; 16423 } 16424 16425 static enum cc_setting_code wmi_reg_status_to_reg_status( 16426 WMI_REG_SET_CC_STATUS_CODE wmi_status_code) 16427 { 16428 if (wmi_status_code == WMI_REG_SET_CC_STATUS_PASS) { 16429 wmi_nofl_debug("REG_SET_CC_STATUS_PASS"); 16430 return REG_SET_CC_STATUS_PASS; 16431 } else if (wmi_status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) { 16432 wmi_nofl_debug("WMI_REG_CURRENT_ALPHA2_NOT_FOUND"); 16433 return REG_CURRENT_ALPHA2_NOT_FOUND; 16434 } else if (wmi_status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) { 16435 wmi_nofl_debug("WMI_REG_INIT_ALPHA2_NOT_FOUND"); 16436 return REG_INIT_ALPHA2_NOT_FOUND; 16437 } else if (wmi_status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) { 16438 wmi_nofl_debug("WMI_REG_SET_CC_CHANGE_NOT_ALLOWED"); 16439 return REG_SET_CC_CHANGE_NOT_ALLOWED; 16440 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) { 16441 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_NO_MEMORY"); 16442 return REG_SET_CC_STATUS_NO_MEMORY; 16443 } else if (wmi_status_code == WMI_REG_SET_CC_STATUS_FAIL) { 16444 wmi_nofl_debug("WMI_REG_SET_CC_STATUS_FAIL"); 16445 return REG_SET_CC_STATUS_FAIL; 16446 } 16447 16448 wmi_debug("Unknown reg status code from WMI"); 16449 return REG_SET_CC_STATUS_FAIL; 16450 } 16451 16452 #ifdef CONFIG_BAND_6GHZ 16453 /** 16454 * reg_print_ap_power_type_6ghz - Prints the AP Power type 16455 * @ap_type: 6ghz-AP Power type 16456 * 16457 * Return: void 16458 */ 16459 static void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16460 { 16461 switch (ap_type) { 16462 case REG_INDOOR_AP: 16463 wmi_nofl_debug("AP Power type %s", "LOW POWER INDOOR"); 16464 break; 16465 case REG_STANDARD_POWER_AP: 16466 wmi_nofl_debug("AP Power type %s", "STANDARD POWER"); 16467 break; 16468 case REG_VERY_LOW_POWER_AP: 16469 wmi_nofl_debug("AP Power type %s", "VERY LOW POWER INDOOR"); 16470 break; 16471 default: 16472 wmi_nofl_debug("Invalid AP Power type %u", ap_type); 16473 } 16474 } 16475 16476 /** 16477 * reg_print_6ghz_client_type - Prints the client type 16478 * @client_type: 6ghz-client type 16479 * 16480 * Return: void 16481 */ 16482 static void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16483 { 16484 switch (client_type) { 16485 case REG_DEFAULT_CLIENT: 16486 wmi_nofl_debug("Client type %s", "DEFAULT CLIENT"); 16487 break; 16488 case REG_SUBORDINATE_CLIENT: 16489 wmi_nofl_debug("Client type %s", "SUBORDINATE CLIENT"); 16490 break; 16491 default: 16492 wmi_nofl_debug("Invalid Client type %u", client_type); 16493 } 16494 } 16495 #else 16496 static inline void reg_print_ap_power_type_6ghz(enum reg_6g_ap_type ap_type) 16497 { 16498 } 16499 16500 static inline void reg_print_6ghz_client_type(enum reg_6g_client_type client_type) 16501 { 16502 } 16503 #endif /* CONFIG_BAND_6GHZ */ 16504 16505 #ifdef CONFIG_BAND_6GHZ 16506 16507 #ifdef CONFIG_REG_CLIENT 16508 #define MAX_NUM_FCC_RULES 2 16509 16510 /** 16511 * extract_ext_fcc_rules_from_wmi - extract fcc rules from WMI TLV 16512 * @num_fcc_rules: Number of FCC rules 16513 * @wmi_fcc_rule: WMI FCC rules TLV 16514 * 16515 * Return: fcc_rule_ptr 16516 */ 16517 static struct cur_fcc_rule 16518 *extract_ext_fcc_rules_from_wmi(uint32_t num_fcc_rules, 16519 wmi_regulatory_fcc_rule_struct *wmi_fcc_rule) 16520 { 16521 struct cur_fcc_rule *fcc_rule_ptr; 16522 uint32_t count; 16523 16524 if (!wmi_fcc_rule) 16525 return NULL; 16526 16527 fcc_rule_ptr = qdf_mem_malloc(num_fcc_rules * 16528 sizeof(*fcc_rule_ptr)); 16529 if (!fcc_rule_ptr) 16530 return NULL; 16531 16532 for (count = 0; count < num_fcc_rules; count++) { 16533 fcc_rule_ptr[count].center_freq = 16534 WMI_REG_FCC_RULE_CHAN_FREQ_GET( 16535 wmi_fcc_rule[count].freq_info); 16536 fcc_rule_ptr[count].tx_power = 16537 WMI_REG_FCC_RULE_FCC_TX_POWER_GET( 16538 wmi_fcc_rule[count].freq_info); 16539 } 16540 16541 return fcc_rule_ptr; 16542 } 16543 16544 /** 16545 * extract_reg_fcc_rules_tlv - Extract reg fcc rules TLV 16546 * @param_buf: Pointer to WMI params TLV 16547 * @ext_chan_list_event_hdr: Pointer to REG CHAN LIST CC EXT EVENT Fixed 16548 * Params TLV 16549 * @ext_wmi_reg_rule: Pointer to REG CHAN LIST CC EXT EVENT Reg Rules TLV 16550 * @ext_wmi_chan_priority: Pointer to REG CHAN LIST CC EXT EVENT Chan 16551 * Priority TLV 16552 * @evt_buf: Pointer to REG CHAN LIST CC EXT EVENT event buffer 16553 * @reg_info: Pointer to Regulatory Info 16554 * @len: Length of REG CHAN LIST CC EXT EVENT buffer 16555 * 16556 * Return: QDF_STATUS 16557 */ 16558 static QDF_STATUS extract_reg_fcc_rules_tlv( 16559 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16560 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16561 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16562 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16563 uint8_t *evt_buf, 16564 struct cur_regulatory_info *reg_info, 16565 uint32_t len) 16566 { 16567 int i; 16568 wmi_regulatory_fcc_rule_struct *ext_wmi_fcc_rule; 16569 16570 if (!param_buf) { 16571 wmi_err("invalid channel list event buf"); 16572 return QDF_STATUS_E_INVAL; 16573 } 16574 16575 reg_info->num_fcc_rules = 0; 16576 if (param_buf->reg_fcc_rule) { 16577 if (param_buf->num_reg_fcc_rule > MAX_NUM_FCC_RULES) { 16578 wmi_err("Number of fcc rules is greater than MAX_NUM_FCC_RULES"); 16579 return QDF_STATUS_E_INVAL; 16580 } 16581 16582 ext_wmi_fcc_rule = 16583 (wmi_regulatory_fcc_rule_struct *) 16584 ((uint8_t *)ext_chan_list_event_hdr + 16585 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16586 WMI_TLV_HDR_SIZE + 16587 sizeof(wmi_regulatory_rule_ext_struct) * 16588 param_buf->num_reg_rule_array + 16589 WMI_TLV_HDR_SIZE + 16590 sizeof(wmi_regulatory_chan_priority_struct) * 16591 param_buf->num_reg_chan_priority + 16592 WMI_TLV_HDR_SIZE); 16593 16594 reg_info->fcc_rules_ptr = extract_ext_fcc_rules_from_wmi( 16595 param_buf->num_reg_fcc_rule, 16596 ext_wmi_fcc_rule); 16597 16598 reg_info->num_fcc_rules = param_buf->num_reg_fcc_rule; 16599 } else { 16600 wmi_err("Fcc rules not sent by fw"); 16601 } 16602 16603 if (reg_info->fcc_rules_ptr) { 16604 for (i = 0; i < reg_info->num_fcc_rules; i++) { 16605 wmi_nofl_debug("FCC rule %d center_freq %d tx_power %d", 16606 i, reg_info->fcc_rules_ptr[i].center_freq, 16607 reg_info->fcc_rules_ptr[i].tx_power); 16608 } 16609 } 16610 return QDF_STATUS_SUCCESS; 16611 } 16612 #else 16613 static QDF_STATUS extract_reg_fcc_rules_tlv( 16614 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf, 16615 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr, 16616 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule, 16617 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority, 16618 uint8_t *evt_buf, 16619 struct cur_regulatory_info *reg_info, 16620 uint32_t len) 16621 { 16622 return QDF_STATUS_SUCCESS; 16623 } 16624 #endif 16625 16626 static QDF_STATUS extract_reg_chan_list_ext_update_event_tlv( 16627 wmi_unified_t wmi_handle, uint8_t *evt_buf, 16628 struct cur_regulatory_info *reg_info, uint32_t len) 16629 { 16630 uint32_t i, j, k; 16631 WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *param_buf; 16632 wmi_reg_chan_list_cc_event_ext_fixed_param *ext_chan_list_event_hdr; 16633 wmi_regulatory_rule_ext_struct *ext_wmi_reg_rule; 16634 wmi_regulatory_chan_priority_struct *ext_wmi_chan_priority; 16635 uint32_t num_2g_reg_rules, num_5g_reg_rules; 16636 uint32_t num_6g_reg_rules_ap[REG_CURRENT_MAX_AP_TYPE]; 16637 uint32_t *num_6g_reg_rules_client[REG_CURRENT_MAX_AP_TYPE]; 16638 uint32_t total_reg_rules = 0; 16639 QDF_STATUS status; 16640 16641 param_buf = (WMI_REG_CHAN_LIST_CC_EXT_EVENTID_param_tlvs *)evt_buf; 16642 if (!param_buf) { 16643 wmi_err("invalid channel list event buf"); 16644 return QDF_STATUS_E_FAILURE; 16645 } 16646 16647 ext_chan_list_event_hdr = param_buf->fixed_param; 16648 ext_wmi_chan_priority = param_buf->reg_chan_priority; 16649 16650 if (ext_wmi_chan_priority) 16651 reg_info->reg_6g_thresh_priority_freq = 16652 WMI_GET_BITS(ext_wmi_chan_priority->freq_info, 0, 16); 16653 reg_info->num_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; 16654 reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; 16655 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] = 16656 ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; 16657 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP] = 16658 ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; 16659 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] = 16660 ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; 16661 16662 wmi_debug("num reg rules from fw, AP SP %d, LPI %d, VLP %d", 16663 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16664 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16665 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16666 16667 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16668 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] = 16669 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; 16670 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][i] = 16671 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; 16672 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] = 16673 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; 16674 wmi_nofl_debug("client %d SP %d, LPI %d, VLP %d", i, 16675 ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i], 16676 ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i], 16677 ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]); 16678 } 16679 16680 num_2g_reg_rules = reg_info->num_2g_reg_rules; 16681 total_reg_rules += num_2g_reg_rules; 16682 num_5g_reg_rules = reg_info->num_5g_reg_rules; 16683 total_reg_rules += num_5g_reg_rules; 16684 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16685 num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; 16686 if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { 16687 wmi_err_rl("Invalid num_6g_reg_rules_ap: %u", 16688 num_6g_reg_rules_ap[i]); 16689 return QDF_STATUS_E_FAILURE; 16690 } 16691 total_reg_rules += num_6g_reg_rules_ap[i]; 16692 num_6g_reg_rules_client[i] = 16693 reg_info->num_6g_reg_rules_client[i]; 16694 } 16695 16696 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16697 total_reg_rules += 16698 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i]; 16699 total_reg_rules += num_6g_reg_rules_client[REG_INDOOR_AP][i]; 16700 total_reg_rules += 16701 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i]; 16702 if ((num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i] > 16703 MAX_6G_REG_RULES) || 16704 (num_6g_reg_rules_client[REG_INDOOR_AP][i] > 16705 MAX_6G_REG_RULES) || 16706 (num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i] > 16707 MAX_6G_REG_RULES)) { 16708 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", 16709 num_6g_reg_rules_client[REG_STANDARD_POWER_AP][i], 16710 num_6g_reg_rules_client[REG_INDOOR_AP][i], 16711 num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][i], 16712 i); 16713 return QDF_STATUS_E_FAILURE; 16714 } 16715 } 16716 16717 if (total_reg_rules != param_buf->num_reg_rule_array) { 16718 wmi_err_rl("Total reg rules %u does not match event params num reg rule %u", 16719 total_reg_rules, param_buf->num_reg_rule_array); 16720 return QDF_STATUS_E_FAILURE; 16721 } 16722 16723 if ((num_2g_reg_rules > MAX_REG_RULES) || 16724 (num_5g_reg_rules > MAX_REG_RULES)) { 16725 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 16726 num_2g_reg_rules, num_5g_reg_rules); 16727 return QDF_STATUS_E_FAILURE; 16728 } 16729 16730 if ((num_6g_reg_rules_ap[REG_STANDARD_POWER_AP] > MAX_6G_REG_RULES) || 16731 (num_6g_reg_rules_ap[REG_INDOOR_AP] > MAX_6G_REG_RULES) || 16732 (num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP] > MAX_6G_REG_RULES)) { 16733 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", 16734 num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16735 num_6g_reg_rules_ap[REG_INDOOR_AP], 16736 num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16737 return QDF_STATUS_E_FAILURE; 16738 } 16739 16740 if (param_buf->num_reg_rule_array > 16741 (WMI_SVC_MSG_MAX_SIZE - sizeof(*ext_chan_list_event_hdr)) / 16742 sizeof(*ext_wmi_reg_rule)) { 16743 wmi_err_rl("Invalid ext_num_reg_rule_array: %u", 16744 param_buf->num_reg_rule_array); 16745 return QDF_STATUS_E_FAILURE; 16746 } 16747 16748 qdf_mem_copy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, 16749 REG_ALPHA2_LEN); 16750 reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; 16751 reg_info->phybitmap = convert_phybitmap_tlv( 16752 ext_chan_list_event_hdr->phybitmap); 16753 reg_info->offload_enabled = true; 16754 reg_info->num_phy = ext_chan_list_event_hdr->num_phy; 16755 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 16756 wmi_handle, ext_chan_list_event_hdr->phy_id); 16757 reg_info->ctry_code = ext_chan_list_event_hdr->country_id; 16758 reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; 16759 16760 reg_info->status_code = 16761 wmi_reg_status_to_reg_status(ext_chan_list_event_hdr-> 16762 status_code); 16763 16764 reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; 16765 reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; 16766 reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; 16767 reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; 16768 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP] = 16769 ext_chan_list_event_hdr->min_bw_6g_ap_sp; 16770 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP] = 16771 ext_chan_list_event_hdr->max_bw_6g_ap_sp; 16772 reg_info->min_bw_6g_ap[REG_INDOOR_AP] = 16773 ext_chan_list_event_hdr->min_bw_6g_ap_lpi; 16774 reg_info->max_bw_6g_ap[REG_INDOOR_AP] = 16775 ext_chan_list_event_hdr->max_bw_6g_ap_lpi; 16776 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16777 ext_chan_list_event_hdr->min_bw_6g_ap_vlp; 16778 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP] = 16779 ext_chan_list_event_hdr->max_bw_6g_ap_vlp; 16780 16781 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16782 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16783 ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; 16784 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][i] = 16785 ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; 16786 reg_info->min_bw_6g_client[REG_INDOOR_AP][i] = 16787 ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; 16788 reg_info->max_bw_6g_client[REG_INDOOR_AP][i] = 16789 ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; 16790 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16791 ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; 16792 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][i] = 16793 ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; 16794 } 16795 16796 wmi_nofl_debug("num_phys = %u and phy_id = %u", 16797 reg_info->num_phy, reg_info->phy_id); 16798 16799 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", 16800 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 16801 reg_info->min_bw_2g, reg_info->max_bw_2g, reg_info->min_bw_5g, 16802 reg_info->max_bw_5g); 16803 16804 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", 16805 reg_info->min_bw_6g_ap[REG_STANDARD_POWER_AP], 16806 reg_info->max_bw_6g_ap[REG_STANDARD_POWER_AP], 16807 reg_info->min_bw_6g_ap[REG_INDOOR_AP], 16808 reg_info->max_bw_6g_ap[REG_INDOOR_AP], 16809 reg_info->min_bw_6g_ap[REG_VERY_LOW_POWER_AP], 16810 reg_info->max_bw_6g_ap[REG_VERY_LOW_POWER_AP]); 16811 16812 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", 16813 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16814 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16815 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16816 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16817 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT], 16818 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16819 16820 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", 16821 reg_info->min_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16822 reg_info->max_bw_6g_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16823 reg_info->min_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16824 reg_info->max_bw_6g_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16825 reg_info->min_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT], 16826 reg_info->max_bw_6g_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16827 16828 wmi_nofl_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 16829 num_2g_reg_rules, num_5g_reg_rules); 16830 16831 wmi_nofl_debug("num_6g_ap_sp_reg_rules %d num_6g_ap_lpi_reg_rules %d num_6g_ap_vlp_reg_rules %d", 16832 reg_info->num_6g_reg_rules_ap[REG_STANDARD_POWER_AP], 16833 reg_info->num_6g_reg_rules_ap[REG_INDOOR_AP], 16834 reg_info->num_6g_reg_rules_ap[REG_VERY_LOW_POWER_AP]); 16835 16836 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", 16837 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_DEFAULT_CLIENT], 16838 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_DEFAULT_CLIENT], 16839 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_DEFAULT_CLIENT]); 16840 16841 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", 16842 reg_info->num_6g_reg_rules_client[REG_STANDARD_POWER_AP][REG_SUBORDINATE_CLIENT], 16843 reg_info->num_6g_reg_rules_client[REG_INDOOR_AP][REG_SUBORDINATE_CLIENT], 16844 reg_info->num_6g_reg_rules_client[REG_VERY_LOW_POWER_AP][REG_SUBORDINATE_CLIENT]); 16845 16846 ext_wmi_reg_rule = 16847 (wmi_regulatory_rule_ext_struct *) 16848 ((uint8_t *)ext_chan_list_event_hdr + 16849 sizeof(wmi_reg_chan_list_cc_event_ext_fixed_param) + 16850 WMI_TLV_HDR_SIZE); 16851 reg_info->reg_rules_2g_ptr = 16852 create_ext_reg_rules_from_wmi(num_2g_reg_rules, 16853 ext_wmi_reg_rule); 16854 ext_wmi_reg_rule += num_2g_reg_rules; 16855 if (!num_2g_reg_rules) 16856 wmi_nofl_debug("No 2ghz reg rule"); 16857 for (i = 0; i < num_2g_reg_rules; i++) { 16858 if (!reg_info->reg_rules_2g_ptr) 16859 break; 16860 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", 16861 i, reg_info->reg_rules_2g_ptr[i].start_freq, 16862 reg_info->reg_rules_2g_ptr[i].end_freq, 16863 reg_info->reg_rules_2g_ptr[i].max_bw, 16864 reg_info->reg_rules_2g_ptr[i].reg_power, 16865 reg_info->reg_rules_2g_ptr[i].ant_gain, 16866 reg_info->reg_rules_2g_ptr[i].flags, 16867 reg_info->reg_rules_2g_ptr[i].psd_flag, 16868 reg_info->reg_rules_2g_ptr[i].psd_eirp); 16869 } 16870 reg_info->reg_rules_5g_ptr = 16871 create_ext_reg_rules_from_wmi(num_5g_reg_rules, 16872 ext_wmi_reg_rule); 16873 ext_wmi_reg_rule += num_5g_reg_rules; 16874 if (!num_5g_reg_rules) 16875 wmi_nofl_debug("No 5ghz reg rule"); 16876 for (i = 0; i < num_5g_reg_rules; i++) { 16877 if (!reg_info->reg_rules_5g_ptr) 16878 break; 16879 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", 16880 i, reg_info->reg_rules_5g_ptr[i].start_freq, 16881 reg_info->reg_rules_5g_ptr[i].end_freq, 16882 reg_info->reg_rules_5g_ptr[i].max_bw, 16883 reg_info->reg_rules_5g_ptr[i].reg_power, 16884 reg_info->reg_rules_5g_ptr[i].ant_gain, 16885 reg_info->reg_rules_5g_ptr[i].flags, 16886 reg_info->reg_rules_5g_ptr[i].psd_flag, 16887 reg_info->reg_rules_5g_ptr[i].psd_eirp); 16888 } 16889 16890 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 16891 reg_print_ap_power_type_6ghz(i); 16892 reg_info->reg_rules_6g_ap_ptr[i] = 16893 create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], 16894 ext_wmi_reg_rule); 16895 16896 ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; 16897 if (!num_6g_reg_rules_ap[i]) 16898 wmi_nofl_debug("No 6ghz reg rule"); 16899 for (j = 0; j < num_6g_reg_rules_ap[i]; j++) { 16900 if (!reg_info->reg_rules_6g_ap_ptr[i]) 16901 break; 16902 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", 16903 j, reg_info->reg_rules_6g_ap_ptr[i][j].start_freq, 16904 reg_info->reg_rules_6g_ap_ptr[i][j].end_freq, 16905 reg_info->reg_rules_6g_ap_ptr[i][j].max_bw, 16906 reg_info->reg_rules_6g_ap_ptr[i][j].reg_power, 16907 reg_info->reg_rules_6g_ap_ptr[i][j].ant_gain, 16908 reg_info->reg_rules_6g_ap_ptr[i][j].flags, 16909 reg_info->reg_rules_6g_ap_ptr[i][j].psd_flag, 16910 reg_info->reg_rules_6g_ap_ptr[i][j].psd_eirp); 16911 } 16912 } 16913 16914 for (j = 0; j < REG_CURRENT_MAX_AP_TYPE; j++) { 16915 reg_print_ap_power_type_6ghz(j); 16916 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16917 reg_print_6ghz_client_type(i); 16918 reg_info->reg_rules_6g_client_ptr[j][i] = 16919 create_ext_reg_rules_from_wmi( 16920 num_6g_reg_rules_client[j][i], 16921 ext_wmi_reg_rule); 16922 16923 ext_wmi_reg_rule += num_6g_reg_rules_client[j][i]; 16924 if (!num_6g_reg_rules_client[j][i]) 16925 wmi_nofl_debug("No 6ghz reg rule for [%d][%d]", j, i); 16926 for (k = 0; k < num_6g_reg_rules_client[j][i]; k++) { 16927 if (!reg_info->reg_rules_6g_client_ptr[j][i]) 16928 break; 16929 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", 16930 k, reg_info->reg_rules_6g_client_ptr[j][i][k].start_freq, 16931 reg_info->reg_rules_6g_client_ptr[j][i][k].end_freq, 16932 reg_info->reg_rules_6g_client_ptr[j][i][k].max_bw, 16933 reg_info->reg_rules_6g_client_ptr[j][i][k].reg_power, 16934 reg_info->reg_rules_6g_client_ptr[j][i][k].ant_gain, 16935 reg_info->reg_rules_6g_client_ptr[j][i][k].flags, 16936 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_flag, 16937 reg_info->reg_rules_6g_client_ptr[j][i][k].psd_eirp); 16938 } 16939 } 16940 } 16941 16942 reg_info->client_type = ext_chan_list_event_hdr->client_type; 16943 reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; 16944 reg_info->unspecified_ap_usable = 16945 ext_chan_list_event_hdr->unspecified_ap_usable; 16946 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP] = 16947 ext_chan_list_event_hdr->domain_code_6g_ap_sp; 16948 reg_info->domain_code_6g_ap[REG_INDOOR_AP] = 16949 ext_chan_list_event_hdr->domain_code_6g_ap_lpi; 16950 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP] = 16951 ext_chan_list_event_hdr->domain_code_6g_ap_vlp; 16952 16953 wmi_nofl_debug("client type %d, RNR TPE usable %d, unspecified AP usable %d, domain code AP SP %d, LPI %d, VLP %d", 16954 reg_info->client_type, reg_info->rnr_tpe_usable, 16955 reg_info->unspecified_ap_usable, 16956 reg_info->domain_code_6g_ap[REG_STANDARD_POWER_AP], 16957 reg_info->domain_code_6g_ap[REG_INDOOR_AP], 16958 reg_info->domain_code_6g_ap[REG_VERY_LOW_POWER_AP]); 16959 16960 for (i = 0; i < REG_MAX_CLIENT_TYPE; i++) { 16961 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i] = 16962 ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; 16963 reg_info->domain_code_6g_client[REG_INDOOR_AP][i] = 16964 ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; 16965 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i] = 16966 ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; 16967 wmi_nofl_debug("domain code client %d SP %d, LPI %d, VLP %d", i, 16968 reg_info->domain_code_6g_client[REG_STANDARD_POWER_AP][i], 16969 reg_info->domain_code_6g_client[REG_INDOOR_AP][i], 16970 reg_info->domain_code_6g_client[REG_VERY_LOW_POWER_AP][i]); 16971 } 16972 16973 reg_info->domain_code_6g_super_id = 16974 ext_chan_list_event_hdr->domain_code_6g_super_id; 16975 16976 status = extract_reg_fcc_rules_tlv(param_buf, ext_chan_list_event_hdr, 16977 ext_wmi_reg_rule, ext_wmi_chan_priority, 16978 evt_buf, reg_info, len); 16979 if (status != QDF_STATUS_SUCCESS) 16980 return status; 16981 16982 return QDF_STATUS_SUCCESS; 16983 } 16984 16985 #ifdef CONFIG_AFC_SUPPORT 16986 /** 16987 * copy_afc_chan_eirp_info() - Copy the channel EIRP object from 16988 * chan_eirp_power_info_hdr to the internal buffer chan_eirp_info. Since the 16989 * cfi and eirp is continuously filled in chan_eirp_power_info_hdr, there is 16990 * an index pointer required to store the current index of 16991 * chan_eirp_power_info_hdr, to fill into the chan_eirp_info object. 16992 * @chan_eirp_info: pointer to chan_eirp_info 16993 * @num_chans: Number of channels 16994 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 16995 * @index: Pointer to index 16996 * 16997 * Return: void 16998 */ 16999 static void 17000 copy_afc_chan_eirp_info(struct chan_eirp_obj *chan_eirp_info, 17001 uint8_t num_chans, 17002 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr, 17003 uint8_t *index) 17004 { 17005 uint8_t chan_idx; 17006 17007 for (chan_idx = 0; chan_idx < num_chans; chan_idx++, (*index)++) { 17008 chan_eirp_info[chan_idx].cfi = 17009 chan_eirp_power_info_hdr[*index].channel_cfi; 17010 chan_eirp_info[chan_idx].eirp_power = 17011 chan_eirp_power_info_hdr[*index].eirp_pwr; 17012 wmi_debug("Chan idx = %d chan freq idx = %d EIRP power = %d", 17013 chan_idx, 17014 chan_eirp_info[chan_idx].cfi, 17015 chan_eirp_info[chan_idx].eirp_power); 17016 } 17017 } 17018 17019 /** 17020 * copy_afc_chan_obj_info() - Copy the channel object from channel_info_hdr to 17021 * to the internal buffer afc_chan_info. 17022 * @afc_chan_info: pointer to afc_chan_info 17023 * @num_chan_objs: Number of channel objects 17024 * @channel_info_hdr: Pointer to channel_info_hdr 17025 * @chan_eirp_power_info_hdr: Pointer to chan_eirp_power_info_hdr 17026 * 17027 * Return: void 17028 */ 17029 static void 17030 copy_afc_chan_obj_info(struct afc_chan_obj *afc_chan_info, 17031 uint8_t num_chan_objs, 17032 wmi_6g_afc_channel_info *channel_info_hdr, 17033 wmi_afc_chan_eirp_power_info *chan_eirp_power_info_hdr) 17034 { 17035 uint8_t count; 17036 uint8_t src_pwr_index = 0; 17037 17038 for (count = 0; count < num_chan_objs; count++) { 17039 afc_chan_info[count].global_opclass = 17040 channel_info_hdr[count].global_operating_class; 17041 afc_chan_info[count].num_chans = 17042 channel_info_hdr[count].num_channels; 17043 wmi_debug("Chan object count = %d global opclasss = %d", 17044 count, 17045 afc_chan_info[count].global_opclass); 17046 wmi_debug("Number of Channel EIRP objects = %d", 17047 afc_chan_info[count].num_chans); 17048 17049 if (afc_chan_info[count].num_chans > 0) { 17050 struct chan_eirp_obj *chan_eirp_info; 17051 17052 chan_eirp_info = 17053 qdf_mem_malloc(afc_chan_info[count].num_chans * 17054 sizeof(*chan_eirp_info)); 17055 17056 if (!chan_eirp_info) 17057 return; 17058 17059 copy_afc_chan_eirp_info(chan_eirp_info, 17060 afc_chan_info[count].num_chans, 17061 chan_eirp_power_info_hdr, 17062 &src_pwr_index); 17063 afc_chan_info[count].chan_eirp_info = chan_eirp_info; 17064 } else { 17065 wmi_err("Number of channels is zero in object idx %d", 17066 count); 17067 } 17068 } 17069 } 17070 17071 static void copy_afc_freq_obj_info(struct afc_freq_obj *afc_freq_info, 17072 uint8_t num_freq_objs, 17073 wmi_6g_afc_frequency_info *freq_info_hdr) 17074 { 17075 uint8_t count; 17076 17077 for (count = 0; count < num_freq_objs; count++) { 17078 afc_freq_info[count].low_freq = 17079 WMI_REG_RULE_START_FREQ_GET(freq_info_hdr[count].freq_info); 17080 afc_freq_info[count].high_freq = 17081 WMI_REG_RULE_END_FREQ_GET(freq_info_hdr[count].freq_info); 17082 afc_freq_info[count].max_psd = 17083 freq_info_hdr[count].psd_power_info; 17084 wmi_debug("count = %d low_freq = %d high_freq = %d max_psd = %d", 17085 count, 17086 afc_freq_info[count].low_freq, 17087 afc_freq_info[count].high_freq, 17088 afc_freq_info[count].max_psd); 17089 } 17090 } 17091 17092 /** 17093 * copy_afc_event_fixed_hdr_power_info() - Copy the fixed header portion of 17094 * the power event info from the WMI AFC event buffer to the internal buffer 17095 * power_info. 17096 * @power_info: pointer to power_info 17097 * @afc_power_event_hdr: pointer to afc_power_event_hdr 17098 * 17099 * Return: void 17100 */ 17101 static void 17102 copy_afc_event_fixed_hdr_power_info( 17103 struct reg_fw_afc_power_event *power_info, 17104 wmi_afc_power_event_param *afc_power_event_hdr) 17105 { 17106 power_info->fw_status_code = afc_power_event_hdr->fw_status_code; 17107 power_info->resp_id = afc_power_event_hdr->resp_id; 17108 power_info->serv_resp_code = afc_power_event_hdr->afc_serv_resp_code; 17109 power_info->afc_wfa_version = 17110 WMI_AFC_WFA_MINOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 17111 power_info->afc_wfa_version |= 17112 WMI_AFC_WFA_MAJOR_VERSION_GET(afc_power_event_hdr->afc_wfa_version); 17113 17114 power_info->avail_exp_time_d = 17115 WMI_AVAIL_EXPIRY_TIME_DAY_GET(afc_power_event_hdr->avail_exp_time_d); 17116 power_info->avail_exp_time_d |= 17117 WMI_AVAIL_EXPIRY_TIME_MONTH_GET(afc_power_event_hdr->avail_exp_time_d); 17118 power_info->avail_exp_time_d |= 17119 WMI_AVAIL_EXPIRY_TIME_YEAR_GET(afc_power_event_hdr->avail_exp_time_d); 17120 17121 power_info->avail_exp_time_t = 17122 WMI_AVAIL_EXPIRY_TIME_SEC_GET(afc_power_event_hdr->avail_exp_time_t); 17123 power_info->avail_exp_time_t |= 17124 WMI_AVAIL_EXPIRY_TIME_MINUTE_GET(afc_power_event_hdr->avail_exp_time_t); 17125 power_info->avail_exp_time_t |= 17126 WMI_AVAIL_EXPIRY_TIME_HOUR_GET(afc_power_event_hdr->avail_exp_time_t); 17127 wmi_debug("FW status = %d resp_id = %d serv_resp_code = %d", 17128 power_info->fw_status_code, 17129 power_info->resp_id, 17130 power_info->serv_resp_code); 17131 wmi_debug("AFC version = %u exp_date = %u exp_time = %u", 17132 power_info->afc_wfa_version, 17133 power_info->avail_exp_time_d, 17134 power_info->avail_exp_time_t); 17135 } 17136 17137 /** 17138 * copy_power_event() - Copy the power event parameters from the AFC event 17139 * buffer to the power_info within the afc_info. 17140 * @afc_info: pointer to afc_info 17141 * @param_buf: pointer to param_buf 17142 * 17143 * Return: void 17144 */ 17145 static void copy_power_event(struct afc_regulatory_info *afc_info, 17146 WMI_AFC_EVENTID_param_tlvs *param_buf) 17147 { 17148 struct reg_fw_afc_power_event *power_info; 17149 wmi_afc_power_event_param *afc_power_event_hdr; 17150 struct afc_freq_obj *afc_freq_info; 17151 17152 power_info = qdf_mem_malloc(sizeof(*power_info)); 17153 17154 if (!power_info) 17155 return; 17156 17157 afc_power_event_hdr = param_buf->afc_power_event_param; 17158 copy_afc_event_fixed_hdr_power_info(power_info, afc_power_event_hdr); 17159 afc_info->power_info = power_info; 17160 17161 power_info->num_freq_objs = param_buf->num_freq_info_array; 17162 wmi_debug("Number of frequency objects = %d", 17163 power_info->num_freq_objs); 17164 if (power_info->num_freq_objs > 0) { 17165 wmi_6g_afc_frequency_info *freq_info_hdr; 17166 17167 freq_info_hdr = param_buf->freq_info_array; 17168 afc_freq_info = qdf_mem_malloc(power_info->num_freq_objs * 17169 sizeof(*afc_freq_info)); 17170 17171 if (!afc_freq_info) 17172 return; 17173 17174 copy_afc_freq_obj_info(afc_freq_info, power_info->num_freq_objs, 17175 freq_info_hdr); 17176 power_info->afc_freq_info = afc_freq_info; 17177 } else { 17178 wmi_err("Number of frequency objects is zero"); 17179 } 17180 17181 power_info->num_chan_objs = param_buf->num_channel_info_array; 17182 wmi_debug("Number of channel objects = %d", power_info->num_chan_objs); 17183 if (power_info->num_chan_objs > 0) { 17184 struct afc_chan_obj *afc_chan_info; 17185 wmi_6g_afc_channel_info *channel_info_hdr; 17186 17187 channel_info_hdr = param_buf->channel_info_array; 17188 afc_chan_info = qdf_mem_malloc(power_info->num_chan_objs * 17189 sizeof(*afc_chan_info)); 17190 17191 if (!afc_chan_info) 17192 return; 17193 17194 copy_afc_chan_obj_info(afc_chan_info, 17195 power_info->num_chan_objs, 17196 channel_info_hdr, 17197 param_buf->chan_eirp_power_info_array); 17198 power_info->afc_chan_info = afc_chan_info; 17199 } else { 17200 wmi_err("Number of channel objects is zero"); 17201 } 17202 } 17203 17204 static void copy_expiry_event(struct afc_regulatory_info *afc_info, 17205 WMI_AFC_EVENTID_param_tlvs *param_buf) 17206 { 17207 struct reg_afc_expiry_event *expiry_info; 17208 17209 expiry_info = qdf_mem_malloc(sizeof(*expiry_info)); 17210 17211 if (!expiry_info) 17212 return; 17213 17214 expiry_info->request_id = 17215 param_buf->expiry_event_param->request_id; 17216 expiry_info->event_subtype = 17217 param_buf->expiry_event_param->event_subtype; 17218 wmi_debug("Event subtype %d request ID %d", 17219 expiry_info->event_subtype, 17220 expiry_info->request_id); 17221 afc_info->expiry_info = expiry_info; 17222 } 17223 17224 /** 17225 * copy_afc_event_common_info() - Copy the phy_id and event_type parameters 17226 * in the AFC event. 'Common' indicates that these parameters are common for 17227 * WMI_AFC_EVENT_POWER_INFO and WMI_AFC_EVENT_TIMER_EXPIRY. 17228 * @wmi_handle: wmi handle 17229 * @afc_info: pointer to afc_info 17230 * @event_fixed_hdr: pointer to event_fixed_hdr 17231 * 17232 * Return: void 17233 */ 17234 static void 17235 copy_afc_event_common_info(wmi_unified_t wmi_handle, 17236 struct afc_regulatory_info *afc_info, 17237 wmi_afc_event_fixed_param *event_fixed_hdr) 17238 { 17239 afc_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17240 wmi_handle, event_fixed_hdr->phy_id); 17241 wmi_debug("phy_id %d", afc_info->phy_id); 17242 afc_info->event_type = event_fixed_hdr->event_type; 17243 } 17244 17245 static QDF_STATUS extract_afc_event_tlv(wmi_unified_t wmi_handle, 17246 uint8_t *evt_buf, 17247 struct afc_regulatory_info *afc_info, 17248 uint32_t len) 17249 { 17250 WMI_AFC_EVENTID_param_tlvs *param_buf; 17251 wmi_afc_event_fixed_param *event_fixed_hdr; 17252 17253 param_buf = (WMI_AFC_EVENTID_param_tlvs *)evt_buf; 17254 if (!param_buf) { 17255 wmi_err("Invalid AFC event buf"); 17256 return QDF_STATUS_E_FAILURE; 17257 } 17258 17259 event_fixed_hdr = param_buf->fixed_param; 17260 copy_afc_event_common_info(wmi_handle, afc_info, event_fixed_hdr); 17261 wmi_debug("AFC event type %d received", afc_info->event_type); 17262 17263 switch (afc_info->event_type) { 17264 case WMI_AFC_EVENT_POWER_INFO: 17265 copy_power_event(afc_info, param_buf); 17266 break; 17267 case WMI_AFC_EVENT_TIMER_EXPIRY: 17268 copy_expiry_event(afc_info, param_buf); 17269 return QDF_STATUS_SUCCESS; 17270 default: 17271 wmi_err("Invalid event type"); 17272 return QDF_STATUS_E_FAILURE; 17273 } 17274 17275 return QDF_STATUS_SUCCESS; 17276 } 17277 #endif 17278 #endif 17279 17280 static QDF_STATUS extract_reg_chan_list_update_event_tlv( 17281 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17282 struct cur_regulatory_info *reg_info, uint32_t len) 17283 { 17284 uint32_t i; 17285 WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *param_buf; 17286 wmi_reg_chan_list_cc_event_fixed_param *chan_list_event_hdr; 17287 wmi_regulatory_rule_struct *wmi_reg_rule; 17288 uint32_t num_2g_reg_rules, num_5g_reg_rules; 17289 17290 wmi_debug("processing regulatory channel list"); 17291 17292 param_buf = (WMI_REG_CHAN_LIST_CC_EVENTID_param_tlvs *)evt_buf; 17293 if (!param_buf) { 17294 wmi_err("invalid channel list event buf"); 17295 return QDF_STATUS_E_FAILURE; 17296 } 17297 17298 chan_list_event_hdr = param_buf->fixed_param; 17299 17300 reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; 17301 reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; 17302 num_2g_reg_rules = reg_info->num_2g_reg_rules; 17303 num_5g_reg_rules = reg_info->num_5g_reg_rules; 17304 if ((num_2g_reg_rules > MAX_REG_RULES) || 17305 (num_5g_reg_rules > MAX_REG_RULES) || 17306 (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || 17307 (num_2g_reg_rules + num_5g_reg_rules != 17308 param_buf->num_reg_rule_array)) { 17309 wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", 17310 num_2g_reg_rules, num_5g_reg_rules); 17311 return QDF_STATUS_E_FAILURE; 17312 } 17313 if (param_buf->num_reg_rule_array > 17314 (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / 17315 sizeof(*wmi_reg_rule)) { 17316 wmi_err_rl("Invalid num_reg_rule_array: %u", 17317 param_buf->num_reg_rule_array); 17318 return QDF_STATUS_E_FAILURE; 17319 } 17320 17321 qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), 17322 REG_ALPHA2_LEN); 17323 reg_info->dfs_region = chan_list_event_hdr->dfs_region; 17324 reg_info->phybitmap = convert_phybitmap_tlv( 17325 chan_list_event_hdr->phybitmap); 17326 reg_info->offload_enabled = true; 17327 reg_info->num_phy = chan_list_event_hdr->num_phy; 17328 reg_info->phy_id = wmi_handle->ops->convert_phy_id_target_to_host( 17329 wmi_handle, chan_list_event_hdr->phy_id); 17330 reg_info->ctry_code = chan_list_event_hdr->country_id; 17331 reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; 17332 17333 reg_info->status_code = 17334 wmi_reg_status_to_reg_status(chan_list_event_hdr->status_code); 17335 17336 reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; 17337 reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; 17338 reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; 17339 reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; 17340 17341 wmi_debug("num_phys = %u and phy_id = %u", 17342 reg_info->num_phy, reg_info->phy_id); 17343 17344 wmi_debug("cc %s dfs_region %d reg_dmn_pair %x BW: min_2g %d max_2g %d min_5g %d max_5g %d", 17345 reg_info->alpha2, reg_info->dfs_region, reg_info->reg_dmn_pair, 17346 reg_info->min_bw_2g, reg_info->max_bw_2g, 17347 reg_info->min_bw_5g, reg_info->max_bw_5g); 17348 17349 wmi_debug("num_2g_reg_rules %d num_5g_reg_rules %d", 17350 num_2g_reg_rules, num_5g_reg_rules); 17351 wmi_reg_rule = 17352 (wmi_regulatory_rule_struct *)((uint8_t *)chan_list_event_hdr 17353 + sizeof(wmi_reg_chan_list_cc_event_fixed_param) 17354 + WMI_TLV_HDR_SIZE); 17355 reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, 17356 wmi_reg_rule); 17357 wmi_reg_rule += num_2g_reg_rules; 17358 if (!num_2g_reg_rules) 17359 wmi_nofl_debug("No 2ghz reg rule"); 17360 for (i = 0; i < num_2g_reg_rules; i++) { 17361 if (!reg_info->reg_rules_2g_ptr) 17362 break; 17363 wmi_nofl_debug("2 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17364 i, reg_info->reg_rules_2g_ptr[i].start_freq, 17365 reg_info->reg_rules_2g_ptr[i].end_freq, 17366 reg_info->reg_rules_2g_ptr[i].max_bw, 17367 reg_info->reg_rules_2g_ptr[i].reg_power, 17368 reg_info->reg_rules_2g_ptr[i].ant_gain, 17369 reg_info->reg_rules_2g_ptr[i].flags); 17370 } 17371 17372 reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, 17373 wmi_reg_rule); 17374 if (!num_5g_reg_rules) 17375 wmi_nofl_debug("No 5ghz reg rule"); 17376 for (i = 0; i < num_5g_reg_rules; i++) { 17377 if (!reg_info->reg_rules_5g_ptr) 17378 break; 17379 wmi_nofl_debug("5 GHz rule %u start freq %u end freq %u max_bw %u reg_power %u ant_gain %u flags %u", 17380 i, reg_info->reg_rules_5g_ptr[i].start_freq, 17381 reg_info->reg_rules_5g_ptr[i].end_freq, 17382 reg_info->reg_rules_5g_ptr[i].max_bw, 17383 reg_info->reg_rules_5g_ptr[i].reg_power, 17384 reg_info->reg_rules_5g_ptr[i].ant_gain, 17385 reg_info->reg_rules_5g_ptr[i].flags); 17386 } 17387 17388 wmi_debug("processed regulatory channel list"); 17389 17390 return QDF_STATUS_SUCCESS; 17391 } 17392 17393 static QDF_STATUS extract_reg_11d_new_country_event_tlv( 17394 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17395 struct reg_11d_new_country *reg_11d_country, uint32_t len) 17396 { 17397 wmi_11d_new_country_event_fixed_param *reg_11d_country_event; 17398 WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf; 17399 17400 param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf; 17401 if (!param_buf) { 17402 wmi_err("invalid 11d country event buf"); 17403 return QDF_STATUS_E_FAILURE; 17404 } 17405 17406 reg_11d_country_event = param_buf->fixed_param; 17407 17408 qdf_mem_copy(reg_11d_country->alpha2, 17409 ®_11d_country_event->new_alpha2, REG_ALPHA2_LEN); 17410 reg_11d_country->alpha2[REG_ALPHA2_LEN] = '\0'; 17411 17412 wmi_debug("processed 11d country event, new cc %s", 17413 reg_11d_country->alpha2); 17414 17415 return QDF_STATUS_SUCCESS; 17416 } 17417 17418 static QDF_STATUS extract_reg_ch_avoid_event_tlv( 17419 wmi_unified_t wmi_handle, uint8_t *evt_buf, 17420 struct ch_avoid_ind_type *ch_avoid_ind, uint32_t len) 17421 { 17422 wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; 17423 wmi_avoid_freq_range_desc *afr_desc; 17424 uint32_t num_freq_ranges, freq_range_idx; 17425 WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = 17426 (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) evt_buf; 17427 17428 if (!param_buf) { 17429 wmi_err("Invalid channel avoid event buffer"); 17430 return QDF_STATUS_E_INVAL; 17431 } 17432 17433 afr_fixed_param = param_buf->fixed_param; 17434 if (!afr_fixed_param) { 17435 wmi_err("Invalid channel avoid event fixed param buffer"); 17436 return QDF_STATUS_E_INVAL; 17437 } 17438 17439 if (!ch_avoid_ind) { 17440 wmi_err("Invalid channel avoid indication buffer"); 17441 return QDF_STATUS_E_INVAL; 17442 } 17443 if (param_buf->num_avd_freq_range < afr_fixed_param->num_freq_ranges) { 17444 wmi_err("no.of freq ranges exceeded the limit"); 17445 return QDF_STATUS_E_INVAL; 17446 } 17447 num_freq_ranges = (afr_fixed_param->num_freq_ranges > 17448 CH_AVOID_MAX_RANGE) ? CH_AVOID_MAX_RANGE : 17449 afr_fixed_param->num_freq_ranges; 17450 17451 wmi_debug("Channel avoid event received with %d ranges", 17452 num_freq_ranges); 17453 17454 ch_avoid_ind->ch_avoid_range_cnt = num_freq_ranges; 17455 afr_desc = (wmi_avoid_freq_range_desc *)(param_buf->avd_freq_range); 17456 for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; 17457 freq_range_idx++) { 17458 ch_avoid_ind->avoid_freq_range[freq_range_idx].start_freq = 17459 afr_desc->start_freq; 17460 ch_avoid_ind->avoid_freq_range[freq_range_idx].end_freq = 17461 afr_desc->end_freq; 17462 wmi_debug("range %d tlv id %u, start freq %u, end freq %u", 17463 freq_range_idx, afr_desc->tlv_header, 17464 afr_desc->start_freq, afr_desc->end_freq); 17465 afr_desc++; 17466 } 17467 17468 return QDF_STATUS_SUCCESS; 17469 } 17470 17471 #ifdef DFS_COMPONENT_ENABLE 17472 /** 17473 * extract_dfs_cac_complete_event_tlv() - extract cac complete event 17474 * @wmi_handle: wma handle 17475 * @evt_buf: event buffer 17476 * @vdev_id: vdev id 17477 * @len: length of buffer 17478 * 17479 * Return: QDF_STATUS_SUCCESS for success or error code 17480 */ 17481 static QDF_STATUS extract_dfs_cac_complete_event_tlv(wmi_unified_t wmi_handle, 17482 uint8_t *evt_buf, 17483 uint32_t *vdev_id, 17484 uint32_t len) 17485 { 17486 WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17487 wmi_vdev_dfs_cac_complete_event_fixed_param *cac_event; 17488 17489 param_tlvs = (WMI_VDEV_DFS_CAC_COMPLETE_EVENTID_param_tlvs *) evt_buf; 17490 if (!param_tlvs) { 17491 wmi_err("invalid cac complete event buf"); 17492 return QDF_STATUS_E_FAILURE; 17493 } 17494 17495 cac_event = param_tlvs->fixed_param; 17496 *vdev_id = cac_event->vdev_id; 17497 wmi_debug("processed cac complete event vdev %d", *vdev_id); 17498 17499 return QDF_STATUS_SUCCESS; 17500 } 17501 17502 /** 17503 * extract_dfs_ocac_complete_event_tlv() - extract cac complete event 17504 * @wmi_handle: wma handle 17505 * @evt_buf: event buffer 17506 * @param: extracted event 17507 * 17508 * Return: QDF_STATUS_SUCCESS for success or error code 17509 */ 17510 static QDF_STATUS 17511 extract_dfs_ocac_complete_event_tlv(wmi_unified_t wmi_handle, 17512 uint8_t *evt_buf, 17513 struct vdev_adfs_complete_status *param) 17514 { 17515 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *param_tlvs; 17516 wmi_vdev_adfs_ocac_complete_event_fixed_param *ocac_complete_status; 17517 17518 param_tlvs = (WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID_param_tlvs *)evt_buf; 17519 if (!param_tlvs) { 17520 wmi_err("invalid ocac complete event buf"); 17521 return QDF_STATUS_E_FAILURE; 17522 } 17523 17524 if (!param_tlvs->fixed_param) { 17525 wmi_err("invalid param_tlvs->fixed_param"); 17526 return QDF_STATUS_E_FAILURE; 17527 } 17528 17529 ocac_complete_status = param_tlvs->fixed_param; 17530 param->vdev_id = ocac_complete_status->vdev_id; 17531 param->chan_freq = ocac_complete_status->chan_freq; 17532 param->center_freq1 = ocac_complete_status->center_freq1; 17533 param->center_freq2 = ocac_complete_status->center_freq2; 17534 param->ocac_status = ocac_complete_status->status; 17535 param->chan_width = ocac_complete_status->chan_width; 17536 wmi_debug("processed ocac complete event vdev %d" 17537 " agile chan %d %d width %d status %d", 17538 param->vdev_id, 17539 param->center_freq1, 17540 param->center_freq2, 17541 param->chan_width, 17542 param->ocac_status); 17543 17544 return QDF_STATUS_SUCCESS; 17545 } 17546 17547 /** 17548 * extract_dfs_radar_detection_event_tlv() - extract radar found event 17549 * @wmi_handle: wma handle 17550 * @evt_buf: event buffer 17551 * @radar_found: radar found event info 17552 * @len: length of buffer 17553 * 17554 * Return: QDF_STATUS_SUCCESS for success or error code 17555 */ 17556 static QDF_STATUS extract_dfs_radar_detection_event_tlv( 17557 wmi_unified_t wmi_handle, 17558 uint8_t *evt_buf, 17559 struct radar_found_info *radar_found, 17560 uint32_t len) 17561 { 17562 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *param_tlv; 17563 wmi_pdev_dfs_radar_detection_event_fixed_param *radar_event; 17564 17565 param_tlv = (WMI_PDEV_DFS_RADAR_DETECTION_EVENTID_param_tlvs *) evt_buf; 17566 if (!param_tlv) { 17567 wmi_err("invalid radar detection event buf"); 17568 return QDF_STATUS_E_FAILURE; 17569 } 17570 17571 radar_event = param_tlv->fixed_param; 17572 17573 radar_found->pdev_id = convert_target_pdev_id_to_host_pdev_id( 17574 wmi_handle, 17575 radar_event->pdev_id); 17576 17577 if (radar_found->pdev_id == WMI_HOST_PDEV_ID_INVALID) 17578 return QDF_STATUS_E_FAILURE; 17579 17580 qdf_mem_zero(radar_found, sizeof(struct radar_found_info)); 17581 radar_found->detection_mode = radar_event->detection_mode; 17582 radar_found->chan_freq = radar_event->chan_freq; 17583 radar_found->chan_width = radar_event->chan_width; 17584 radar_found->detector_id = radar_event->detector_id; 17585 radar_found->segment_id = radar_event->segment_id; 17586 radar_found->timestamp = radar_event->timestamp; 17587 radar_found->is_chirp = radar_event->is_chirp; 17588 radar_found->freq_offset = radar_event->freq_offset; 17589 radar_found->sidx = radar_event->sidx; 17590 17591 if (is_service_enabled_tlv(wmi_handle, 17592 WMI_SERVICE_RADAR_FLAGS_SUPPORT)) { 17593 WMI_RADAR_FLAGS *radar_flags; 17594 17595 radar_flags = param_tlv->radar_flags; 17596 if (radar_flags) { 17597 radar_found->is_full_bw_nol = 17598 WMI_RADAR_FLAGS_FULL_BW_NOL_GET(radar_flags->flags); 17599 wmi_debug("Is full bw nol %d", 17600 radar_found->is_full_bw_nol); 17601 } 17602 } 17603 17604 wmi_debug("processed radar found event pdev %d," 17605 "Radar Event Info:pdev_id %d,timestamp %d,chan_freq (dur) %d," 17606 "chan_width (RSSI) %d,detector_id (false_radar) %d," 17607 "freq_offset (radar_check) %d,segment_id %d,sidx %d," 17608 "is_chirp %d,detection mode %d", 17609 radar_event->pdev_id, radar_found->pdev_id, 17610 radar_event->timestamp, radar_event->chan_freq, 17611 radar_event->chan_width, radar_event->detector_id, 17612 radar_event->freq_offset, radar_event->segment_id, 17613 radar_event->sidx, radar_event->is_chirp, 17614 radar_event->detection_mode); 17615 17616 return QDF_STATUS_SUCCESS; 17617 } 17618 17619 #ifdef MOBILE_DFS_SUPPORT 17620 /** 17621 * extract_wlan_radar_event_info_tlv() - extract radar pulse event 17622 * @wmi_handle: wma handle 17623 * @evt_buf: event buffer 17624 * @wlan_radar_event: Pointer to struct radar_event_info 17625 * @len: length of buffer 17626 * 17627 * Return: QDF_STATUS 17628 */ 17629 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17630 wmi_unified_t wmi_handle, 17631 uint8_t *evt_buf, 17632 struct radar_event_info *wlan_radar_event, 17633 uint32_t len) 17634 { 17635 WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlv; 17636 wmi_dfs_radar_event_fixed_param *radar_event; 17637 17638 param_tlv = (WMI_DFS_RADAR_EVENTID_param_tlvs *)evt_buf; 17639 if (!param_tlv) { 17640 wmi_err("invalid wlan radar event buf"); 17641 return QDF_STATUS_E_FAILURE; 17642 } 17643 17644 radar_event = param_tlv->fixed_param; 17645 wlan_radar_event->pulse_is_chirp = radar_event->pulse_is_chirp; 17646 wlan_radar_event->pulse_center_freq = radar_event->pulse_center_freq; 17647 wlan_radar_event->pulse_duration = radar_event->pulse_duration; 17648 wlan_radar_event->rssi = radar_event->rssi; 17649 wlan_radar_event->pulse_detect_ts = radar_event->pulse_detect_ts; 17650 wlan_radar_event->upload_fullts_high = radar_event->upload_fullts_high; 17651 wlan_radar_event->upload_fullts_low = radar_event->upload_fullts_low; 17652 wlan_radar_event->peak_sidx = radar_event->peak_sidx; 17653 wlan_radar_event->delta_peak = radar_event->pulse_delta_peak; 17654 wlan_radar_event->delta_diff = radar_event->pulse_delta_diff; 17655 if (radar_event->pulse_flags & 17656 WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) { 17657 wlan_radar_event->is_psidx_diff_valid = true; 17658 wlan_radar_event->psidx_diff = radar_event->psidx_diff; 17659 } else { 17660 wlan_radar_event->is_psidx_diff_valid = false; 17661 } 17662 17663 wlan_radar_event->pdev_id = radar_event->pdev_id; 17664 17665 return QDF_STATUS_SUCCESS; 17666 } 17667 #else 17668 static QDF_STATUS extract_wlan_radar_event_info_tlv( 17669 wmi_unified_t wmi_handle, 17670 uint8_t *evt_buf, 17671 struct radar_event_info *wlan_radar_event, 17672 uint32_t len) 17673 { 17674 return QDF_STATUS_SUCCESS; 17675 } 17676 #endif 17677 #endif 17678 17679 /** 17680 * send_get_rcpi_cmd_tlv() - send request for rcpi value 17681 * @wmi_handle: wmi handle 17682 * @get_rcpi_param: rcpi params 17683 * 17684 * Return: QDF status 17685 */ 17686 static QDF_STATUS send_get_rcpi_cmd_tlv(wmi_unified_t wmi_handle, 17687 struct rcpi_req *get_rcpi_param) 17688 { 17689 wmi_buf_t buf; 17690 wmi_request_rcpi_cmd_fixed_param *cmd; 17691 uint8_t len = sizeof(wmi_request_rcpi_cmd_fixed_param); 17692 17693 buf = wmi_buf_alloc(wmi_handle, len); 17694 if (!buf) 17695 return QDF_STATUS_E_NOMEM; 17696 17697 cmd = (wmi_request_rcpi_cmd_fixed_param *) wmi_buf_data(buf); 17698 WMITLV_SET_HDR(&cmd->tlv_header, 17699 WMITLV_TAG_STRUC_wmi_request_rcpi_cmd_fixed_param, 17700 WMITLV_GET_STRUCT_TLVLEN 17701 (wmi_request_rcpi_cmd_fixed_param)); 17702 17703 cmd->vdev_id = get_rcpi_param->vdev_id; 17704 WMI_CHAR_ARRAY_TO_MAC_ADDR(get_rcpi_param->mac_addr, 17705 &cmd->peer_macaddr); 17706 17707 switch (get_rcpi_param->measurement_type) { 17708 17709 case RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17710 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17711 break; 17712 17713 case RCPI_MEASUREMENT_TYPE_AVG_DATA: 17714 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA; 17715 break; 17716 17717 case RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17718 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17719 break; 17720 17721 case RCPI_MEASUREMENT_TYPE_LAST_DATA: 17722 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA; 17723 break; 17724 17725 default: 17726 /* 17727 * invalid rcpi measurement type, fall back to 17728 * RCPI_MEASUREMENT_TYPE_AVG_MGMT 17729 */ 17730 cmd->measurement_type = WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17731 break; 17732 } 17733 wmi_debug("RCPI REQ VDEV_ID:%d-->", cmd->vdev_id); 17734 wmi_mtrace(WMI_REQUEST_RCPI_CMDID, cmd->vdev_id, 0); 17735 if (wmi_unified_cmd_send(wmi_handle, buf, len, 17736 WMI_REQUEST_RCPI_CMDID)) { 17737 17738 wmi_err("Failed to send WMI_REQUEST_RCPI_CMDID"); 17739 wmi_buf_free(buf); 17740 return QDF_STATUS_E_FAILURE; 17741 } 17742 17743 return QDF_STATUS_SUCCESS; 17744 } 17745 17746 /** 17747 * extract_rcpi_response_event_tlv() - Extract RCPI event params 17748 * @wmi_handle: wmi handle 17749 * @evt_buf: pointer to event buffer 17750 * @res: pointer to hold rcpi response from firmware 17751 * 17752 * Return: QDF_STATUS_SUCCESS for successful event parse 17753 * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE 17754 */ 17755 static QDF_STATUS 17756 extract_rcpi_response_event_tlv(wmi_unified_t wmi_handle, 17757 void *evt_buf, struct rcpi_res *res) 17758 { 17759 WMI_UPDATE_RCPI_EVENTID_param_tlvs *param_buf; 17760 wmi_update_rcpi_event_fixed_param *event; 17761 17762 param_buf = (WMI_UPDATE_RCPI_EVENTID_param_tlvs *)evt_buf; 17763 if (!param_buf) { 17764 wmi_err("Invalid rcpi event"); 17765 return QDF_STATUS_E_INVAL; 17766 } 17767 17768 event = param_buf->fixed_param; 17769 res->vdev_id = event->vdev_id; 17770 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, res->mac_addr); 17771 17772 switch (event->measurement_type) { 17773 17774 case WMI_RCPI_MEASUREMENT_TYPE_AVG_MGMT: 17775 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_MGMT; 17776 break; 17777 17778 case WMI_RCPI_MEASUREMENT_TYPE_AVG_DATA: 17779 res->measurement_type = RCPI_MEASUREMENT_TYPE_AVG_DATA; 17780 break; 17781 17782 case WMI_RCPI_MEASUREMENT_TYPE_LAST_MGMT: 17783 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_MGMT; 17784 break; 17785 17786 case WMI_RCPI_MEASUREMENT_TYPE_LAST_DATA: 17787 res->measurement_type = RCPI_MEASUREMENT_TYPE_LAST_DATA; 17788 break; 17789 17790 default: 17791 wmi_err("Invalid rcpi measurement type from firmware"); 17792 res->measurement_type = RCPI_MEASUREMENT_TYPE_INVALID; 17793 return QDF_STATUS_E_FAILURE; 17794 } 17795 17796 if (event->status) 17797 return QDF_STATUS_E_FAILURE; 17798 else 17799 return QDF_STATUS_SUCCESS; 17800 } 17801 17802 /** 17803 * convert_host_pdev_id_to_target_pdev_id_legacy() - Convert pdev_id from 17804 * host to target defines. For legacy there is not conversion 17805 * required. Just return pdev_id as it is. 17806 * @wmi_handle: handle to WMI. 17807 * @pdev_id: host pdev_id to be converted. 17808 * Return: target pdev_id after conversion. 17809 */ 17810 static uint32_t convert_host_pdev_id_to_target_pdev_id_legacy( 17811 wmi_unified_t wmi_handle, 17812 uint32_t pdev_id) 17813 { 17814 if (pdev_id == WMI_HOST_PDEV_ID_SOC) 17815 return WMI_PDEV_ID_SOC; 17816 17817 /*No conversion required*/ 17818 return pdev_id; 17819 } 17820 17821 /** 17822 * convert_target_pdev_id_to_host_pdev_id_legacy() - Convert pdev_id from 17823 * target to host defines. For legacy there is not conversion 17824 * required. Just return pdev_id as it is. 17825 * @wmi_handle: handle to WMI. 17826 * @pdev_id: target pdev_id to be converted. 17827 * Return: host pdev_id after conversion. 17828 */ 17829 static uint32_t convert_target_pdev_id_to_host_pdev_id_legacy( 17830 wmi_unified_t wmi_handle, 17831 uint32_t pdev_id) 17832 { 17833 /*No conversion required*/ 17834 return pdev_id; 17835 } 17836 17837 /** 17838 * convert_host_phy_id_to_target_phy_id_legacy() - Convert phy_id from 17839 * host to target defines. For legacy there is not conversion 17840 * required. Just return phy_id as it is. 17841 * @wmi_handle: handle to WMI. 17842 * @phy_id: host phy_id to be converted. 17843 * 17844 * Return: target phy_id after conversion. 17845 */ 17846 static uint32_t convert_host_phy_id_to_target_phy_id_legacy( 17847 wmi_unified_t wmi_handle, 17848 uint32_t phy_id) 17849 { 17850 /*No conversion required*/ 17851 return phy_id; 17852 } 17853 17854 /** 17855 * convert_target_phy_id_to_host_phy_id_legacy() - Convert phy_id from 17856 * target to host defines. For legacy there is not conversion 17857 * required. Just return phy_id as it is. 17858 * @wmi_handle: handle to WMI. 17859 * @phy_id: target phy_id to be converted. 17860 * 17861 * Return: host phy_id after conversion. 17862 */ 17863 static uint32_t convert_target_phy_id_to_host_phy_id_legacy( 17864 wmi_unified_t wmi_handle, 17865 uint32_t phy_id) 17866 { 17867 /*No conversion required*/ 17868 return phy_id; 17869 } 17870 17871 /** 17872 * send_set_country_cmd_tlv() - WMI scan channel list function 17873 * @wmi_handle: handle to WMI. 17874 * @params: pointer to hold scan channel list parameter 17875 * 17876 * Return: QDF_STATUS_SUCCESS for success or error code 17877 */ 17878 static QDF_STATUS send_set_country_cmd_tlv(wmi_unified_t wmi_handle, 17879 struct set_country *params) 17880 { 17881 wmi_buf_t buf; 17882 QDF_STATUS qdf_status; 17883 wmi_set_current_country_cmd_fixed_param *cmd; 17884 uint16_t len = sizeof(*cmd); 17885 uint8_t pdev_id = params->pdev_id; 17886 17887 buf = wmi_buf_alloc(wmi_handle, len); 17888 if (!buf) { 17889 qdf_status = QDF_STATUS_E_NOMEM; 17890 goto end; 17891 } 17892 17893 cmd = (wmi_set_current_country_cmd_fixed_param *)wmi_buf_data(buf); 17894 WMITLV_SET_HDR(&cmd->tlv_header, 17895 WMITLV_TAG_STRUC_wmi_set_current_country_cmd_fixed_param, 17896 WMITLV_GET_STRUCT_TLVLEN 17897 (wmi_set_current_country_cmd_fixed_param)); 17898 17899 cmd->pdev_id = wmi_handle->ops->convert_host_pdev_id_to_target( 17900 wmi_handle, 17901 pdev_id); 17902 wmi_debug("setting current country to %s and target pdev_id = %u", 17903 params->country, cmd->pdev_id); 17904 17905 qdf_mem_copy((uint8_t *)&cmd->new_alpha2, params->country, 3); 17906 17907 wmi_mtrace(WMI_SET_CURRENT_COUNTRY_CMDID, NO_SESSION, 0); 17908 qdf_status = wmi_unified_cmd_send(wmi_handle, 17909 buf, len, WMI_SET_CURRENT_COUNTRY_CMDID); 17910 17911 if (QDF_IS_STATUS_ERROR(qdf_status)) { 17912 wmi_err("Failed to send WMI_SET_CURRENT_COUNTRY_CMDID"); 17913 wmi_buf_free(buf); 17914 } 17915 17916 end: 17917 return qdf_status; 17918 } 17919 17920 #define WMI_REG_COUNTRY_ALPHA_SET(alpha, val0, val1, val2) do { \ 17921 WMI_SET_BITS(alpha, 0, 8, val0); \ 17922 WMI_SET_BITS(alpha, 8, 8, val1); \ 17923 WMI_SET_BITS(alpha, 16, 8, val2); \ 17924 } while (0) 17925 17926 static QDF_STATUS send_user_country_code_cmd_tlv(wmi_unified_t wmi_handle, 17927 uint8_t pdev_id, struct cc_regdmn_s *rd) 17928 { 17929 wmi_set_init_country_cmd_fixed_param *cmd; 17930 uint16_t len; 17931 wmi_buf_t buf; 17932 int ret; 17933 17934 len = sizeof(wmi_set_init_country_cmd_fixed_param); 17935 buf = wmi_buf_alloc(wmi_handle, len); 17936 if (!buf) 17937 return QDF_STATUS_E_NOMEM; 17938 17939 cmd = (wmi_set_init_country_cmd_fixed_param *) wmi_buf_data(buf); 17940 WMITLV_SET_HDR(&cmd->tlv_header, 17941 WMITLV_TAG_STRUC_wmi_set_init_country_cmd_fixed_param, 17942 WMITLV_GET_STRUCT_TLVLEN 17943 (wmi_set_init_country_cmd_fixed_param)); 17944 17945 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 17946 wmi_handle, 17947 pdev_id); 17948 17949 if (rd->flags == CC_IS_SET) { 17950 cmd->countrycode_type = WMI_COUNTRYCODE_COUNTRY_ID; 17951 cmd->country_code.country_id = rd->cc.country_code; 17952 } else if (rd->flags == ALPHA_IS_SET) { 17953 cmd->countrycode_type = WMI_COUNTRYCODE_ALPHA2; 17954 WMI_REG_COUNTRY_ALPHA_SET(cmd->country_code.alpha2, 17955 rd->cc.alpha[0], 17956 rd->cc.alpha[1], 17957 rd->cc.alpha[2]); 17958 } else if (rd->flags == REGDMN_IS_SET) { 17959 cmd->countrycode_type = WMI_COUNTRYCODE_DOMAIN_CODE; 17960 WMI_SET_BITS(cmd->country_code.domain_code, 0, 16, 17961 rd->cc.regdmn.reg_2g_5g_pair_id); 17962 WMI_SET_BITS(cmd->country_code.domain_code, 16, 16, 17963 rd->cc.regdmn.sixg_superdmn_id); 17964 } 17965 17966 wmi_mtrace(WMI_SET_INIT_COUNTRY_CMDID, NO_SESSION, 0); 17967 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 17968 WMI_SET_INIT_COUNTRY_CMDID); 17969 if (ret) { 17970 wmi_err("Failed to config wow wakeup event"); 17971 wmi_buf_free(buf); 17972 return QDF_STATUS_E_FAILURE; 17973 } 17974 17975 return QDF_STATUS_SUCCESS; 17976 } 17977 17978 /** 17979 * send_obss_detection_cfg_cmd_tlv() - send obss detection 17980 * configurations to firmware. 17981 * @wmi_handle: wmi handle 17982 * @obss_cfg_param: obss detection configurations 17983 * 17984 * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. 17985 * 17986 * Return: QDF_STATUS 17987 */ 17988 static QDF_STATUS send_obss_detection_cfg_cmd_tlv(wmi_unified_t wmi_handle, 17989 struct wmi_obss_detection_cfg_param *obss_cfg_param) 17990 { 17991 wmi_buf_t buf; 17992 wmi_sap_obss_detection_cfg_cmd_fixed_param *cmd; 17993 uint8_t len = sizeof(wmi_sap_obss_detection_cfg_cmd_fixed_param); 17994 17995 buf = wmi_buf_alloc(wmi_handle, len); 17996 if (!buf) 17997 return QDF_STATUS_E_NOMEM; 17998 17999 cmd = (wmi_sap_obss_detection_cfg_cmd_fixed_param *)wmi_buf_data(buf); 18000 WMITLV_SET_HDR(&cmd->tlv_header, 18001 WMITLV_TAG_STRUC_wmi_sap_obss_detection_cfg_cmd_fixed_param, 18002 WMITLV_GET_STRUCT_TLVLEN 18003 (wmi_sap_obss_detection_cfg_cmd_fixed_param)); 18004 18005 cmd->vdev_id = obss_cfg_param->vdev_id; 18006 cmd->detect_period_ms = obss_cfg_param->obss_detect_period_ms; 18007 cmd->b_ap_detect_mode = obss_cfg_param->obss_11b_ap_detect_mode; 18008 cmd->b_sta_detect_mode = obss_cfg_param->obss_11b_sta_detect_mode; 18009 cmd->g_ap_detect_mode = obss_cfg_param->obss_11g_ap_detect_mode; 18010 cmd->a_detect_mode = obss_cfg_param->obss_11a_detect_mode; 18011 cmd->ht_legacy_detect_mode = obss_cfg_param->obss_ht_legacy_detect_mode; 18012 cmd->ht_mixed_detect_mode = obss_cfg_param->obss_ht_mixed_detect_mode; 18013 cmd->ht_20mhz_detect_mode = obss_cfg_param->obss_ht_20mhz_detect_mode; 18014 18015 wmi_mtrace(WMI_SAP_OBSS_DETECTION_CFG_CMDID, cmd->vdev_id, 0); 18016 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18017 WMI_SAP_OBSS_DETECTION_CFG_CMDID)) { 18018 wmi_err("Failed to send WMI_SAP_OBSS_DETECTION_CFG_CMDID"); 18019 wmi_buf_free(buf); 18020 return QDF_STATUS_E_FAILURE; 18021 } 18022 18023 return QDF_STATUS_SUCCESS; 18024 } 18025 18026 /** 18027 * extract_obss_detection_info_tlv() - Extract obss detection info 18028 * received from firmware. 18029 * @evt_buf: pointer to event buffer 18030 * @obss_detection: Pointer to hold obss detection info 18031 * 18032 * Return: QDF_STATUS 18033 */ 18034 static QDF_STATUS extract_obss_detection_info_tlv(uint8_t *evt_buf, 18035 struct wmi_obss_detect_info 18036 *obss_detection) 18037 { 18038 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *param_buf; 18039 wmi_sap_obss_detection_info_evt_fixed_param *fix_param; 18040 18041 if (!obss_detection) { 18042 wmi_err("Invalid obss_detection event buffer"); 18043 return QDF_STATUS_E_INVAL; 18044 } 18045 18046 param_buf = (WMI_SAP_OBSS_DETECTION_REPORT_EVENTID_param_tlvs *)evt_buf; 18047 if (!param_buf) { 18048 wmi_err("Invalid evt_buf"); 18049 return QDF_STATUS_E_INVAL; 18050 } 18051 18052 fix_param = param_buf->fixed_param; 18053 obss_detection->vdev_id = fix_param->vdev_id; 18054 obss_detection->matched_detection_masks = 18055 fix_param->matched_detection_masks; 18056 WMI_MAC_ADDR_TO_CHAR_ARRAY(&fix_param->matched_bssid_addr, 18057 &obss_detection->matched_bssid_addr[0]); 18058 switch (fix_param->reason) { 18059 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_NOT_SUPPORT: 18060 obss_detection->reason = OBSS_OFFLOAD_DETECTION_DISABLED; 18061 break; 18062 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_PRESENT_NOTIFY: 18063 obss_detection->reason = OBSS_OFFLOAD_DETECTION_PRESENT; 18064 break; 18065 case WMI_SAP_OBSS_DETECTION_EVENT_REASON_ABSENT_TIMEOUT: 18066 obss_detection->reason = OBSS_OFFLOAD_DETECTION_ABSENT; 18067 break; 18068 default: 18069 wmi_err("Invalid reason: %d", fix_param->reason); 18070 return QDF_STATUS_E_INVAL; 18071 } 18072 18073 return QDF_STATUS_SUCCESS; 18074 } 18075 18076 /** 18077 * send_roam_scan_stats_cmd_tlv() - Send roam scan stats req command to fw 18078 * @wmi_handle: wmi handle 18079 * @params: pointer to request structure 18080 * 18081 * Return: QDF_STATUS 18082 */ 18083 static QDF_STATUS 18084 send_roam_scan_stats_cmd_tlv(wmi_unified_t wmi_handle, 18085 struct wmi_roam_scan_stats_req *params) 18086 { 18087 wmi_buf_t buf; 18088 wmi_request_roam_scan_stats_cmd_fixed_param *cmd; 18089 WMITLV_TAG_ID tag; 18090 uint32_t size; 18091 uint32_t len = sizeof(*cmd); 18092 18093 buf = wmi_buf_alloc(wmi_handle, len); 18094 if (!buf) 18095 return QDF_STATUS_E_FAILURE; 18096 18097 cmd = (wmi_request_roam_scan_stats_cmd_fixed_param *)wmi_buf_data(buf); 18098 18099 tag = WMITLV_TAG_STRUC_wmi_request_roam_scan_stats_cmd_fixed_param; 18100 size = WMITLV_GET_STRUCT_TLVLEN( 18101 wmi_request_roam_scan_stats_cmd_fixed_param); 18102 WMITLV_SET_HDR(&cmd->tlv_header, tag, size); 18103 18104 cmd->vdev_id = params->vdev_id; 18105 18106 wmi_debug("Roam Scan Stats Req vdev_id: %u", cmd->vdev_id); 18107 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18108 WMI_REQUEST_ROAM_SCAN_STATS_CMDID)) { 18109 wmi_err("Failed to send WMI_REQUEST_ROAM_SCAN_STATS_CMDID"); 18110 wmi_buf_free(buf); 18111 return QDF_STATUS_E_FAILURE; 18112 } 18113 18114 return QDF_STATUS_SUCCESS; 18115 } 18116 18117 /** 18118 * send_roam_scan_ch_list_req_cmd_tlv() - send wmi cmd to get roam scan 18119 * channel list from firmware 18120 * @wmi_handle: wmi handler 18121 * @vdev_id: vdev id 18122 * 18123 * Return: QDF_STATUS 18124 */ 18125 static QDF_STATUS send_roam_scan_ch_list_req_cmd_tlv(wmi_unified_t wmi_handle, 18126 uint32_t vdev_id) 18127 { 18128 wmi_buf_t buf; 18129 wmi_roam_get_scan_channel_list_cmd_fixed_param *cmd; 18130 uint16_t len = sizeof(*cmd); 18131 int ret; 18132 18133 buf = wmi_buf_alloc(wmi_handle, len); 18134 if (!buf) { 18135 wmi_err("Failed to allocate wmi buffer"); 18136 return QDF_STATUS_E_NOMEM; 18137 } 18138 18139 cmd = (wmi_roam_get_scan_channel_list_cmd_fixed_param *) 18140 wmi_buf_data(buf); 18141 WMITLV_SET_HDR(&cmd->tlv_header, 18142 WMITLV_TAG_STRUC_wmi_roam_get_scan_channel_list_cmd_fixed_param, 18143 WMITLV_GET_STRUCT_TLVLEN( 18144 wmi_roam_get_scan_channel_list_cmd_fixed_param)); 18145 cmd->vdev_id = vdev_id; 18146 wmi_mtrace(WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID, vdev_id, 0); 18147 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18148 WMI_ROAM_GET_SCAN_CHANNEL_LIST_CMDID); 18149 if (QDF_IS_STATUS_ERROR(ret)) { 18150 wmi_err("Failed to send get roam scan channels request = %d", 18151 ret); 18152 wmi_buf_free(buf); 18153 } 18154 return ret; 18155 } 18156 18157 /** 18158 * extract_roam_scan_stats_res_evt_tlv() - Extract roam scan stats event 18159 * @wmi_handle: wmi handle 18160 * @evt_buf: pointer to event buffer 18161 * @vdev_id: output pointer to hold vdev id 18162 * @res_param: output pointer to hold the allocated response 18163 * 18164 * Return: QDF_STATUS 18165 */ 18166 static QDF_STATUS 18167 extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18168 uint32_t *vdev_id, 18169 struct wmi_roam_scan_stats_res **res_param) 18170 { 18171 WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *param_buf; 18172 wmi_roam_scan_stats_event_fixed_param *fixed_param; 18173 uint32_t *client_id = NULL; 18174 wmi_roaming_timestamp *timestamp = NULL; 18175 uint32_t *num_channels = NULL; 18176 uint32_t *chan_info = NULL; 18177 wmi_mac_addr *old_bssid = NULL; 18178 uint32_t *is_roaming_success = NULL; 18179 wmi_mac_addr *new_bssid = NULL; 18180 uint32_t *num_roam_candidates = NULL; 18181 wmi_roam_scan_trigger_reason *roam_reason = NULL; 18182 wmi_mac_addr *bssid = NULL; 18183 uint32_t *score = NULL; 18184 uint32_t *channel = NULL; 18185 uint32_t *rssi = NULL; 18186 int chan_idx = 0, cand_idx = 0; 18187 uint32_t total_len; 18188 struct wmi_roam_scan_stats_res *res; 18189 uint32_t i, j; 18190 uint32_t num_scans, scan_param_size; 18191 18192 *res_param = NULL; 18193 *vdev_id = 0xFF; /* Initialize to invalid vdev id */ 18194 param_buf = (WMI_ROAM_SCAN_STATS_EVENTID_param_tlvs *)evt_buf; 18195 if (!param_buf) { 18196 wmi_err("Invalid roam scan stats event"); 18197 return QDF_STATUS_E_INVAL; 18198 } 18199 18200 fixed_param = param_buf->fixed_param; 18201 18202 num_scans = fixed_param->num_roam_scans; 18203 scan_param_size = sizeof(struct wmi_roam_scan_stats_params); 18204 *vdev_id = fixed_param->vdev_id; 18205 if (num_scans > WMI_ROAM_SCAN_STATS_MAX) { 18206 wmi_err_rl("%u exceeded maximum roam scan stats: %u", 18207 num_scans, WMI_ROAM_SCAN_STATS_MAX); 18208 return QDF_STATUS_E_INVAL; 18209 } 18210 18211 total_len = sizeof(*res) + num_scans * scan_param_size; 18212 18213 res = qdf_mem_malloc(total_len); 18214 if (!res) 18215 return QDF_STATUS_E_NOMEM; 18216 18217 if (!num_scans) { 18218 *res_param = res; 18219 return QDF_STATUS_SUCCESS; 18220 } 18221 18222 if (param_buf->client_id && 18223 param_buf->num_client_id == num_scans) 18224 client_id = param_buf->client_id; 18225 18226 if (param_buf->timestamp && 18227 param_buf->num_timestamp == num_scans) 18228 timestamp = param_buf->timestamp; 18229 18230 if (param_buf->old_bssid && 18231 param_buf->num_old_bssid == num_scans) 18232 old_bssid = param_buf->old_bssid; 18233 18234 if (param_buf->new_bssid && 18235 param_buf->num_new_bssid == num_scans) 18236 new_bssid = param_buf->new_bssid; 18237 18238 if (param_buf->is_roaming_success && 18239 param_buf->num_is_roaming_success == num_scans) 18240 is_roaming_success = param_buf->is_roaming_success; 18241 18242 if (param_buf->roam_reason && 18243 param_buf->num_roam_reason == num_scans) 18244 roam_reason = param_buf->roam_reason; 18245 18246 if (param_buf->num_channels && 18247 param_buf->num_num_channels == num_scans) { 18248 uint32_t count, chan_info_sum = 0; 18249 18250 num_channels = param_buf->num_channels; 18251 for (count = 0; count < param_buf->num_num_channels; count++) { 18252 if (param_buf->num_channels[count] > 18253 WMI_ROAM_SCAN_STATS_CHANNELS_MAX) { 18254 wmi_err_rl("%u exceeded max scan channels %u", 18255 param_buf->num_channels[count], 18256 WMI_ROAM_SCAN_STATS_CHANNELS_MAX); 18257 goto error; 18258 } 18259 chan_info_sum += param_buf->num_channels[count]; 18260 } 18261 18262 if (param_buf->chan_info && 18263 param_buf->num_chan_info == chan_info_sum) 18264 chan_info = param_buf->chan_info; 18265 } 18266 18267 if (param_buf->num_roam_candidates && 18268 param_buf->num_num_roam_candidates == num_scans) { 18269 uint32_t cnt, roam_cand_sum = 0; 18270 18271 num_roam_candidates = param_buf->num_roam_candidates; 18272 for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) { 18273 if (param_buf->num_roam_candidates[cnt] > 18274 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) { 18275 wmi_err_rl("%u exceeded max scan cand %u", 18276 param_buf->num_roam_candidates[cnt], 18277 WMI_ROAM_SCAN_STATS_CANDIDATES_MAX); 18278 goto error; 18279 } 18280 roam_cand_sum += param_buf->num_roam_candidates[cnt]; 18281 } 18282 18283 if (param_buf->bssid && 18284 param_buf->num_bssid == roam_cand_sum) 18285 bssid = param_buf->bssid; 18286 18287 if (param_buf->score && 18288 param_buf->num_score == roam_cand_sum) 18289 score = param_buf->score; 18290 18291 if (param_buf->channel && 18292 param_buf->num_channel == roam_cand_sum) 18293 channel = param_buf->channel; 18294 18295 if (param_buf->rssi && 18296 param_buf->num_rssi == roam_cand_sum) 18297 rssi = param_buf->rssi; 18298 } 18299 18300 res->num_roam_scans = num_scans; 18301 for (i = 0; i < num_scans; i++) { 18302 struct wmi_roam_scan_stats_params *roam = &res->roam_scan[i]; 18303 18304 if (timestamp) 18305 roam->time_stamp = timestamp[i].lower32bit | 18306 (timestamp[i].upper32bit << 31); 18307 18308 if (client_id) 18309 roam->client_id = client_id[i]; 18310 18311 if (num_channels) { 18312 roam->num_scan_chans = num_channels[i]; 18313 if (chan_info) { 18314 for (j = 0; j < num_channels[i]; j++) 18315 roam->scan_freqs[j] = 18316 chan_info[chan_idx++]; 18317 } 18318 } 18319 18320 if (is_roaming_success) 18321 roam->is_roam_successful = is_roaming_success[i]; 18322 18323 if (roam_reason) { 18324 roam->trigger_id = roam_reason[i].trigger_id; 18325 roam->trigger_value = roam_reason[i].trigger_value; 18326 } 18327 18328 if (num_roam_candidates) { 18329 roam->num_roam_candidates = num_roam_candidates[i]; 18330 18331 for (j = 0; j < num_roam_candidates[i]; j++) { 18332 if (score) 18333 roam->cand[j].score = score[cand_idx]; 18334 if (rssi) 18335 roam->cand[j].rssi = rssi[cand_idx]; 18336 if (channel) 18337 roam->cand[j].freq = 18338 channel[cand_idx]; 18339 18340 if (bssid) 18341 WMI_MAC_ADDR_TO_CHAR_ARRAY( 18342 &bssid[cand_idx], 18343 roam->cand[j].bssid); 18344 18345 cand_idx++; 18346 } 18347 } 18348 18349 if (old_bssid) 18350 WMI_MAC_ADDR_TO_CHAR_ARRAY(&old_bssid[i], 18351 roam->old_bssid); 18352 18353 if (new_bssid) 18354 WMI_MAC_ADDR_TO_CHAR_ARRAY(&new_bssid[i], 18355 roam->new_bssid); 18356 } 18357 18358 *res_param = res; 18359 18360 return QDF_STATUS_SUCCESS; 18361 error: 18362 qdf_mem_free(res); 18363 return QDF_STATUS_E_FAILURE; 18364 } 18365 18366 /** 18367 * extract_offload_bcn_tx_status_evt() - Extract beacon-tx status event 18368 * @wmi_handle: wmi handle 18369 * @evt_buf: pointer to event buffer 18370 * @vdev_id: output pointer to hold vdev id 18371 * @tx_status: output pointer to hold the tx_status 18372 * 18373 * Return: QDF_STATUS 18374 */ 18375 static QDF_STATUS extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, 18376 void *evt_buf, 18377 uint32_t *vdev_id, 18378 uint32_t *tx_status) { 18379 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; 18380 wmi_offload_bcn_tx_status_event_fixed_param *bcn_tx_status_event; 18381 18382 param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *)evt_buf; 18383 if (!param_buf) { 18384 wmi_err("Invalid offload bcn tx status event buffer"); 18385 return QDF_STATUS_E_INVAL; 18386 } 18387 18388 bcn_tx_status_event = param_buf->fixed_param; 18389 *vdev_id = bcn_tx_status_event->vdev_id; 18390 *tx_status = bcn_tx_status_event->tx_status; 18391 18392 return QDF_STATUS_SUCCESS; 18393 } 18394 18395 #ifdef WLAN_SUPPORT_GREEN_AP 18396 static QDF_STATUS extract_green_ap_egap_status_info_tlv( 18397 uint8_t *evt_buf, 18398 struct wlan_green_ap_egap_status_info *egap_status_info_params) 18399 { 18400 WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *param_buf; 18401 wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; 18402 wmi_ap_ps_egap_info_chainmask_list *chainmask_event; 18403 18404 param_buf = (WMI_AP_PS_EGAP_INFO_EVENTID_param_tlvs *)evt_buf; 18405 if (!param_buf) { 18406 wmi_err("Invalid EGAP Info status event buffer"); 18407 return QDF_STATUS_E_INVAL; 18408 } 18409 18410 egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) 18411 param_buf->fixed_param; 18412 chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) 18413 param_buf->chainmask_list; 18414 18415 if (!egap_info_event || !chainmask_event) { 18416 wmi_err("Invalid EGAP Info event or chainmask event"); 18417 return QDF_STATUS_E_INVAL; 18418 } 18419 18420 egap_status_info_params->status = egap_info_event->status; 18421 egap_status_info_params->mac_id = chainmask_event->mac_id; 18422 egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; 18423 egap_status_info_params->rx_chainmask = chainmask_event->rx_chainmask; 18424 18425 return QDF_STATUS_SUCCESS; 18426 } 18427 #endif 18428 18429 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 18430 static QDF_STATUS extract_green_ap_ll_ps_param_tlv( 18431 uint8_t *evt_buf, 18432 struct wlan_green_ap_ll_ps_event_param *ll_ps_params) 18433 { 18434 WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf; 18435 wmi_xgap_enable_complete_event_fixed_param *ll_ps_event; 18436 18437 param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf; 18438 if (!param_buf) { 18439 wmi_err("Invalid XGAP SAP info status"); 18440 return QDF_STATUS_E_INVAL; 18441 } 18442 18443 ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *) 18444 param_buf->fixed_param; 18445 if (!ll_ps_event) { 18446 wmi_err("Invalid low latency power save event buffer"); 18447 return QDF_STATUS_E_INVAL; 18448 } 18449 18450 ll_ps_params->dialog_token = ll_ps_event->dialog_token; 18451 ll_ps_params->next_tsf = 18452 ((uint64_t)ll_ps_event->next_tsf_high32 << 32) | 18453 ll_ps_event->next_tsf_low32; 18454 18455 wmi_debug("cookie : %u next_tsf %llu", ll_ps_params->dialog_token, 18456 ll_ps_params->next_tsf); 18457 18458 return QDF_STATUS_SUCCESS; 18459 } 18460 #endif 18461 18462 /* 18463 * extract_comb_phyerr_tlv() - extract comb phy error from event 18464 * @wmi_handle: wmi handle 18465 * @evt_buf: pointer to event buffer 18466 * @datalen: data length of event buffer 18467 * @buf_offset: Pointer to hold value of current event buffer offset 18468 * post extraction 18469 * @phyerr: Pointer to hold phyerr 18470 * 18471 * Return: QDF_STATUS 18472 */ 18473 static QDF_STATUS extract_comb_phyerr_tlv(wmi_unified_t wmi_handle, 18474 void *evt_buf, 18475 uint16_t datalen, 18476 uint16_t *buf_offset, 18477 wmi_host_phyerr_t *phyerr) 18478 { 18479 WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; 18480 wmi_comb_phyerr_rx_hdr *pe_hdr; 18481 18482 param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)evt_buf; 18483 if (!param_tlvs) { 18484 wmi_debug("Received null data from FW"); 18485 return QDF_STATUS_E_FAILURE; 18486 } 18487 18488 pe_hdr = param_tlvs->hdr; 18489 if (!pe_hdr) { 18490 wmi_debug("Received Data PE Header is NULL"); 18491 return QDF_STATUS_E_FAILURE; 18492 } 18493 18494 /* Ensure it's at least the size of the header */ 18495 if (datalen < sizeof(*pe_hdr)) { 18496 wmi_debug("Expected minimum size %zu, received %d", 18497 sizeof(*pe_hdr), datalen); 18498 return QDF_STATUS_E_FAILURE; 18499 } 18500 18501 phyerr->pdev_id = wmi_handle->ops-> 18502 convert_pdev_id_target_to_host(wmi_handle, pe_hdr->pdev_id); 18503 phyerr->tsf64 = pe_hdr->tsf_l32; 18504 phyerr->tsf64 |= (((uint64_t)pe_hdr->tsf_u32) << 32); 18505 phyerr->bufp = param_tlvs->bufp; 18506 18507 if (pe_hdr->buf_len > param_tlvs->num_bufp) { 18508 wmi_debug("Invalid buf_len %d, num_bufp %d", 18509 pe_hdr->buf_len, param_tlvs->num_bufp); 18510 return QDF_STATUS_E_FAILURE; 18511 } 18512 18513 phyerr->buf_len = pe_hdr->buf_len; 18514 phyerr->phy_err_mask0 = pe_hdr->rsPhyErrMask0; 18515 phyerr->phy_err_mask1 = pe_hdr->rsPhyErrMask1; 18516 *buf_offset = sizeof(*pe_hdr) + sizeof(uint32_t); 18517 18518 return QDF_STATUS_SUCCESS; 18519 } 18520 18521 /** 18522 * extract_single_phyerr_tlv() - extract single phy error from event 18523 * @wmi_handle: wmi handle 18524 * @evt_buf: pointer to event buffer 18525 * @datalen: data length of event buffer 18526 * @buf_offset: Pointer to hold value of current event buffer offset 18527 * post extraction 18528 * @phyerr: Pointer to hold phyerr 18529 * 18530 * Return: QDF_STATUS 18531 */ 18532 static QDF_STATUS extract_single_phyerr_tlv(wmi_unified_t wmi_handle, 18533 void *evt_buf, 18534 uint16_t datalen, 18535 uint16_t *buf_offset, 18536 wmi_host_phyerr_t *phyerr) 18537 { 18538 wmi_single_phyerr_rx_event *ev; 18539 uint16_t n = *buf_offset; 18540 uint8_t *data = (uint8_t *)evt_buf; 18541 18542 if (n < datalen) { 18543 if ((datalen - n) < sizeof(ev->hdr)) { 18544 wmi_debug("Not enough space. len=%d, n=%d, hdr=%zu", 18545 datalen, n, sizeof(ev->hdr)); 18546 return QDF_STATUS_E_FAILURE; 18547 } 18548 18549 /* 18550 * Obtain a pointer to the beginning of the current event. 18551 * data[0] is the beginning of the WMI payload. 18552 */ 18553 ev = (wmi_single_phyerr_rx_event *)&data[n]; 18554 18555 /* 18556 * Sanity check the buffer length of the event against 18557 * what we currently have. 18558 * 18559 * Since buf_len is 32 bits, we check if it overflows 18560 * a large 32 bit value. It's not 0x7fffffff because 18561 * we increase n by (buf_len + sizeof(hdr)), which would 18562 * in itself cause n to overflow. 18563 * 18564 * If "int" is 64 bits then this becomes a moot point. 18565 */ 18566 if (ev->hdr.buf_len > PHYERROR_MAX_BUFFER_LENGTH) { 18567 wmi_debug("buf_len is garbage 0x%x", ev->hdr.buf_len); 18568 return QDF_STATUS_E_FAILURE; 18569 } 18570 18571 if ((n + ev->hdr.buf_len) > datalen) { 18572 wmi_debug("len exceeds n=%d, buf_len=%d, datalen=%d", 18573 n, ev->hdr.buf_len, datalen); 18574 return QDF_STATUS_E_FAILURE; 18575 } 18576 18577 phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); 18578 phyerr->tsf_timestamp = ev->hdr.tsf_timestamp; 18579 phyerr->bufp = &ev->bufp[0]; 18580 phyerr->buf_len = ev->hdr.buf_len; 18581 phyerr->rf_info.rssi_comb = WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr); 18582 18583 /* 18584 * Advance the buffer pointer to the next PHY error. 18585 * buflen is the length of this payload, so we need to 18586 * advance past the current header _AND_ the payload. 18587 */ 18588 n += sizeof(*ev) + ev->hdr.buf_len; 18589 } 18590 *buf_offset = n; 18591 18592 return QDF_STATUS_SUCCESS; 18593 } 18594 18595 /** 18596 * extract_esp_estimation_ev_param_tlv() - extract air time from event 18597 * @wmi_handle: wmi handle 18598 * @evt_buf: pointer to event buffer 18599 * @param: Pointer to hold esp event 18600 * 18601 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_INVAL on failure 18602 */ 18603 static QDF_STATUS 18604 extract_esp_estimation_ev_param_tlv(wmi_unified_t wmi_handle, 18605 void *evt_buf, 18606 struct esp_estimation_event *param) 18607 { 18608 WMI_ESP_ESTIMATE_EVENTID_param_tlvs *param_buf; 18609 wmi_esp_estimate_event_fixed_param *esp_event; 18610 18611 param_buf = (WMI_ESP_ESTIMATE_EVENTID_param_tlvs *)evt_buf; 18612 if (!param_buf) { 18613 wmi_err("Invalid ESP Estimate Event buffer"); 18614 return QDF_STATUS_E_INVAL; 18615 } 18616 esp_event = param_buf->fixed_param; 18617 param->ac_airtime_percentage = esp_event->ac_airtime_percentage; 18618 18619 param->pdev_id = convert_target_pdev_id_to_host_pdev_id( 18620 wmi_handle, 18621 esp_event->pdev_id); 18622 18623 if (param->pdev_id == WMI_HOST_PDEV_ID_INVALID) 18624 return QDF_STATUS_E_FAILURE; 18625 18626 return QDF_STATUS_SUCCESS; 18627 } 18628 18629 /* 18630 * send_bss_color_change_enable_cmd_tlv() - Send command to enable or disable of 18631 * updating bss color change within firmware when AP announces bss color change. 18632 * @wmi_handle: wmi handle 18633 * @vdev_id: vdev ID 18634 * @enable: enable bss color change within firmware 18635 * 18636 * Send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID parameters to fw. 18637 * 18638 * Return: QDF_STATUS 18639 */ 18640 static QDF_STATUS send_bss_color_change_enable_cmd_tlv(wmi_unified_t wmi_handle, 18641 uint32_t vdev_id, 18642 bool enable) 18643 { 18644 wmi_buf_t buf; 18645 wmi_bss_color_change_enable_fixed_param *cmd; 18646 uint8_t len = sizeof(wmi_bss_color_change_enable_fixed_param); 18647 18648 buf = wmi_buf_alloc(wmi_handle, len); 18649 if (!buf) 18650 return QDF_STATUS_E_NOMEM; 18651 18652 cmd = (wmi_bss_color_change_enable_fixed_param *)wmi_buf_data(buf); 18653 WMITLV_SET_HDR(&cmd->tlv_header, 18654 WMITLV_TAG_STRUC_wmi_bss_color_change_enable_fixed_param, 18655 WMITLV_GET_STRUCT_TLVLEN 18656 (wmi_bss_color_change_enable_fixed_param)); 18657 cmd->vdev_id = vdev_id; 18658 cmd->enable = enable; 18659 wmi_mtrace(WMI_BSS_COLOR_CHANGE_ENABLE_CMDID, cmd->vdev_id, 0); 18660 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18661 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID)) { 18662 wmi_err("Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID"); 18663 wmi_buf_free(buf); 18664 return QDF_STATUS_E_FAILURE; 18665 } 18666 18667 return QDF_STATUS_SUCCESS; 18668 } 18669 18670 /** 18671 * send_obss_color_collision_cfg_cmd_tlv() - send bss color detection 18672 * configurations to firmware. 18673 * @wmi_handle: wmi handle 18674 * @cfg_param: obss detection configurations 18675 * 18676 * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. 18677 * 18678 * Return: QDF_STATUS 18679 */ 18680 static QDF_STATUS send_obss_color_collision_cfg_cmd_tlv( 18681 wmi_unified_t wmi_handle, 18682 struct wmi_obss_color_collision_cfg_param *cfg_param) 18683 { 18684 wmi_buf_t buf; 18685 wmi_obss_color_collision_det_config_fixed_param *cmd; 18686 uint8_t len = sizeof(wmi_obss_color_collision_det_config_fixed_param); 18687 18688 buf = wmi_buf_alloc(wmi_handle, len); 18689 if (!buf) 18690 return QDF_STATUS_E_NOMEM; 18691 18692 cmd = (wmi_obss_color_collision_det_config_fixed_param *)wmi_buf_data( 18693 buf); 18694 WMITLV_SET_HDR(&cmd->tlv_header, 18695 WMITLV_TAG_STRUC_wmi_obss_color_collision_det_config_fixed_param, 18696 WMITLV_GET_STRUCT_TLVLEN 18697 (wmi_obss_color_collision_det_config_fixed_param)); 18698 cmd->vdev_id = cfg_param->vdev_id; 18699 cmd->flags = cfg_param->flags; 18700 cmd->current_bss_color = cfg_param->current_bss_color; 18701 cmd->detection_period_ms = cfg_param->detection_period_ms; 18702 cmd->scan_period_ms = cfg_param->scan_period_ms; 18703 cmd->free_slot_expiry_time_ms = cfg_param->free_slot_expiry_time_ms; 18704 18705 switch (cfg_param->evt_type) { 18706 case OBSS_COLOR_COLLISION_DETECTION_DISABLE: 18707 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DISABLE; 18708 break; 18709 case OBSS_COLOR_COLLISION_DETECTION: 18710 cmd->evt_type = WMI_BSS_COLOR_COLLISION_DETECTION; 18711 break; 18712 case OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18713 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18714 break; 18715 case OBSS_COLOR_FREE_SLOT_AVAILABLE: 18716 cmd->evt_type = WMI_BSS_COLOR_FREE_SLOT_AVAILABLE; 18717 break; 18718 default: 18719 wmi_err("Invalid event type: %d", cfg_param->evt_type); 18720 wmi_buf_free(buf); 18721 return QDF_STATUS_E_FAILURE; 18722 } 18723 18724 wmi_debug("evt_type: %d vdev id: %d current_bss_color: %d " 18725 "detection_period_ms: %d scan_period_ms: %d " 18726 "free_slot_expiry_timer_ms: %d", 18727 cmd->evt_type, cmd->vdev_id, cmd->current_bss_color, 18728 cmd->detection_period_ms, cmd->scan_period_ms, 18729 cmd->free_slot_expiry_time_ms); 18730 18731 wmi_mtrace(WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID, cmd->vdev_id, 0); 18732 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18733 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID)) { 18734 wmi_err("Sending OBSS color det cmd failed, vdev_id: %d", 18735 cfg_param->vdev_id); 18736 wmi_buf_free(buf); 18737 return QDF_STATUS_E_FAILURE; 18738 } 18739 18740 return QDF_STATUS_SUCCESS; 18741 } 18742 18743 /** 18744 * extract_obss_color_collision_info_tlv() - Extract bss color collision info 18745 * received from firmware. 18746 * @evt_buf: pointer to event buffer 18747 * @info: Pointer to hold bss collision info 18748 * 18749 * Return: QDF_STATUS 18750 */ 18751 static QDF_STATUS extract_obss_color_collision_info_tlv(uint8_t *evt_buf, 18752 struct wmi_obss_color_collision_info *info) 18753 { 18754 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *param_buf; 18755 wmi_obss_color_collision_evt_fixed_param *fix_param; 18756 18757 if (!info) { 18758 wmi_err("Invalid obss color buffer"); 18759 return QDF_STATUS_E_INVAL; 18760 } 18761 18762 param_buf = (WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID_param_tlvs *) 18763 evt_buf; 18764 if (!param_buf) { 18765 wmi_err("Invalid evt_buf"); 18766 return QDF_STATUS_E_INVAL; 18767 } 18768 18769 fix_param = param_buf->fixed_param; 18770 info->vdev_id = fix_param->vdev_id; 18771 info->obss_color_bitmap_bit0to31 = 18772 fix_param->bss_color_bitmap_bit0to31; 18773 info->obss_color_bitmap_bit32to63 = 18774 fix_param->bss_color_bitmap_bit32to63; 18775 18776 switch (fix_param->evt_type) { 18777 case WMI_BSS_COLOR_COLLISION_DISABLE: 18778 info->evt_type = OBSS_COLOR_COLLISION_DETECTION_DISABLE; 18779 break; 18780 case WMI_BSS_COLOR_COLLISION_DETECTION: 18781 info->evt_type = OBSS_COLOR_COLLISION_DETECTION; 18782 break; 18783 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 18784 info->evt_type = OBSS_COLOR_FREE_SLOT_TIMER_EXPIRY; 18785 break; 18786 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 18787 info->evt_type = OBSS_COLOR_FREE_SLOT_AVAILABLE; 18788 break; 18789 default: 18790 wmi_err("Invalid event type: %d, vdev_id: %d", 18791 fix_param->evt_type, fix_param->vdev_id); 18792 return QDF_STATUS_E_FAILURE; 18793 } 18794 18795 return QDF_STATUS_SUCCESS; 18796 } 18797 18798 static void wmi_11ax_bss_color_attach_tlv(struct wmi_unified *wmi_handle) 18799 { 18800 struct wmi_ops *ops = wmi_handle->ops; 18801 18802 ops->send_obss_color_collision_cfg_cmd = 18803 send_obss_color_collision_cfg_cmd_tlv; 18804 ops->extract_obss_color_collision_info = 18805 extract_obss_color_collision_info_tlv; 18806 } 18807 18808 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 18809 static QDF_STATUS 18810 send_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, 18811 struct config_fils_params *param) 18812 { 18813 wmi_buf_t buf; 18814 wmi_enable_fils_cmd_fixed_param *cmd; 18815 uint8_t len = sizeof(wmi_enable_fils_cmd_fixed_param); 18816 18817 buf = wmi_buf_alloc(wmi_handle, len); 18818 if (!buf) 18819 return QDF_STATUS_E_NOMEM; 18820 18821 cmd = (wmi_enable_fils_cmd_fixed_param *)wmi_buf_data( 18822 buf); 18823 WMITLV_SET_HDR(&cmd->tlv_header, 18824 WMITLV_TAG_STRUC_wmi_enable_fils_cmd_fixed_param, 18825 WMITLV_GET_STRUCT_TLVLEN 18826 (wmi_enable_fils_cmd_fixed_param)); 18827 cmd->vdev_id = param->vdev_id; 18828 cmd->fd_period = param->fd_period; 18829 if (param->send_prb_rsp_frame) 18830 cmd->flags |= WMI_FILS_FLAGS_BITMAP_BCAST_PROBE_RSP; 18831 wmi_debug("vdev id: %d fd_period: %d cmd->Flags %d", 18832 cmd->vdev_id, cmd->fd_period, cmd->flags); 18833 wmi_mtrace(WMI_ENABLE_FILS_CMDID, cmd->vdev_id, cmd->fd_period); 18834 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18835 WMI_ENABLE_FILS_CMDID)) { 18836 wmi_err("Sending FILS cmd failed, vdev_id: %d", param->vdev_id); 18837 wmi_buf_free(buf); 18838 return QDF_STATUS_E_FAILURE; 18839 } 18840 18841 return QDF_STATUS_SUCCESS; 18842 } 18843 #endif 18844 18845 #ifdef WLAN_MWS_INFO_DEBUGFS 18846 /** 18847 * send_mws_coex_status_req_cmd_tlv() - send coex cmd to fw 18848 * 18849 * @wmi_handle: wmi handle 18850 * @vdev_id: vdev id 18851 * @cmd_id: Coex command id 18852 * 18853 * Send WMI_VDEV_GET_MWS_COEX_INFO_CMDID to fw. 18854 * 18855 * Return: QDF_STATUS 18856 */ 18857 static QDF_STATUS send_mws_coex_status_req_cmd_tlv(wmi_unified_t wmi_handle, 18858 uint32_t vdev_id, 18859 uint32_t cmd_id) 18860 { 18861 wmi_buf_t buf; 18862 wmi_vdev_get_mws_coex_info_cmd_fixed_param *cmd; 18863 uint16_t len = sizeof(*cmd); 18864 int ret; 18865 18866 buf = wmi_buf_alloc(wmi_handle, len); 18867 if (!buf) { 18868 wmi_err("Failed to allocate wmi buffer"); 18869 return QDF_STATUS_E_NOMEM; 18870 } 18871 18872 cmd = (wmi_vdev_get_mws_coex_info_cmd_fixed_param *)wmi_buf_data(buf); 18873 WMITLV_SET_HDR(&cmd->tlv_header, 18874 WMITLV_TAG_STRUC_wmi_vdev_get_mws_coex_info_cmd_fixed_param, 18875 WMITLV_GET_STRUCT_TLVLEN 18876 (wmi_vdev_get_mws_coex_info_cmd_fixed_param)); 18877 cmd->vdev_id = vdev_id; 18878 cmd->cmd_id = cmd_id; 18879 wmi_mtrace(WMI_VDEV_GET_MWS_COEX_INFO_CMDID, vdev_id, 0); 18880 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 18881 WMI_VDEV_GET_MWS_COEX_INFO_CMDID); 18882 if (QDF_IS_STATUS_ERROR(ret)) { 18883 wmi_err("Failed to send set param command ret = %d", ret); 18884 wmi_buf_free(buf); 18885 } 18886 return ret; 18887 } 18888 #endif 18889 18890 #ifdef FEATURE_MEC_OFFLOAD 18891 static QDF_STATUS 18892 send_pdev_set_mec_timer_cmd_tlv(struct wmi_unified *wmi_handle, 18893 struct set_mec_timer_params *param) 18894 { 18895 wmi_pdev_mec_aging_timer_config_cmd_fixed_param *cmd; 18896 wmi_buf_t buf; 18897 int32_t len = sizeof(*cmd); 18898 18899 buf = wmi_buf_alloc(wmi_handle, len); 18900 if (!buf) { 18901 wmi_err("wmi_buf_alloc failed"); 18902 return QDF_STATUS_E_FAILURE; 18903 } 18904 cmd = (wmi_pdev_mec_aging_timer_config_cmd_fixed_param *) 18905 wmi_buf_data(buf); 18906 WMITLV_SET_HDR(&cmd->tlv_header, 18907 WMITLV_TAG_STRUC_wmi_pdev_mec_aging_timer_config_cmd_fixed_param, 18908 WMITLV_GET_STRUCT_TLVLEN( 18909 wmi_pdev_mec_aging_timer_config_cmd_fixed_param)); 18910 cmd->pdev_id = param->pdev_id; 18911 cmd->mec_aging_timer_threshold = param->mec_aging_timer_threshold; 18912 18913 wmi_mtrace(WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID, param->vdev_id, 0); 18914 if (wmi_unified_cmd_send(wmi_handle, buf, len, 18915 WMI_PDEV_MEC_AGING_TIMER_CONFIG_CMDID)) { 18916 wmi_err("Failed to set mec aging timer param"); 18917 wmi_buf_free(buf); 18918 return QDF_STATUS_E_FAILURE; 18919 } 18920 18921 return QDF_STATUS_SUCCESS; 18922 } 18923 #endif 18924 18925 #ifdef WIFI_POS_CONVERGED 18926 /** 18927 * extract_oem_response_param_tlv() - Extract oem response params 18928 * @wmi_handle: wmi handle 18929 * @resp_buf: response buffer 18930 * @oem_resp_param: pointer to hold oem response params 18931 * 18932 * Return: QDF_STATUS_SUCCESS on success or proper error code. 18933 */ 18934 static QDF_STATUS 18935 extract_oem_response_param_tlv(wmi_unified_t wmi_handle, void *resp_buf, 18936 struct wmi_oem_response_param *oem_resp_param) 18937 { 18938 uint64_t temp_addr; 18939 WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = 18940 (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)resp_buf; 18941 18942 if (!param_buf) { 18943 wmi_err("Invalid OEM response"); 18944 return QDF_STATUS_E_INVAL; 18945 } 18946 18947 if (param_buf->num_data) { 18948 oem_resp_param->num_data1 = param_buf->num_data; 18949 oem_resp_param->data_1 = param_buf->data; 18950 } 18951 18952 if (param_buf->num_data2) { 18953 oem_resp_param->num_data2 = param_buf->num_data2; 18954 oem_resp_param->data_2 = param_buf->data2; 18955 } 18956 18957 if (param_buf->indirect_data) { 18958 oem_resp_param->indirect_data.pdev_id = 18959 param_buf->indirect_data->pdev_id; 18960 temp_addr = (param_buf->indirect_data->addr_hi) & 0xf; 18961 oem_resp_param->indirect_data.addr = 18962 param_buf->indirect_data->addr_lo + 18963 ((uint64_t)temp_addr << 32); 18964 oem_resp_param->indirect_data.len = 18965 param_buf->indirect_data->len; 18966 } 18967 18968 return QDF_STATUS_SUCCESS; 18969 } 18970 #endif /* WIFI_POS_CONVERGED */ 18971 18972 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 18973 #define WLAN_PASN_LTF_KEY_SEED_REQUIRED 0x2 18974 18975 static QDF_STATUS 18976 extract_pasn_peer_create_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 18977 struct wifi_pos_pasn_peer_data *dst) 18978 { 18979 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *param_buf; 18980 wmi_rtt_pasn_peer_create_req_event_fixed_param *fixed_param; 18981 wmi_rtt_pasn_peer_create_req_param *buf; 18982 uint8_t security_mode, i; 18983 18984 param_buf = (WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID_param_tlvs *)evt_buf; 18985 if (!param_buf) { 18986 wmi_err("Invalid peer_create req buffer"); 18987 return QDF_STATUS_E_INVAL; 18988 } 18989 18990 fixed_param = param_buf->fixed_param; 18991 18992 if (param_buf->num_rtt_pasn_peer_param > 18993 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 18994 sizeof(wmi_rtt_pasn_peer_create_req_param))) { 18995 wmi_err("Invalid TLV size"); 18996 return QDF_STATUS_E_INVAL; 18997 } 18998 18999 if (!param_buf->num_rtt_pasn_peer_param || 19000 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 19001 wmi_err("Invalid num TLV:%d", 19002 param_buf->num_rtt_pasn_peer_param); 19003 return QDF_STATUS_E_INVAL; 19004 } 19005 19006 dst->vdev_id = fixed_param->vdev_id; 19007 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 19008 wmi_err("Invalid vdev id:%d", dst->vdev_id); 19009 return QDF_STATUS_E_INVAL; 19010 } 19011 19012 buf = param_buf->rtt_pasn_peer_param; 19013 if (!buf) { 19014 wmi_err("NULL peer param TLV"); 19015 return QDF_STATUS_E_INVAL; 19016 } 19017 19018 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 19019 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->self_mac_addr, 19020 dst->peer_info[i].self_mac.bytes); 19021 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->dest_mac_addr, 19022 dst->peer_info[i].peer_mac.bytes); 19023 security_mode = WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_GET( 19024 buf->control_flag); 19025 if (security_mode) 19026 dst->peer_info[i].peer_type = 19027 WLAN_WIFI_POS_PASN_SECURE_PEER; 19028 else 19029 dst->peer_info[i].peer_type = 19030 WLAN_WIFI_POS_PASN_UNSECURE_PEER; 19031 if (security_mode & WLAN_PASN_LTF_KEY_SEED_REQUIRED) 19032 dst->peer_info[i].is_ltf_keyseed_required = true; 19033 19034 dst->peer_info[i].force_self_mac_usage = 19035 WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET( 19036 buf->control_flag); 19037 wmi_debug("Peer[%d]: self_mac:" QDF_MAC_ADDR_FMT " peer_mac:" QDF_MAC_ADDR_FMT "security_mode:0x%x force_self_mac:%d", 19038 i, QDF_MAC_ADDR_REF(dst->peer_info[i].self_mac.bytes), 19039 QDF_MAC_ADDR_REF(dst->peer_info[i].peer_mac.bytes), 19040 security_mode, 19041 dst->peer_info[i].force_self_mac_usage); 19042 19043 dst->num_peers++; 19044 buf++; 19045 } 19046 19047 return QDF_STATUS_SUCCESS; 19048 } 19049 19050 static QDF_STATUS 19051 extract_pasn_peer_delete_req_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19052 struct wifi_pos_pasn_peer_data *dst) 19053 { 19054 WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *param_buf; 19055 wmi_rtt_pasn_peer_delete_event_fixed_param *fixed_param; 19056 wmi_rtt_pasn_peer_delete_param *buf; 19057 uint8_t i; 19058 19059 param_buf = (WMI_RTT_PASN_PEER_DELETE_EVENTID_param_tlvs *)evt_buf; 19060 if (!param_buf) { 19061 wmi_err("Invalid peer_delete evt buffer"); 19062 return QDF_STATUS_E_INVAL; 19063 } 19064 19065 fixed_param = param_buf->fixed_param; 19066 19067 if (param_buf->num_rtt_pasn_peer_param > 19068 ((WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param)) / 19069 sizeof(wmi_rtt_pasn_peer_delete_param))) { 19070 wmi_err("Invalid TLV size"); 19071 return QDF_STATUS_E_INVAL; 19072 } 19073 19074 if (!param_buf->num_rtt_pasn_peer_param || 19075 param_buf->num_rtt_pasn_peer_param > WLAN_MAX_11AZ_PEERS) { 19076 wmi_err("Invalid num TLV:%d", 19077 param_buf->num_rtt_pasn_peer_param); 19078 return QDF_STATUS_E_INVAL; 19079 } 19080 19081 dst->vdev_id = fixed_param->vdev_id; 19082 if (dst->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) { 19083 wmi_err("Invalid vdev id:%d", dst->vdev_id); 19084 return QDF_STATUS_E_INVAL; 19085 } 19086 19087 buf = param_buf->rtt_pasn_peer_param; 19088 if (!buf) { 19089 wmi_err("NULL peer param TLV"); 19090 return QDF_STATUS_E_INVAL; 19091 } 19092 19093 for (i = 0; i < param_buf->num_rtt_pasn_peer_param; i++) { 19094 WMI_MAC_ADDR_TO_CHAR_ARRAY(&buf->peer_mac_addr, 19095 dst->peer_info[i].peer_mac.bytes); 19096 dst->peer_info[i].control_flags = buf->control_flag; 19097 19098 dst->num_peers++; 19099 buf++; 19100 } 19101 19102 return QDF_STATUS_SUCCESS; 19103 } 19104 19105 static QDF_STATUS 19106 send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, 19107 struct wlan_pasn_auth_status *data) 19108 { 19109 QDF_STATUS status; 19110 wmi_buf_t buf; 19111 wmi_rtt_pasn_auth_status_cmd_fixed_param *fixed_param; 19112 uint8_t *buf_ptr; 19113 uint8_t i; 19114 size_t len = sizeof(*fixed_param) + 19115 data->num_peers * sizeof(wmi_rtt_pasn_auth_status_param) + 19116 WMI_TLV_HDR_SIZE; 19117 19118 buf = wmi_buf_alloc(wmi_handle, len); 19119 if (!buf) { 19120 wmi_err("wmi_buf_alloc failed"); 19121 return QDF_STATUS_E_FAILURE; 19122 } 19123 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19124 fixed_param = 19125 (wmi_rtt_pasn_auth_status_cmd_fixed_param *)wmi_buf_data(buf); 19126 WMITLV_SET_HDR(&fixed_param->tlv_header, 19127 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, 19128 WMITLV_GET_STRUCT_TLVLEN( 19129 wmi_rtt_pasn_auth_status_cmd_fixed_param)); 19130 buf_ptr += sizeof(*fixed_param); 19131 19132 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 19133 (data->num_peers * 19134 sizeof(wmi_rtt_pasn_auth_status_param))); 19135 buf_ptr += WMI_TLV_HDR_SIZE; 19136 19137 for (i = 0; i < data->num_peers; i++) { 19138 wmi_rtt_pasn_auth_status_param *auth_status_tlv = 19139 (wmi_rtt_pasn_auth_status_param *)buf_ptr; 19140 19141 WMITLV_SET_HDR(&auth_status_tlv->tlv_header, 19142 WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_param, 19143 WMITLV_GET_STRUCT_TLVLEN(wmi_rtt_pasn_auth_status_param)); 19144 19145 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].peer_mac.bytes, 19146 &auth_status_tlv->peer_mac_addr); 19147 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, 19148 &auth_status_tlv->source_mac_addr); 19149 auth_status_tlv->status = data->auth_status[i].status; 19150 wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", 19151 QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), 19152 QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), 19153 auth_status_tlv->status); 19154 19155 buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); 19156 } 19157 19158 wmi_mtrace(WMI_RTT_PASN_AUTH_STATUS_CMD, 0, 0); 19159 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19160 WMI_RTT_PASN_AUTH_STATUS_CMD); 19161 if (QDF_IS_STATUS_ERROR(status)) { 19162 wmi_err("Failed to send Auth status command ret = %d", status); 19163 wmi_buf_free(buf); 19164 } 19165 19166 return status; 19167 } 19168 19169 static QDF_STATUS 19170 send_rtt_pasn_deauth_cmd_tlv(wmi_unified_t wmi_handle, 19171 struct qdf_mac_addr *peer_mac) 19172 { 19173 QDF_STATUS status; 19174 wmi_buf_t buf; 19175 wmi_rtt_pasn_deauth_cmd_fixed_param *fixed_param; 19176 size_t len = sizeof(*fixed_param); 19177 19178 buf = wmi_buf_alloc(wmi_handle, len); 19179 if (!buf) { 19180 wmi_err("wmi_buf_alloc failed"); 19181 return QDF_STATUS_E_FAILURE; 19182 } 19183 fixed_param = 19184 (wmi_rtt_pasn_deauth_cmd_fixed_param *)wmi_buf_data(buf); 19185 WMITLV_SET_HDR(&fixed_param->tlv_header, 19186 WMITLV_TAG_STRUC_wmi_rtt_pasn_deauth_cmd_fixed_param, 19187 WMITLV_GET_STRUCT_TLVLEN( 19188 wmi_rtt_pasn_deauth_cmd_fixed_param)); 19189 WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_mac->bytes, 19190 &fixed_param->peer_mac_addr); 19191 19192 wmi_mtrace(WMI_RTT_PASN_DEAUTH_CMD, 0, 0); 19193 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19194 WMI_RTT_PASN_DEAUTH_CMD); 19195 if (QDF_IS_STATUS_ERROR(status)) { 19196 wmi_err("Failed to send pasn deauth command ret = %d", status); 19197 wmi_buf_free(buf); 19198 } 19199 19200 return status; 19201 } 19202 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 19203 19204 static QDF_STATUS 19205 send_vdev_set_ltf_key_seed_cmd_tlv(wmi_unified_t wmi_handle, 19206 struct wlan_crypto_ltf_keyseed_data *data) 19207 { 19208 QDF_STATUS status; 19209 wmi_buf_t buf; 19210 wmi_vdev_set_ltf_key_seed_cmd_fixed_param *fixed_param; 19211 uint8_t *buf_ptr; 19212 size_t len = sizeof(*fixed_param) + data->key_seed_len + 19213 WMI_TLV_HDR_SIZE; 19214 19215 buf = wmi_buf_alloc(wmi_handle, len); 19216 if (!buf) { 19217 wmi_err("wmi_buf_alloc failed"); 19218 return QDF_STATUS_E_FAILURE; 19219 } 19220 19221 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19222 fixed_param = 19223 (wmi_vdev_set_ltf_key_seed_cmd_fixed_param *)wmi_buf_data(buf); 19224 WMITLV_SET_HDR(&fixed_param->tlv_header, 19225 WMITLV_TAG_STRUC_wmi_vdev_set_ltf_key_seed_cmd_fixed_param, 19226 WMITLV_GET_STRUCT_TLVLEN( 19227 wmi_vdev_set_ltf_key_seed_cmd_fixed_param)); 19228 19229 fixed_param->vdev_id = data->vdev_id; 19230 WMI_CHAR_ARRAY_TO_MAC_ADDR(data->peer_mac_addr.bytes, 19231 &fixed_param->peer_macaddr); 19232 fixed_param->key_seed_len = data->key_seed_len; 19233 fixed_param->rsn_authmode = data->rsn_authmode; 19234 19235 buf_ptr += sizeof(*fixed_param); 19236 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 19237 (fixed_param->key_seed_len * sizeof(A_UINT8))); 19238 buf_ptr += WMI_TLV_HDR_SIZE; 19239 19240 qdf_mem_copy(buf_ptr, data->key_seed, fixed_param->key_seed_len); 19241 19242 wmi_mtrace(WMI_VDEV_SET_LTF_KEY_SEED_CMDID, 0, 0); 19243 status = wmi_unified_cmd_send(wmi_handle, buf, len, 19244 WMI_VDEV_SET_LTF_KEY_SEED_CMDID); 19245 if (QDF_IS_STATUS_ERROR(status)) { 19246 wmi_err("Failed to send ltf keyseed command ret = %d", status); 19247 wmi_buf_free(buf); 19248 } 19249 19250 return status; 19251 } 19252 19253 /** 19254 * extract_hw_mode_resp_event_status_tlv() - Extract HW mode change status 19255 * @wmi_handle: wmi handle 19256 * @evt_buf: pointer to event buffer 19257 * @cmd_status: status of HW mode change command 19258 * 19259 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19260 */ 19261 static QDF_STATUS 19262 extract_hw_mode_resp_event_status_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19263 uint32_t *cmd_status) 19264 { 19265 WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf; 19266 wmi_pdev_set_hw_mode_response_event_fixed_param *fixed_param; 19267 19268 param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *)evt_buf; 19269 if (!param_buf) { 19270 wmi_err("Invalid mode change event buffer"); 19271 return QDF_STATUS_E_INVAL; 19272 } 19273 19274 fixed_param = param_buf->fixed_param; 19275 if (!fixed_param) { 19276 wmi_err("Invalid fixed param"); 19277 return QDF_STATUS_E_INVAL; 19278 } 19279 19280 *cmd_status = fixed_param->status; 19281 return QDF_STATUS_SUCCESS; 19282 } 19283 19284 /** 19285 * extract_rf_path_resp_tlv() - Extract RF path change status 19286 * @wmi_handle: wmi handle 19287 * @evt_buf: pointer to event buffer 19288 * @cmd_status: status of RF path change request 19289 * 19290 * Return: QDF_STATUS_SUCCESS on success or proper error code. 19291 */ 19292 static QDF_STATUS 19293 extract_rf_path_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19294 uint32_t *cmd_status) 19295 { 19296 WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *param_buf; 19297 wmi_pdev_set_rf_path_event_fixed_param *fixed_param; 19298 19299 param_buf = (WMI_PDEV_SET_RF_PATH_RESP_EVENTID_param_tlvs *)evt_buf; 19300 if (!param_buf) { 19301 wmi_err("Invalid RF path event buffer"); 19302 return QDF_STATUS_E_INVAL; 19303 } 19304 19305 fixed_param = param_buf->fixed_param; 19306 if (!fixed_param) { 19307 wmi_err("Invalid fixed param"); 19308 return QDF_STATUS_E_INVAL; 19309 } 19310 19311 *cmd_status = fixed_param->status; 19312 return QDF_STATUS_SUCCESS; 19313 } 19314 19315 #ifdef FEATURE_ANI_LEVEL_REQUEST 19316 static QDF_STATUS send_ani_level_cmd_tlv(wmi_unified_t wmi_handle, 19317 uint32_t *freqs, 19318 uint8_t num_freqs) 19319 { 19320 wmi_buf_t buf; 19321 wmi_get_channel_ani_cmd_fixed_param *cmd; 19322 QDF_STATUS ret; 19323 uint32_t len; 19324 A_UINT32 *chan_list; 19325 uint8_t i, *buf_ptr; 19326 19327 len = sizeof(wmi_get_channel_ani_cmd_fixed_param) + 19328 WMI_TLV_HDR_SIZE + 19329 num_freqs * sizeof(A_UINT32); 19330 19331 buf = wmi_buf_alloc(wmi_handle, len); 19332 if (!buf) 19333 return QDF_STATUS_E_FAILURE; 19334 19335 buf_ptr = (uint8_t *)wmi_buf_data(buf); 19336 cmd = (wmi_get_channel_ani_cmd_fixed_param *)buf_ptr; 19337 WMITLV_SET_HDR(&cmd->tlv_header, 19338 WMITLV_TAG_STRUC_wmi_get_channel_ani_cmd_fixed_param, 19339 WMITLV_GET_STRUCT_TLVLEN( 19340 wmi_get_channel_ani_cmd_fixed_param)); 19341 19342 buf_ptr += sizeof(wmi_get_channel_ani_cmd_fixed_param); 19343 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 19344 (num_freqs * sizeof(A_UINT32))); 19345 19346 chan_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); 19347 for (i = 0; i < num_freqs; i++) { 19348 chan_list[i] = freqs[i]; 19349 wmi_debug("Requesting ANI for channel[%d]", chan_list[i]); 19350 } 19351 19352 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 19353 WMI_GET_CHANNEL_ANI_CMDID); 19354 19355 if (QDF_IS_STATUS_ERROR(ret)) { 19356 wmi_err("WMI_GET_CHANNEL_ANI_CMDID send error %d", ret); 19357 wmi_buf_free(buf); 19358 } 19359 19360 return ret; 19361 } 19362 19363 static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf, 19364 struct wmi_host_ani_level_event **info, 19365 uint32_t *num_freqs) 19366 { 19367 WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *param_buf; 19368 wmi_get_channel_ani_event_fixed_param *fixed_param; 19369 wmi_channel_ani_info_tlv_param *tlv_params; 19370 uint8_t *buf_ptr, i; 19371 19372 param_buf = (WMI_GET_CHANNEL_ANI_EVENTID_param_tlvs *)evt_buf; 19373 if (!param_buf) { 19374 wmi_err("Invalid ani level event buffer"); 19375 return QDF_STATUS_E_INVAL; 19376 } 19377 19378 fixed_param = 19379 (wmi_get_channel_ani_event_fixed_param *)param_buf->fixed_param; 19380 if (!fixed_param) { 19381 wmi_err("Invalid fixed param"); 19382 return QDF_STATUS_E_INVAL; 19383 } 19384 19385 buf_ptr = (uint8_t *)fixed_param; 19386 buf_ptr += sizeof(wmi_get_channel_ani_event_fixed_param); 19387 buf_ptr += WMI_TLV_HDR_SIZE; 19388 19389 *num_freqs = param_buf->num_ani_info; 19390 if (*num_freqs > MAX_NUM_FREQS_FOR_ANI_LEVEL) { 19391 wmi_err("Invalid number of freqs received"); 19392 return QDF_STATUS_E_INVAL; 19393 } 19394 19395 *info = qdf_mem_malloc(*num_freqs * 19396 sizeof(struct wmi_host_ani_level_event)); 19397 if (!(*info)) 19398 return QDF_STATUS_E_NOMEM; 19399 19400 tlv_params = (wmi_channel_ani_info_tlv_param *)buf_ptr; 19401 for (i = 0; i < param_buf->num_ani_info; i++) { 19402 (*info)[i].ani_level = tlv_params->ani_level; 19403 (*info)[i].chan_freq = tlv_params->chan_freq; 19404 tlv_params++; 19405 } 19406 19407 return QDF_STATUS_SUCCESS; 19408 } 19409 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 19410 19411 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 19412 /** 19413 * convert_wtc_scan_mode() - Function to convert TLV specific 19414 * ROAM_TRIGGER_SCAN_MODE scan mode to unified Roam trigger scan mode enum 19415 * @scan_mode: scan freq scheme coming from firmware 19416 * 19417 * Return: ROAM_TRIGGER_SCAN_MODE 19418 */ 19419 static enum roam_scan_freq_scheme 19420 convert_wtc_scan_mode(WMI_ROAM_TRIGGER_SCAN_MODE scan_mode) 19421 { 19422 switch (scan_mode) { 19423 case ROAM_TRIGGER_SCAN_MODE_NO_SCAN_DISCONNECTION: 19424 return ROAM_SCAN_FREQ_SCHEME_NO_SCAN; 19425 case ROAM_TRIGGER_SCAN_MODE_PARTIAL: 19426 return ROAM_SCAN_FREQ_SCHEME_PARTIAL_SCAN; 19427 case ROAM_TRIGGER_SCAN_MODE_FULL: 19428 return ROAM_SCAN_FREQ_SCHEME_FULL_SCAN; 19429 default: 19430 return ROAM_SCAN_FREQ_SCHEME_NONE; 19431 } 19432 } 19433 19434 static uint32_t wmi_convert_fw_to_cm_trig_reason(uint32_t fw_trig_reason) 19435 { 19436 switch (fw_trig_reason) { 19437 case WMI_ROAM_TRIGGER_REASON_NONE: 19438 return ROAM_TRIGGER_REASON_NONE; 19439 case WMI_ROAM_TRIGGER_REASON_PER: 19440 return ROAM_TRIGGER_REASON_PER; 19441 case WMI_ROAM_TRIGGER_REASON_BMISS: 19442 return ROAM_TRIGGER_REASON_BMISS; 19443 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 19444 return ROAM_TRIGGER_REASON_LOW_RSSI; 19445 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19446 return ROAM_TRIGGER_REASON_HIGH_RSSI; 19447 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 19448 return ROAM_TRIGGER_REASON_PERIODIC; 19449 case WMI_ROAM_TRIGGER_REASON_MAWC: 19450 return ROAM_TRIGGER_REASON_MAWC; 19451 case WMI_ROAM_TRIGGER_REASON_DENSE: 19452 return ROAM_TRIGGER_REASON_DENSE; 19453 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19454 return ROAM_TRIGGER_REASON_BACKGROUND; 19455 case WMI_ROAM_TRIGGER_REASON_FORCED: 19456 return ROAM_TRIGGER_REASON_FORCED; 19457 case WMI_ROAM_TRIGGER_REASON_BTM: 19458 return ROAM_TRIGGER_REASON_BTM; 19459 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19460 return ROAM_TRIGGER_REASON_UNIT_TEST; 19461 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 19462 return ROAM_TRIGGER_REASON_BSS_LOAD; 19463 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 19464 return ROAM_TRIGGER_REASON_DEAUTH; 19465 case WMI_ROAM_TRIGGER_REASON_IDLE: 19466 return ROAM_TRIGGER_REASON_IDLE; 19467 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 19468 return ROAM_TRIGGER_REASON_STA_KICKOUT; 19469 case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: 19470 return ROAM_TRIGGER_REASON_ESS_RSSI; 19471 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 19472 return ROAM_TRIGGER_REASON_WTC_BTM; 19473 case WMI_ROAM_TRIGGER_REASON_PMK_TIMEOUT: 19474 return ROAM_TRIGGER_REASON_PMK_TIMEOUT; 19475 case WMI_ROAM_TRIGGER_REASON_BTC: 19476 return ROAM_TRIGGER_REASON_BTC; 19477 case WMI_ROAM_TRIGGER_EXT_REASON_MAX: 19478 return ROAM_TRIGGER_REASON_MAX; 19479 default: 19480 return ROAM_TRIGGER_REASON_NONE; 19481 } 19482 } 19483 19484 /** 19485 * extract_roam_11kv_candidate_info - Extract btm candidate info 19486 * @wmi_handle: wmi_handle 19487 * @evt_buf: Event buffer 19488 * @dst_info: Destination buffer 19489 * @btm_idx: BTM index 19490 * @num_cand: Number of candidates 19491 * 19492 * Return: QDF_STATUS 19493 */ 19494 static QDF_STATUS 19495 extract_roam_11kv_candidate_info(wmi_unified_t wmi_handle, void *evt_buf, 19496 struct wmi_btm_req_candidate_info *dst_info, 19497 uint8_t btm_idx, uint16_t num_cand) 19498 { 19499 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19500 wmi_roam_btm_request_candidate_info *src_data; 19501 uint8_t i; 19502 19503 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19504 if (!param_buf || !param_buf->roam_btm_request_candidate_info || 19505 !param_buf->num_roam_btm_request_candidate_info || 19506 (btm_idx + 19507 num_cand) > param_buf->num_roam_btm_request_candidate_info) 19508 return QDF_STATUS_SUCCESS; 19509 19510 src_data = ¶m_buf->roam_btm_request_candidate_info[btm_idx]; 19511 if (num_cand > WLAN_MAX_BTM_CANDIDATE) 19512 num_cand = WLAN_MAX_BTM_CANDIDATE; 19513 for (i = 0; i < num_cand; i++) { 19514 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->btm_candidate_bssid, 19515 dst_info->candidate_bssid.bytes); 19516 dst_info->preference = src_data->preference; 19517 src_data++; 19518 dst_info++; 19519 } 19520 19521 return QDF_STATUS_SUCCESS; 19522 } 19523 19524 static enum roam_trigger_sub_reason 19525 wmi_convert_roam_sub_reason(WMI_ROAM_TRIGGER_SUB_REASON_ID subreason) 19526 { 19527 switch (subreason) { 19528 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: 19529 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER; 19530 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: 19531 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI; 19532 case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: 19533 return ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER; 19534 case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: 19535 return ROAM_TRIGGER_SUB_REASON_FULL_SCAN; 19536 case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: 19537 return ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC; 19538 case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: 19539 return ROAM_TRIGGER_SUB_REASON_CU_PERIODIC; 19540 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: 19541 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY; 19542 case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: 19543 return ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU; 19544 case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: 19545 return ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU; 19546 default: 19547 break; 19548 } 19549 19550 return 0; 19551 } 19552 19553 /** 19554 * wlan_roam_fail_reason_code() - Convert FW enum to Host enum 19555 * @wmi_roam_fail_reason: roam fail enum 19556 * 19557 * Return: Roaming failure reason codes 19558 */ 19559 static enum wlan_roam_failure_reason_code 19560 wlan_roam_fail_reason_code(uint16_t wmi_roam_fail_reason) 19561 { 19562 switch (wmi_roam_fail_reason) { 19563 case WMI_ROAM_FAIL_REASON_NO_SCAN_START: 19564 return ROAM_FAIL_REASON_NO_SCAN_START; 19565 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND: 19566 return ROAM_FAIL_REASON_NO_AP_FOUND; 19567 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: 19568 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND; 19569 case WMI_ROAM_FAIL_REASON_HOST: 19570 return ROAM_FAIL_REASON_HOST; 19571 case WMI_ROAM_FAIL_REASON_AUTH_SEND: 19572 return ROAM_FAIL_REASON_AUTH_SEND; 19573 case WMI_ROAM_FAIL_REASON_AUTH_RECV: 19574 return ROAM_FAIL_REASON_AUTH_RECV; 19575 case WMI_ROAM_FAIL_REASON_NO_AUTH_RESP: 19576 return ROAM_FAIL_REASON_NO_AUTH_RESP; 19577 case WMI_ROAM_FAIL_REASON_REASSOC_SEND: 19578 return ROAM_FAIL_REASON_REASSOC_SEND; 19579 case WMI_ROAM_FAIL_REASON_REASSOC_RECV: 19580 return ROAM_FAIL_REASON_REASSOC_RECV; 19581 case WMI_ROAM_FAIL_REASON_NO_REASSOC_RESP: 19582 return ROAM_FAIL_REASON_NO_REASSOC_RESP; 19583 case WMI_ROAM_FAIL_REASON_EAPOL_TIMEOUT: 19584 return ROAM_FAIL_REASON_EAPOL_TIMEOUT; 19585 case WMI_ROAM_FAIL_REASON_MLME: 19586 return ROAM_FAIL_REASON_MLME; 19587 case WMI_ROAM_FAIL_REASON_INTERNAL_ABORT: 19588 return ROAM_FAIL_REASON_INTERNAL_ABORT; 19589 case WMI_ROAM_FAIL_REASON_SCAN_START: 19590 return ROAM_FAIL_REASON_SCAN_START; 19591 case WMI_ROAM_FAIL_REASON_AUTH_NO_ACK: 19592 return ROAM_FAIL_REASON_AUTH_NO_ACK; 19593 case WMI_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: 19594 return ROAM_FAIL_REASON_AUTH_INTERNAL_DROP; 19595 case WMI_ROAM_FAIL_REASON_REASSOC_NO_ACK: 19596 return ROAM_FAIL_REASON_REASSOC_NO_ACK; 19597 case WMI_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: 19598 return ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP; 19599 case WMI_ROAM_FAIL_REASON_EAPOL_M2_SEND: 19600 return ROAM_FAIL_REASON_EAPOL_M2_SEND; 19601 case WMI_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: 19602 return ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP; 19603 case WMI_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: 19604 return ROAM_FAIL_REASON_EAPOL_M2_NO_ACK; 19605 case WMI_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: 19606 return ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT; 19607 case WMI_ROAM_FAIL_REASON_EAPOL_M4_SEND: 19608 return ROAM_FAIL_REASON_EAPOL_M4_SEND; 19609 case WMI_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: 19610 return ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP; 19611 case WMI_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: 19612 return ROAM_FAIL_REASON_EAPOL_M4_NO_ACK; 19613 case WMI_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS: 19614 return ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BMISS; 19615 case WMI_ROAM_FAIL_REASON_DISCONNECT: 19616 return ROAM_FAIL_REASON_DISCONNECT; 19617 case WMI_ROAM_FAIL_REASON_SYNC: 19618 return ROAM_FAIL_REASON_SYNC; 19619 case WMI_ROAM_FAIL_REASON_SAE_INVALID_PMKID: 19620 return ROAM_FAIL_REASON_SAE_INVALID_PMKID; 19621 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: 19622 return ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT; 19623 case WMI_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: 19624 return ROAM_FAIL_REASON_SAE_PREAUTH_FAIL; 19625 case WMI_ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO: 19626 return ROAM_FAIL_REASON_UNABLE_TO_START_ROAM_HO; 19627 case WMI_ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT: 19628 return ROAM_FAIL_REASON_NO_AP_FOUND_AND_FINAL_BMISS_SENT; 19629 case WMI_ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT: 19630 return ROAM_FAIL_REASON_NO_CAND_AP_FOUND_AND_FINAL_BMISS_SENT; 19631 case WMI_ROAM_FAIL_REASON_CURR_AP_STILL_OK: 19632 return ROAM_FAIL_REASON_CURR_AP_STILL_OK; 19633 case WMI_ROAM_FAIL_REASON_SCAN_CANCEL: 19634 return ROAM_FAIL_REASON_SCAN_CANCEL; 19635 default: 19636 return ROAM_FAIL_REASON_UNKNOWN; 19637 } 19638 } 19639 19640 /** 19641 * wmi_convert_to_cm_roam_invoke_reason() - Convert FW enum to Host enum 19642 * @reason: roam invoke reason from fw 19643 * 19644 * Return: Roam invoke reason code defined in host driver 19645 */ 19646 static enum roam_invoke_reason 19647 wmi_convert_to_cm_roam_invoke_reason(enum wlan_roam_invoke_reason reason) 19648 { 19649 switch (reason) { 19650 case ROAM_INVOKE_REASON_UNDEFINED: 19651 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19652 case ROAM_INVOKE_REASON_NUD_FAILURE: 19653 return WLAN_ROAM_STATS_INVOKE_REASON_NUD_FAILURE; 19654 case ROAM_INVOKE_REASON_USER_SPACE: 19655 return WLAN_ROAM_STATS_INVOKE_REASON_USER_SPACE; 19656 default: 19657 return WLAN_ROAM_STATS_INVOKE_REASON_UNDEFINED; 19658 } 19659 } 19660 19661 /** 19662 * wmi_convert_to_cm_roam_tx_fail_reason() - Convert FW enum to Host enum 19663 * @tx_fail_reason: roam tx fail reason from fw 19664 * 19665 * Return: Roam tx fail reason code defined in host driver 19666 */ 19667 static enum roam_tx_failures_reason 19668 wmi_convert_to_cm_roam_tx_fail_reason(PEER_KICKOUT_REASON tx_fail_reason) 19669 { 19670 switch (tx_fail_reason) { 19671 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: 19672 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19673 case WMI_PEER_STA_KICKOUT_REASON_XRETRY: 19674 return WLAN_ROAM_STATS_KICKOUT_REASON_XRETRY; 19675 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: 19676 return WLAN_ROAM_STATS_KICKOUT_REASON_INACTIVITY; 19677 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: 19678 return WLAN_ROAM_STATS_KICKOUT_REASON_IBSS_DISCONNECT; 19679 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: 19680 return WLAN_ROAM_STATS_KICKOUT_REASON_TDLS_DISCONNECT; 19681 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT: 19682 return WLAN_ROAM_STATS_KICKOUT_REASON_SA_QUERY_TIMEOUT; 19683 case WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT: 19684 return WLAN_ROAM_STATS_KICKOUT_REASON_ROAMING_EVENT; 19685 default: 19686 return WLAN_ROAM_STATS_KICKOUT_REASON_UNSPECIFIED; 19687 } 19688 } 19689 19690 /** 19691 * wmi_convert_roam_abort_reason() - Convert FW enum to Host enum 19692 * @abort_reason: roam abort reason from fw 19693 * 19694 * Return: Roam abort reason code defined in host driver 19695 */ 19696 static enum roam_abort_reason 19697 wmi_convert_roam_abort_reason(WMI_ROAM_FAIL_SUB_REASON_ID abort_reason) 19698 { 19699 switch (abort_reason) { 19700 case WMI_ROAM_ABORT_UNSPECIFIED: 19701 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19702 case WMI_ROAM_ABORT_LOWRSSI_DATA_RSSI_HIGH: 19703 return WLAN_ROAM_STATS_ABORT_LOWRSSI_DATA_RSSI_HIGH; 19704 case WMI_ROAM_ABORT_LOWRSSI_LINK_SPEED_GOOD: 19705 return WLAN_ROAM_STATS_ABORT_LOWRSSI_LINK_SPEED_GOOD; 19706 case WMI_ROAM_ABORT_BG_DATA_RSSI_HIGH: 19707 return WLAN_ROAM_STATS_ABORT_BG_DATA_RSSI_HIGH; 19708 case WMI_ROAM_ABORT_BG_RSSI_ABOVE_THRESHOLD: 19709 return WLAN_ROAM_STATS_ABORT_BG_RSSI_ABOVE_THRESHOLD; 19710 default: 19711 return WLAN_ROAM_STATS_ABORT_UNSPECIFIED; 19712 } 19713 } 19714 19715 /** 19716 * wlan_roam_scan_type() - Convert FW enum to Host enum 19717 * @scan_type: roam scan type from fw 19718 * 19719 * Return: Roam scan type defined in host driver 19720 */ 19721 static enum roam_stats_scan_type 19722 wlan_roam_scan_type(uint32_t scan_type) 19723 { 19724 switch (scan_type) { 19725 case 0: 19726 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19727 case 1: 19728 return ROAM_STATS_SCAN_TYPE_FULL; 19729 case 2: 19730 return ROAM_STATS_SCAN_TYPE_NO_SCAN; 19731 case 3: 19732 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_5GHZ_6GHZ; 19733 case 4: 19734 return ROAM_STATS_SCAN_TYPE_HIGHER_BAND_6GHZ; 19735 default: 19736 return ROAM_STATS_SCAN_TYPE_PARTIAL; 19737 } 19738 } 19739 19740 /** 19741 * wlan_roam_dwell_type() - Convert FW enum to Host enum 19742 * @dwell_type: roam channel scan dwell type from fw 19743 * 19744 * Return: Roam channel scan dwell type defined in host driver 19745 */ 19746 static enum roam_scan_dwell_type 19747 wlan_roam_dwell_type(uint32_t dwell_type) 19748 { 19749 switch (dwell_type) { 19750 case 0: 19751 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19752 case 1: 19753 return WLAN_ROAM_DWELL_ACTIVE_TYPE; 19754 case 2: 19755 return WLAN_ROAM_DWELL_PASSIVE_TYPE; 19756 default: 19757 return WLAN_ROAM_DWELL_TYPE_UNSPECIFIED; 19758 } 19759 } 19760 19761 #define WLAN_ROAM_PER_TX_RATE_OFFSET 0 19762 #define WLAN_ROAM_PER_RX_RATE_OFFSET 16 19763 #define WLAN_ROAM_BMISS_FINNAL_OFFSET 0 19764 #define WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET 7 19765 #define WLAN_ROAM_BMISS_QOSNULL_OFFSET 24 19766 #define WLAN_ROAM_DENSE_ROAMABLE_OFFSET 0 19767 19768 /** 19769 * extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats 19770 * from the WMI_ROAM_STATS_EVENTID 19771 * @wmi_handle: wmi handle 19772 * @evt_buf: Pointer to the event buffer 19773 * @trig: Pointer to destination structure to fill data 19774 * @idx: TLV id 19775 * @btm_idx: BTM index 19776 */ 19777 static QDF_STATUS 19778 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 19779 struct wmi_roam_trigger_info *trig, uint8_t idx, 19780 uint8_t btm_idx) 19781 { 19782 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 19783 wmi_roam_trigger_reason *src_data = NULL; 19784 uint32_t trig_reason = 0; 19785 uint32_t fail_reason = 0; 19786 uint32_t abort = 0; 19787 uint32_t invoke = 0; 19788 uint32_t tx_fail = 0; 19789 wmi_roam_trigger_reason_cmm *cmn_data = NULL; 19790 wmi_roam_trigger_per *per_data = NULL; 19791 wmi_roam_trigger_bmiss *bmiss_data = NULL; 19792 wmi_roam_trigger_hi_rssi *hi_rssi_data = NULL; 19793 wmi_roam_trigger_dense *dense_data = NULL; 19794 wmi_roam_trigger_force *force_data = NULL; 19795 wmi_roam_trigger_btm *btm_data = NULL; 19796 wmi_roam_trigger_bss_load *bss_load_data = NULL; 19797 wmi_roam_trigger_deauth *deauth_data = NULL; 19798 wmi_roam_trigger_periodic *periodic_data = NULL; 19799 wmi_roam_trigger_rssi *rssi_data = NULL; 19800 wmi_roam_trigger_kickout *kickout_data = NULL; 19801 wmi_roam_result *roam_result = NULL; 19802 wmi_roam_scan_info *scan_info = NULL; 19803 19804 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 19805 if (!param_buf) { 19806 wmi_err("Param buf is NULL"); 19807 return QDF_STATUS_E_FAILURE; 19808 } 19809 19810 if (!param_buf->roam_result || idx >= param_buf->num_roam_result) 19811 wmi_err("roam_result or idx error.%u", idx); 19812 19813 if (!param_buf->roam_scan_info || idx >= param_buf->num_roam_scan_info) 19814 wmi_err("roam_scan_info or idx error.%u", idx); 19815 19816 trig->present = true; 19817 19818 if (param_buf->roam_scan_info) 19819 scan_info = ¶m_buf->roam_scan_info[idx]; 19820 19821 if (param_buf->roam_trigger_reason_cmm) 19822 cmn_data = ¶m_buf->roam_trigger_reason_cmm[idx]; 19823 19824 if (param_buf->roam_trigger_reason) 19825 src_data = ¶m_buf->roam_trigger_reason[idx]; 19826 19827 if (cmn_data) { 19828 trig_reason = cmn_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(cmn_data->trigger_sub_reason); 19833 trig->timestamp = cmn_data->timestamp; 19834 trig->common_roam = true; 19835 } else if (src_data) { 19836 trig_reason = src_data->trigger_reason; 19837 trig->trigger_reason = 19838 wmi_convert_fw_to_cm_trig_reason(trig_reason); 19839 trig->trigger_sub_reason = 19840 wmi_convert_roam_sub_reason(src_data->trigger_sub_reason); 19841 trig->current_rssi = src_data->current_rssi; 19842 trig->timestamp = src_data->timestamp; 19843 trig->common_roam = false; 19844 } 19845 19846 if (param_buf->roam_trigger_rssi) 19847 rssi_data = ¶m_buf->roam_trigger_rssi[idx]; 19848 19849 if (param_buf->roam_result) { 19850 roam_result = ¶m_buf->roam_result[idx]; 19851 19852 if (roam_result) { 19853 trig->roam_status = roam_result->roam_status; 19854 if (trig->roam_status) { 19855 fail_reason = roam_result->roam_fail_reason; 19856 trig->fail_reason = 19857 wlan_roam_fail_reason_code(fail_reason); 19858 19859 if (rssi_data) { 19860 abort = roam_result->roam_abort_reason; 19861 trig->abort_reason.abort_reason_code = 19862 wmi_convert_roam_abort_reason(abort); 19863 trig->abort_reason.data_rssi = 19864 rssi_data->data_rssi; 19865 trig->abort_reason.data_rssi_threshold = 19866 rssi_data->data_rssi_threshold; 19867 trig->abort_reason.rx_linkspeed_status = 19868 rssi_data->rx_linkspeed_status; 19869 } 19870 } 19871 } 19872 } 19873 19874 if (scan_info) 19875 trig->scan_type = 19876 wlan_roam_scan_type(scan_info->roam_scan_type); 19877 19878 switch (trig_reason) { 19879 case WMI_ROAM_TRIGGER_REASON_PER: 19880 if (param_buf->roam_trigger_per) 19881 per_data = ¶m_buf->roam_trigger_per[idx]; 19882 if (per_data) { 19883 trig->per_trig_data.tx_rate_thresh_percent = 19884 WMI_GET_BITS(per_data->rate_thresh_percnt, 19885 WLAN_ROAM_PER_RX_RATE_OFFSET, 8); 19886 trig->per_trig_data.rx_rate_thresh_percent = 19887 WMI_GET_BITS(per_data->rate_thresh_percnt, 19888 WLAN_ROAM_PER_TX_RATE_OFFSET, 8); 19889 } 19890 return QDF_STATUS_SUCCESS; 19891 19892 case WMI_ROAM_TRIGGER_REASON_BMISS: 19893 if (param_buf->roam_trigger_bmiss) 19894 bmiss_data = ¶m_buf->roam_trigger_bmiss[idx]; 19895 if (bmiss_data) { 19896 trig->bmiss_trig_data.final_bmiss_cnt = 19897 WMI_GET_BITS(bmiss_data->bmiss_status, 19898 WLAN_ROAM_BMISS_FINNAL_OFFSET, 7); 19899 trig->bmiss_trig_data.consecutive_bmiss_cnt = 19900 WMI_GET_BITS(bmiss_data->bmiss_status, 19901 WLAN_ROAM_BMISS_CONSECUTIVE_OFFSET, 19902 17); 19903 trig->bmiss_trig_data.qos_null_success = 19904 WMI_GET_BITS(bmiss_data->bmiss_status, 19905 WLAN_ROAM_BMISS_QOSNULL_OFFSET, 1); 19906 } 19907 return QDF_STATUS_SUCCESS; 19908 19909 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI: 19910 if (param_buf->roam_trigger_hi_rssi) 19911 hi_rssi_data = ¶m_buf->roam_trigger_hi_rssi[idx]; 19912 19913 if (hi_rssi_data && cmn_data) { 19914 trig->hi_rssi_trig_data.current_rssi = 19915 (uint8_t)cmn_data->current_rssi; 19916 trig->hi_rssi_trig_data.hirssi_threshold = 19917 (uint8_t)hi_rssi_data->hi_rssi_threshold; 19918 } 19919 return QDF_STATUS_SUCCESS; 19920 19921 case WMI_ROAM_TRIGGER_REASON_MAWC: 19922 case WMI_ROAM_TRIGGER_REASON_DENSE: 19923 if (param_buf->roam_trigger_dense) 19924 dense_data = ¶m_buf->roam_trigger_dense[idx]; 19925 if (dense_data) { 19926 trig->congestion_trig_data.rx_tput = 19927 dense_data->rx_tput; 19928 trig->congestion_trig_data.tx_tput = 19929 dense_data->tx_tput; 19930 trig->congestion_trig_data.roamable_count = 19931 WMI_GET_BITS(dense_data->dense_status, 19932 WLAN_ROAM_DENSE_ROAMABLE_OFFSET, 19933 8); 19934 } 19935 return QDF_STATUS_SUCCESS; 19936 19937 case WMI_ROAM_TRIGGER_REASON_BACKGROUND: 19938 if (cmn_data && rssi_data) { 19939 trig->background_trig_data.current_rssi = 19940 (uint8_t)cmn_data->current_rssi; 19941 trig->background_trig_data.data_rssi = 19942 (uint8_t)rssi_data->data_rssi; 19943 trig->background_trig_data.data_rssi_threshold = 19944 (uint8_t)rssi_data->data_rssi_threshold; 19945 } 19946 return QDF_STATUS_SUCCESS; 19947 19948 case WMI_ROAM_TRIGGER_REASON_IDLE: 19949 case WMI_ROAM_TRIGGER_REASON_FORCED: 19950 if (param_buf->roam_trigger_force) 19951 force_data = ¶m_buf->roam_trigger_force[idx]; 19952 if (force_data) { 19953 invoke = force_data->invoke_reason; 19954 trig->user_trig_data.invoke_reason = 19955 wmi_convert_to_cm_roam_invoke_reason(invoke); 19956 } 19957 return QDF_STATUS_SUCCESS; 19958 19959 case WMI_ROAM_TRIGGER_REASON_UNIT_TEST: 19960 case WMI_ROAM_TRIGGER_REASON_BTC: 19961 return QDF_STATUS_SUCCESS; 19962 19963 case WMI_ROAM_TRIGGER_REASON_BTM: 19964 if (param_buf->roam_trigger_btm) 19965 btm_data = ¶m_buf->roam_trigger_btm[idx]; 19966 if (btm_data) { 19967 trig->btm_trig_data.btm_request_mode = 19968 btm_data->btm_request_mode; 19969 trig->btm_trig_data.disassoc_timer = 19970 btm_data->disassoc_imminent_timer; 19971 trig->btm_trig_data.validity_interval = 19972 btm_data->validity_internal; 19973 trig->btm_trig_data.candidate_list_count = 19974 btm_data->candidate_list_count; 19975 trig->btm_trig_data.btm_resp_status = 19976 btm_data->btm_response_status_code; 19977 trig->btm_trig_data.btm_bss_termination_timeout = 19978 btm_data->btm_bss_termination_timeout; 19979 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 19980 btm_data->btm_mbo_assoc_retry_timeout; 19981 trig->btm_trig_data.token = 19982 (uint16_t)btm_data->btm_req_dialog_token; 19983 if (scan_info) { 19984 trig->btm_trig_data.band = 19985 WMI_GET_MLO_BAND(scan_info->flags); 19986 if (trig->btm_trig_data.band != 19987 WMI_MLO_BAND_NO_MLO) 19988 trig->btm_trig_data.is_mlo = true; 19989 } 19990 } else if (src_data) { 19991 trig->btm_trig_data.btm_request_mode = 19992 src_data->btm_request_mode; 19993 trig->btm_trig_data.disassoc_timer = 19994 src_data->disassoc_imminent_timer; 19995 trig->btm_trig_data.validity_interval = 19996 src_data->validity_internal; 19997 trig->btm_trig_data.candidate_list_count = 19998 src_data->candidate_list_count; 19999 trig->btm_trig_data.btm_resp_status = 20000 src_data->btm_response_status_code; 20001 trig->btm_trig_data.btm_bss_termination_timeout = 20002 src_data->btm_bss_termination_timeout; 20003 trig->btm_trig_data.btm_mbo_assoc_retry_timeout = 20004 src_data->btm_mbo_assoc_retry_timeout; 20005 trig->btm_trig_data.token = 20006 src_data->btm_req_dialog_token; 20007 if (scan_info) { 20008 trig->btm_trig_data.band = 20009 WMI_GET_MLO_BAND(scan_info->flags); 20010 if (trig->btm_trig_data.band != 20011 WMI_MLO_BAND_NO_MLO) 20012 trig->btm_trig_data.is_mlo = true; 20013 } 20014 if ((btm_idx + 20015 trig->btm_trig_data.candidate_list_count) <= 20016 param_buf->num_roam_btm_request_candidate_info) 20017 extract_roam_11kv_candidate_info( 20018 wmi_handle, evt_buf, 20019 trig->btm_trig_data.btm_cand, 20020 btm_idx, 20021 src_data->candidate_list_count); 20022 } 20023 20024 return QDF_STATUS_SUCCESS; 20025 20026 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD: 20027 if (param_buf->roam_trigger_bss_load) 20028 bss_load_data = ¶m_buf->roam_trigger_bss_load[idx]; 20029 if (bss_load_data) 20030 trig->cu_trig_data.cu_load = bss_load_data->cu_load; 20031 else if (src_data) 20032 trig->cu_trig_data.cu_load = src_data->cu_load; 20033 return QDF_STATUS_SUCCESS; 20034 20035 case WMI_ROAM_TRIGGER_REASON_DEAUTH: 20036 if (param_buf->roam_trigger_deauth) 20037 deauth_data = ¶m_buf->roam_trigger_deauth[idx]; 20038 if (deauth_data) { 20039 trig->deauth_trig_data.type = deauth_data->deauth_type; 20040 trig->deauth_trig_data.reason = 20041 deauth_data->deauth_reason; 20042 } else if (src_data) { 20043 trig->deauth_trig_data.type = src_data->deauth_type; 20044 trig->deauth_trig_data.reason = src_data->deauth_reason; 20045 } 20046 return QDF_STATUS_SUCCESS; 20047 20048 case WMI_ROAM_TRIGGER_REASON_PERIODIC: 20049 if (param_buf->roam_trigger_periodic) 20050 periodic_data = ¶m_buf->roam_trigger_periodic[idx]; 20051 if (periodic_data) { 20052 trig->periodic_trig_data.periodic_timer_ms = 20053 periodic_data->periodic_timer_ms; 20054 } else if (src_data) 20055 trig->rssi_trig_data.threshold = 20056 src_data->roam_rssi_threshold; 20057 return QDF_STATUS_SUCCESS; 20058 20059 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: 20060 if (cmn_data && rssi_data) { 20061 trig->low_rssi_trig_data.current_rssi = 20062 (uint8_t)cmn_data->current_rssi; 20063 trig->low_rssi_trig_data.roam_rssi_threshold = 20064 (uint8_t)rssi_data->roam_rssi_threshold; 20065 trig->low_rssi_trig_data.rx_linkspeed_status = 20066 (uint8_t)rssi_data->rx_linkspeed_status; 20067 } else if (src_data) 20068 trig->rssi_trig_data.threshold = 20069 src_data->roam_rssi_threshold; 20070 20071 return QDF_STATUS_SUCCESS; 20072 20073 case WMI_ROAM_TRIGGER_REASON_STA_KICKOUT: 20074 if (param_buf->roam_trigger_kickout) 20075 kickout_data = ¶m_buf->roam_trigger_kickout[idx]; 20076 if (kickout_data) { 20077 tx_fail = kickout_data->kickout_reason; 20078 trig->tx_failures_trig_data.kickout_threshold = 20079 kickout_data->kickout_th; 20080 trig->tx_failures_trig_data.kickout_reason = 20081 wmi_convert_to_cm_roam_tx_fail_reason(tx_fail); 20082 } 20083 return QDF_STATUS_SUCCESS; 20084 20085 case WMI_ROAM_TRIGGER_REASON_WTC_BTM: 20086 if (src_data) { 20087 trig->wtc_btm_trig_data.roaming_mode = 20088 src_data->vendor_specific1[0]; 20089 trig->wtc_btm_trig_data.vsie_trigger_reason = 20090 src_data->vendor_specific1[1]; 20091 trig->wtc_btm_trig_data.sub_code = 20092 src_data->vendor_specific1[2]; 20093 trig->wtc_btm_trig_data.wtc_mode = 20094 src_data->vendor_specific1[3]; 20095 trig->wtc_btm_trig_data.wtc_scan_mode = 20096 convert_wtc_scan_mode(src_data->vendor_specific1[4]); 20097 trig->wtc_btm_trig_data.wtc_rssi_th = 20098 src_data->vendor_specific1[5]; 20099 trig->wtc_btm_trig_data.wtc_candi_rssi_th = 20100 src_data->vendor_specific1[6]; 20101 20102 trig->wtc_btm_trig_data.wtc_candi_rssi_ext_present = 20103 src_data->vendor_specific2[0]; 20104 trig->wtc_btm_trig_data.wtc_candi_rssi_th_5g = 20105 src_data->vendor_specific2[1]; 20106 trig->wtc_btm_trig_data.wtc_candi_rssi_th_6g = 20107 src_data->vendor_specific2[2]; 20108 trig->wtc_btm_trig_data.duration = 20109 src_data->vendor_specific2[3]; 20110 } 20111 return QDF_STATUS_SUCCESS; 20112 default: 20113 return QDF_STATUS_SUCCESS; 20114 } 20115 20116 return QDF_STATUS_SUCCESS; 20117 } 20118 20119 /** 20120 * extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats 20121 * from the WMI_ROAM_STATS_EVENTID 20122 * @wmi_handle: wmi handle 20123 * @evt_buf: Pointer to the event buffer 20124 * @dst: Pointer to destination structure to fill data 20125 * @ap_idx: TLV index for this roam scan 20126 * @num_cand: number of candidates list in the roam scan 20127 */ 20128 static QDF_STATUS 20129 extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20130 struct wmi_roam_candidate_info *dst, 20131 uint8_t ap_idx, uint16_t num_cand) 20132 { 20133 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20134 wmi_roam_ap_info *src = NULL; 20135 uint8_t i; 20136 20137 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20138 if (!param_buf) { 20139 wmi_err("Param buf is NULL"); 20140 return QDF_STATUS_E_FAILURE; 20141 } 20142 20143 if (ap_idx >= param_buf->num_roam_ap_info) { 20144 wmi_err("Invalid roam scan AP tlv ap_idx:%d total_ap:%d", 20145 ap_idx, param_buf->num_roam_ap_info); 20146 return QDF_STATUS_E_FAILURE; 20147 } 20148 20149 src = ¶m_buf->roam_ap_info[ap_idx]; 20150 20151 for (i = 0; i < num_cand; i++) { 20152 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes); 20153 dst->type = src->candidate_type; 20154 dst->freq = src->channel; 20155 dst->etp = src->etp; 20156 dst->rssi = src->rssi; 20157 dst->rssi_score = src->rssi_score; 20158 dst->cu_load = src->cu_load; 20159 dst->cu_score = src->cu_score; 20160 dst->total_score = src->total_score; 20161 dst->timestamp = src->timestamp; 20162 dst->dl_reason = src->bl_reason; 20163 dst->dl_source = src->bl_source; 20164 dst->dl_timestamp = src->bl_timestamp; 20165 dst->dl_original_timeout = src->bl_original_timeout; 20166 dst->is_mlo = WMI_GET_AP_INFO_MLO_STATUS(src->flags); 20167 20168 src++; 20169 dst++; 20170 } 20171 20172 return QDF_STATUS_SUCCESS; 20173 } 20174 20175 #define ROAM_SUCCESS 0 20176 20177 /** 20178 * extract_roam_scan_stats_tlv() - Extract the Roam trigger stats 20179 * from the WMI_ROAM_STATS_EVENTID 20180 * @wmi_handle: wmi handle 20181 * @evt_buf: Pointer to the event buffer 20182 * @dst: Pointer to destination structure to fill data 20183 * @idx: TLV id 20184 * @chan_idx: Index of the channel tlv for the current roam trigger 20185 * @ap_idx: Index of the candidate AP TLV for the current roam trigger 20186 */ 20187 static QDF_STATUS 20188 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20189 struct wmi_roam_scan_data *dst, uint8_t idx, 20190 uint8_t chan_idx, uint8_t ap_idx) 20191 { 20192 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20193 wmi_roam_scan_info *src_data = NULL; 20194 wmi_roam_scan_channel_info *src_chan = NULL; 20195 QDF_STATUS status; 20196 uint8_t i; 20197 20198 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20199 if (!param_buf || !param_buf->roam_scan_info || 20200 idx >= param_buf->num_roam_scan_info) 20201 return QDF_STATUS_E_FAILURE; 20202 20203 src_data = ¶m_buf->roam_scan_info[idx]; 20204 20205 dst->present = true; 20206 dst->type = src_data->roam_scan_type; 20207 dst->num_chan = src_data->roam_scan_channel_count; 20208 dst->scan_complete_timestamp = src_data->scan_complete_timestamp; 20209 dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold; 20210 dst->is_btcoex_active = WMI_GET_BTCONNECT_STATUS(src_data->flags); 20211 dst->frame_info_count = src_data->frame_info_count; 20212 if (dst->frame_info_count > WLAN_ROAM_MAX_FRAME_INFO) 20213 dst->frame_info_count = WLAN_ROAM_MAX_FRAME_INFO; 20214 20215 dst->band = WMI_GET_MLO_BAND(src_data->flags); 20216 if (dst->band != WMI_MLO_BAND_NO_MLO) 20217 dst->is_mlo = true; 20218 20219 /* Read the channel data only for dst->type is 0 (partial scan) */ 20220 if (dst->num_chan && !dst->type && param_buf->num_roam_scan_chan_info && 20221 chan_idx < param_buf->num_roam_scan_chan_info) { 20222 if (dst->num_chan > MAX_ROAM_SCAN_CHAN) 20223 dst->num_chan = MAX_ROAM_SCAN_CHAN; 20224 20225 src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; 20226 20227 if ((dst->num_chan + chan_idx) > 20228 param_buf->num_roam_scan_chan_info) { 20229 wmi_err("Invalid TLV. num_chan %d chan_idx %d num_roam_scan_chan_info %d", 20230 dst->num_chan, chan_idx, 20231 param_buf->num_roam_scan_chan_info); 20232 return QDF_STATUS_SUCCESS; 20233 } 20234 20235 for (i = 0; i < dst->num_chan; i++) { 20236 dst->chan_freq[i] = src_chan->channel; 20237 dst->dwell_type[i] = 20238 (uint8_t)wlan_roam_dwell_type(src_chan->ch_dwell_type); 20239 src_chan++; 20240 } 20241 } 20242 20243 if (!src_data->roam_ap_count || !param_buf->num_roam_ap_info) 20244 return QDF_STATUS_SUCCESS; 20245 20246 dst->num_ap = src_data->roam_ap_count; 20247 if (dst->num_ap > MAX_ROAM_CANDIDATE_AP) 20248 dst->num_ap = MAX_ROAM_CANDIDATE_AP; 20249 20250 status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap, 20251 ap_idx, dst->num_ap); 20252 if (QDF_IS_STATUS_ERROR(status)) { 20253 wmi_err("Extract candidate stats for tlv[%d] failed", idx); 20254 return status; 20255 } 20256 20257 return QDF_STATUS_SUCCESS; 20258 } 20259 20260 /** 20261 * extract_roam_result_stats_tlv() - Extract the Roam trigger stats 20262 * from the WMI_ROAM_STATS_EVENTID 20263 * @wmi_handle: wmi handle 20264 * @evt_buf: Pointer to the event buffer 20265 * @dst: Pointer to destination structure to fill data 20266 * @idx: TLV id 20267 */ 20268 static QDF_STATUS 20269 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20270 struct wmi_roam_result *dst, uint8_t idx) 20271 { 20272 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20273 wmi_roam_result *src_data = NULL; 20274 20275 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20276 if (!param_buf || !param_buf->roam_result || 20277 idx >= param_buf->num_roam_result) 20278 return QDF_STATUS_E_FAILURE; 20279 20280 src_data = ¶m_buf->roam_result[idx]; 20281 20282 dst->present = true; 20283 dst->status = src_data->roam_status; 20284 dst->timestamp = src_data->timestamp; 20285 dst->roam_abort_reason = src_data->roam_abort_reason; 20286 if (src_data->roam_fail_reason != ROAM_SUCCESS) 20287 dst->fail_reason = 20288 wlan_roam_fail_reason_code(src_data->roam_fail_reason); 20289 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes); 20290 20291 return QDF_STATUS_SUCCESS; 20292 } 20293 20294 /** 20295 * extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats 20296 * from the WMI_ROAM_STATS_EVENTID 20297 * @wmi_handle: wmi handle 20298 * @evt_buf: Pointer to the event buffer 20299 * @dst: Pointer to destination structure to fill data 20300 * @idx: TLV id 20301 * @rpt_idx: Neighbor report Channel index 20302 */ 20303 static QDF_STATUS 20304 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20305 struct wmi_neighbor_report_data *dst, 20306 uint8_t idx, uint8_t rpt_idx) 20307 { 20308 WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; 20309 wmi_roam_neighbor_report_info *src_data = NULL; 20310 wmi_roam_neighbor_report_channel_info *src_freq = NULL; 20311 uint8_t i; 20312 20313 param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; 20314 if (!param_buf || !param_buf->roam_neighbor_report_info || 20315 !param_buf->num_roam_neighbor_report_info || 20316 idx >= param_buf->num_roam_neighbor_report_info) { 20317 wmi_debug("Invalid 1kv param buf"); 20318 return QDF_STATUS_E_FAILURE; 20319 } 20320 20321 src_data = ¶m_buf->roam_neighbor_report_info[idx]; 20322 20323 dst->present = true; 20324 dst->req_type = src_data->request_type; 20325 dst->num_freq = src_data->neighbor_report_channel_count; 20326 dst->req_time = src_data->neighbor_report_request_timestamp; 20327 dst->resp_time = src_data->neighbor_report_response_timestamp; 20328 dst->btm_query_token = src_data->btm_query_token; 20329 dst->btm_query_reason = src_data->btm_query_reason_code; 20330 dst->req_token = 20331 WMI_ROAM_NEIGHBOR_REPORT_INFO_REQUEST_TOKEN_GET(src_data->neighbor_report_detail); 20332 dst->resp_token = 20333 WMI_ROAM_NEIGHBOR_REPORT_INFO_RESPONSE_TOKEN_GET(src_data->neighbor_report_detail); 20334 dst->num_rpt = 20335 WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_GET(src_data->neighbor_report_detail); 20336 20337 dst->band = 20338 WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET(src_data->neighbor_report_detail); 20339 20340 if (dst->band != WMI_MLO_BAND_NO_MLO) 20341 dst->is_mlo = true; 20342 20343 if (!dst->num_freq || !param_buf->num_roam_neighbor_report_chan_info || 20344 rpt_idx >= param_buf->num_roam_neighbor_report_chan_info) 20345 return QDF_STATUS_SUCCESS; 20346 20347 if (!param_buf->roam_neighbor_report_chan_info) { 20348 wmi_debug("11kv channel present, but TLV is NULL num_freq:%d", 20349 dst->num_freq); 20350 dst->num_freq = 0; 20351 /* return success as its optional tlv and we can print neighbor 20352 * report received info 20353 */ 20354 return QDF_STATUS_SUCCESS; 20355 } 20356 20357 src_freq = ¶m_buf->roam_neighbor_report_chan_info[rpt_idx]; 20358 20359 if (dst->num_freq > MAX_ROAM_SCAN_CHAN) 20360 dst->num_freq = MAX_ROAM_SCAN_CHAN; 20361 20362 if ((dst->num_freq + rpt_idx) > 20363 param_buf->num_roam_neighbor_report_chan_info) { 20364 wmi_err("Invalid TLV. num_freq %d rpt_idx %d num_roam_neighbor_report_chan_info %d", 20365 dst->num_freq, rpt_idx, 20366 param_buf->num_roam_scan_chan_info); 20367 return QDF_STATUS_SUCCESS; 20368 } 20369 20370 for (i = 0; i < dst->num_freq; i++) { 20371 dst->freq[i] = src_freq->channel; 20372 src_freq++; 20373 } 20374 20375 return QDF_STATUS_SUCCESS; 20376 } 20377 20378 /** 20379 * send_roam_set_param_cmd_tlv() - WMI roam set parameter function 20380 * @wmi_handle: handle to WMI. 20381 * @roam_param: pointer to hold roam set parameter 20382 * 20383 * Return: QDF_STATUS_SUCCESS for success or error code 20384 */ 20385 static QDF_STATUS 20386 send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle, 20387 struct vdev_set_params *roam_param) 20388 { 20389 QDF_STATUS ret; 20390 wmi_roam_set_param_cmd_fixed_param *cmd; 20391 wmi_buf_t buf; 20392 uint16_t len = sizeof(*cmd); 20393 20394 buf = wmi_buf_alloc(wmi_handle, len); 20395 if (!buf) 20396 return QDF_STATUS_E_NOMEM; 20397 20398 cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf); 20399 WMITLV_SET_HDR(&cmd->tlv_header, 20400 WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param, 20401 WMITLV_GET_STRUCT_TLVLEN 20402 (wmi_roam_set_param_cmd_fixed_param)); 20403 cmd->vdev_id = roam_param->vdev_id; 20404 cmd->param_id = roam_param->param_id; 20405 cmd->param_value = roam_param->param_value; 20406 wmi_debug("Setting vdev %d roam_param = %x, value = %u", 20407 cmd->vdev_id, cmd->param_id, cmd->param_value); 20408 wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0); 20409 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20410 WMI_ROAM_SET_PARAM_CMDID); 20411 if (QDF_IS_STATUS_ERROR(ret)) { 20412 wmi_err("Failed to send roam set param command, ret = %d", ret); 20413 wmi_buf_free(buf); 20414 } 20415 20416 return ret; 20417 } 20418 #else 20419 static inline QDF_STATUS 20420 extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20421 struct wmi_roam_trigger_info *trig, uint8_t idx, 20422 uint8_t btm_idx) 20423 { 20424 return QDF_STATUS_E_NOSUPPORT; 20425 } 20426 20427 static inline QDF_STATUS 20428 extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20429 struct wmi_roam_result *dst, uint8_t idx) 20430 { 20431 return QDF_STATUS_E_NOSUPPORT; 20432 } 20433 20434 static QDF_STATUS 20435 extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20436 struct wmi_neighbor_report_data *dst, 20437 uint8_t idx, uint8_t rpt_idx) 20438 { 20439 return QDF_STATUS_E_NOSUPPORT; 20440 } 20441 20442 static QDF_STATUS 20443 extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20444 struct wmi_roam_scan_data *dst, uint8_t idx, 20445 uint8_t chan_idx, uint8_t ap_idx) 20446 { 20447 return QDF_STATUS_E_NOSUPPORT; 20448 } 20449 #endif 20450 20451 #ifdef WLAN_FEATURE_PKT_CAPTURE 20452 static QDF_STATUS 20453 extract_vdev_mgmt_offload_event_tlv(void *handle, void *evt_buf, 20454 struct mgmt_offload_event_params *params) 20455 { 20456 WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *param_tlvs; 20457 wmi_mgmt_hdr *hdr; 20458 20459 param_tlvs = (WMI_VDEV_MGMT_OFFLOAD_EVENTID_param_tlvs *)evt_buf; 20460 if (!param_tlvs) 20461 return QDF_STATUS_E_INVAL; 20462 20463 hdr = param_tlvs->fixed_param; 20464 if (!hdr) 20465 return QDF_STATUS_E_INVAL; 20466 20467 if (hdr->buf_len > param_tlvs->num_bufp) 20468 return QDF_STATUS_E_INVAL; 20469 20470 params->tsf_l32 = hdr->tsf_l32; 20471 params->chan_freq = hdr->chan_freq; 20472 params->rate_kbps = hdr->rate_kbps; 20473 params->rssi = hdr->rssi; 20474 params->buf_len = hdr->buf_len; 20475 params->tx_status = hdr->tx_status; 20476 params->buf = param_tlvs->bufp; 20477 params->tx_retry_cnt = hdr->tx_retry_cnt; 20478 return QDF_STATUS_SUCCESS; 20479 } 20480 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 20481 20482 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 20483 static QDF_STATUS 20484 extract_smart_monitor_event_tlv(void *handle, void *evt_buf, 20485 struct smu_event_params *params) 20486 { 20487 WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *param_buf = NULL; 20488 wmi_vdev_smart_monitor_event_fixed_param *smu_event = NULL; 20489 20490 param_buf = (WMI_VDEV_SMART_MONITOR_EVENTID_param_tlvs *)evt_buf; 20491 if (!param_buf) { 20492 wmi_err("Invalid smart monitor event"); 20493 return QDF_STATUS_E_INVAL; 20494 } 20495 20496 smu_event = param_buf->fixed_param; 20497 if (!smu_event) { 20498 wmi_err("smart monitor event fixed param is NULL"); 20499 return QDF_STATUS_E_INVAL; 20500 } 20501 20502 params->vdev_id = smu_event->vdev_id; 20503 if (params->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 20504 return QDF_STATUS_E_INVAL; 20505 20506 params->rx_vht_sgi = smu_event->rx_vht_sgi; 20507 20508 return QDF_STATUS_SUCCESS; 20509 } 20510 #endif /* WLAN_FEATURE_PKT_CAPTURE_V2 */ 20511 20512 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 20513 /** 20514 * send_wlan_ts_ftm_trigger_cmd_tlv(): send wlan time sync cmd to FW 20515 * 20516 * @wmi: wmi handle 20517 * @vdev_id: vdev id 20518 * @burst_mode: Indicates whether relation derived using FTM is needed for 20519 * each FTM frame or only aggregated result is required. 20520 * 20521 * Send WMI_AUDIO_SYNC_TRIGGER_CMDID to FW. 20522 * 20523 * Return: QDF_STATUS 20524 */ 20525 static QDF_STATUS send_wlan_ts_ftm_trigger_cmd_tlv(wmi_unified_t wmi, 20526 uint32_t vdev_id, 20527 bool burst_mode) 20528 { 20529 wmi_audio_sync_trigger_cmd_fixed_param *cmd; 20530 wmi_buf_t buf; 20531 int32_t len = sizeof(*cmd); 20532 20533 buf = wmi_buf_alloc(wmi, len); 20534 if (!buf) { 20535 wmi_err("wmi_buf_alloc failed"); 20536 return QDF_STATUS_E_NOMEM; 20537 } 20538 cmd = (wmi_audio_sync_trigger_cmd_fixed_param *)wmi_buf_data(buf); 20539 WMITLV_SET_HDR(&cmd->tlv_header, 20540 WMITLV_TAG_STRUC_wmi_audio_sync_trigger_cmd_fixed_param, 20541 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_trigger_cmd_fixed_param)); 20542 cmd->vdev_id = vdev_id; 20543 cmd->agg_relation = burst_mode ? false : true; 20544 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID)) { 20545 wmi_err("Failed to send audio sync trigger cmd"); 20546 wmi_buf_free(buf); 20547 return QDF_STATUS_E_FAILURE; 20548 } 20549 20550 return QDF_STATUS_SUCCESS; 20551 } 20552 20553 static QDF_STATUS send_wlan_ts_qtime_cmd_tlv(wmi_unified_t wmi, 20554 uint32_t vdev_id, 20555 uint64_t lpass_ts) 20556 { 20557 wmi_audio_sync_qtimer_cmd_fixed_param *cmd; 20558 wmi_buf_t buf; 20559 int32_t len = sizeof(*cmd); 20560 20561 buf = wmi_buf_alloc(wmi, len); 20562 if (!buf) { 20563 wmi_err("wmi_buf_alloc failed"); 20564 return QDF_STATUS_E_NOMEM; 20565 } 20566 cmd = (wmi_audio_sync_qtimer_cmd_fixed_param *)wmi_buf_data(buf); 20567 WMITLV_SET_HDR(&cmd->tlv_header, 20568 WMITLV_TAG_STRUC_wmi_audio_sync_qtimer_cmd_fixed_param, 20569 WMITLV_GET_STRUCT_TLVLEN(wmi_audio_sync_qtimer_cmd_fixed_param)); 20570 cmd->vdev_id = vdev_id; 20571 cmd->qtimer_u32 = (uint32_t)((lpass_ts & 0xffffffff00000000LL) >> 32); 20572 cmd->qtimer_l32 = (uint32_t)(lpass_ts & 0xffffffffLL); 20573 20574 if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID)) { 20575 wmi_err("Failed to send audio qtime command"); 20576 wmi_buf_free(buf); 20577 return QDF_STATUS_E_FAILURE; 20578 } 20579 20580 return QDF_STATUS_SUCCESS; 20581 } 20582 20583 static QDF_STATUS extract_time_sync_ftm_start_stop_event_tlv( 20584 wmi_unified_t wmi, void *buf, 20585 struct ftm_time_sync_start_stop_params *param) 20586 { 20587 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *param_buf; 20588 wmi_audio_sync_start_stop_event_fixed_param *resp_event; 20589 20590 param_buf = (WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID_param_tlvs *)buf; 20591 if (!param_buf) { 20592 wmi_err("Invalid audio sync start stop event buffer"); 20593 return QDF_STATUS_E_FAILURE; 20594 } 20595 20596 resp_event = param_buf->fixed_param; 20597 if (!resp_event) { 20598 wmi_err("Invalid audio sync start stop fixed param buffer"); 20599 return QDF_STATUS_E_FAILURE; 20600 } 20601 20602 param->vdev_id = resp_event->vdev_id; 20603 param->timer_interval = resp_event->periodicity; 20604 param->num_reads = resp_event->reads_needed; 20605 param->qtime = ((uint64_t)resp_event->qtimer_u32 << 32) | 20606 resp_event->qtimer_l32; 20607 param->mac_time = ((uint64_t)resp_event->mac_timer_u32 << 32) | 20608 resp_event->mac_timer_l32; 20609 20610 wmi_debug("FTM time sync time_interval %d, num_reads %d", 20611 param->timer_interval, param->num_reads); 20612 20613 return QDF_STATUS_SUCCESS; 20614 } 20615 20616 static QDF_STATUS 20617 extract_time_sync_ftm_offset_event_tlv(wmi_unified_t wmi, void *buf, 20618 struct ftm_time_sync_offset *param) 20619 { 20620 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *param_buf; 20621 wmi_audio_sync_q_master_slave_offset_event_fixed_param *resp_event; 20622 wmi_audio_sync_q_master_slave_times *q_pair; 20623 int iter; 20624 20625 param_buf = 20626 (WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID_param_tlvs *)buf; 20627 if (!param_buf) { 20628 wmi_err("Invalid timesync ftm offset event buffer"); 20629 return QDF_STATUS_E_FAILURE; 20630 } 20631 20632 resp_event = param_buf->fixed_param; 20633 if (!resp_event) { 20634 wmi_err("Invalid timesync ftm offset fixed param buffer"); 20635 return QDF_STATUS_E_FAILURE; 20636 } 20637 20638 param->vdev_id = resp_event->vdev_id; 20639 param->num_qtime = param_buf->num_audio_sync_q_master_slave_times; 20640 if (param->num_qtime > FTM_TIME_SYNC_QTIME_PAIR_MAX) 20641 param->num_qtime = FTM_TIME_SYNC_QTIME_PAIR_MAX; 20642 20643 q_pair = param_buf->audio_sync_q_master_slave_times; 20644 if (!q_pair) { 20645 wmi_err("Invalid q_master_slave_times buffer"); 20646 return QDF_STATUS_E_FAILURE; 20647 } 20648 20649 for (iter = 0; iter < param->num_qtime; iter++) { 20650 param->pairs[iter].qtime_initiator = ( 20651 (uint64_t)q_pair[iter].qmaster_u32 << 32) | 20652 q_pair[iter].qmaster_l32; 20653 param->pairs[iter].qtime_target = ( 20654 (uint64_t)q_pair[iter].qslave_u32 << 32) | 20655 q_pair[iter].qslave_l32; 20656 } 20657 return QDF_STATUS_SUCCESS; 20658 } 20659 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 20660 20661 /** 20662 * send_vdev_tsf_tstamp_action_cmd_tlv() - send vdev tsf action command 20663 * @wmi: wmi handle 20664 * @vdev_id: vdev id 20665 * 20666 * TSF_TSTAMP_READ_VALUE is the only operation supported 20667 * Return: QDF_STATUS_SUCCESS for success or error code 20668 */ 20669 static QDF_STATUS 20670 send_vdev_tsf_tstamp_action_cmd_tlv(wmi_unified_t wmi, uint8_t vdev_id) 20671 { 20672 wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd; 20673 wmi_buf_t buf; 20674 int32_t len = sizeof(*cmd); 20675 20676 buf = wmi_buf_alloc(wmi, len); 20677 if (!buf) 20678 return QDF_STATUS_E_NOMEM; 20679 20680 cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *)wmi_buf_data(buf); 20681 WMITLV_SET_HDR(&cmd->tlv_header, 20682 WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, 20683 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_tsf_tstamp_action_cmd_fixed_param)); 20684 cmd->vdev_id = vdev_id; 20685 cmd->tsf_action = TSF_TSTAMP_QTIMER_CAPTURE_REQ; 20686 wmi_mtrace(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, cmd->vdev_id, 0); 20687 if (wmi_unified_cmd_send(wmi, buf, len, 20688 WMI_VDEV_TSF_TSTAMP_ACTION_CMDID)) { 20689 wmi_err("%s: Failed to send WMI_VDEV_TSF_TSTAMP_ACTION_CMDID", 20690 __func__); 20691 wmi_buf_free(buf); 20692 return QDF_STATUS_E_FAILURE; 20693 } 20694 20695 return QDF_STATUS_SUCCESS; 20696 } 20697 20698 /** 20699 * extract_vdev_tsf_report_event_tlv() - extract vdev tsf report from event 20700 * @wmi_handle: wmi handle 20701 * @evt_buf: pointer to event buffer 20702 * @param: Pointer to struct to hold event info 20703 * 20704 * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure 20705 */ 20706 static QDF_STATUS 20707 extract_vdev_tsf_report_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 20708 struct wmi_host_tsf_event *param) 20709 { 20710 WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf; 20711 wmi_vdev_tsf_report_event_fixed_param *evt; 20712 20713 param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)evt_buf; 20714 if (!param_buf) { 20715 wmi_err("Invalid tsf report event buffer"); 20716 return QDF_STATUS_E_INVAL; 20717 } 20718 20719 evt = param_buf->fixed_param; 20720 param->vdev_id = evt->vdev_id; 20721 param->tsf = ((uint64_t)(evt->tsf_high) << 32) | evt->tsf_low; 20722 param->tsf_low = evt->tsf_low; 20723 param->tsf_high = evt->tsf_high; 20724 param->qtimer_low = evt->qtimer_low; 20725 param->qtimer_high = evt->qtimer_high; 20726 param->tsf_id = evt->tsf_id; 20727 param->tsf_id_valid = evt->tsf_id_valid; 20728 param->mac_id = evt->mac_id; 20729 param->mac_id_valid = evt->mac_id_valid; 20730 param->wlan_global_tsf_low = evt->wlan_global_tsf_low; 20731 param->wlan_global_tsf_high = evt->wlan_global_tsf_high; 20732 param->tqm_timer_low = evt->tqm_timer_low; 20733 param->tqm_timer_high = evt->tqm_timer_high; 20734 param->use_tqm_timer = evt->use_tqm_timer; 20735 20736 return QDF_STATUS_SUCCESS; 20737 } 20738 20739 /** 20740 * extract_pdev_csa_switch_count_status_tlv() - extract pdev csa switch count 20741 * status tlv 20742 * @wmi_handle: wmi handle 20743 * @evt_buf: pointer to event buffer 20744 * @param: Pointer to hold csa switch count status event param 20745 * 20746 * Return: QDF_STATUS_SUCCESS for success or error code 20747 */ 20748 static QDF_STATUS extract_pdev_csa_switch_count_status_tlv( 20749 wmi_unified_t wmi_handle, 20750 void *evt_buf, 20751 struct pdev_csa_switch_count_status *param) 20752 { 20753 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *param_buf; 20754 wmi_pdev_csa_switch_count_status_event_fixed_param *csa_status; 20755 20756 param_buf = (WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID_param_tlvs *) 20757 evt_buf; 20758 if (!param_buf) { 20759 wmi_err("Invalid CSA status event"); 20760 return QDF_STATUS_E_INVAL; 20761 } 20762 20763 csa_status = param_buf->fixed_param; 20764 20765 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 20766 wmi_handle, 20767 csa_status->pdev_id); 20768 param->current_switch_count = csa_status->current_switch_count; 20769 param->num_vdevs = csa_status->num_vdevs; 20770 param->vdev_ids = param_buf->vdev_ids; 20771 20772 return QDF_STATUS_SUCCESS; 20773 } 20774 20775 #ifdef CONFIG_AFC_SUPPORT 20776 /** 20777 * send_afc_cmd_tlv() - Sends the AFC indication to FW 20778 * @wmi_handle: wmi handle 20779 * @pdev_id: Pdev id 20780 * @param: Pointer to hold AFC indication. 20781 * 20782 * Return: QDF_STATUS_SUCCESS for success or error code 20783 */ 20784 static 20785 QDF_STATUS send_afc_cmd_tlv(wmi_unified_t wmi_handle, 20786 uint8_t pdev_id, 20787 struct reg_afc_resp_rx_ind_info *param) 20788 { 20789 wmi_buf_t buf; 20790 wmi_afc_cmd_fixed_param *cmd; 20791 uint32_t len; 20792 uint8_t *buf_ptr; 20793 QDF_STATUS ret; 20794 20795 len = sizeof(wmi_afc_cmd_fixed_param); 20796 buf = wmi_buf_alloc(wmi_handle, len); 20797 if (!buf) 20798 return QDF_STATUS_E_NOMEM; 20799 20800 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20801 cmd = (wmi_afc_cmd_fixed_param *)buf_ptr; 20802 20803 WMITLV_SET_HDR(&cmd->tlv_header, 20804 WMITLV_TAG_STRUC_wmi_afc_cmd_fixed_param, 20805 WMITLV_GET_STRUCT_TLVLEN(wmi_afc_cmd_fixed_param)); 20806 20807 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 20808 wmi_handle, 20809 pdev_id); 20810 cmd->cmd_type = param->cmd_type; 20811 cmd->serv_resp_format = param->serv_resp_format; 20812 20813 wmi_mtrace(WMI_AFC_CMDID, NO_SESSION, 0); 20814 ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_AFC_CMDID); 20815 if (QDF_IS_STATUS_ERROR(ret)) { 20816 wmi_err("Failed to send WMI_AFC_CMDID"); 20817 wmi_buf_free(buf); 20818 return QDF_STATUS_E_FAILURE; 20819 } 20820 20821 return QDF_STATUS_SUCCESS; 20822 } 20823 #endif 20824 20825 /** 20826 * send_set_tpc_power_cmd_tlv() - Sends the set TPC power level to FW 20827 * @wmi_handle: wmi handle 20828 * @vdev_id: vdev id 20829 * @param: Pointer to hold TX power info 20830 * 20831 * Return: QDF_STATUS_SUCCESS for success or error code 20832 */ 20833 static QDF_STATUS send_set_tpc_power_cmd_tlv(wmi_unified_t wmi_handle, 20834 uint8_t vdev_id, 20835 struct reg_tpc_power_info *param) 20836 { 20837 wmi_buf_t buf; 20838 wmi_vdev_set_tpc_power_fixed_param *tpc_power_info_param; 20839 wmi_vdev_ch_power_info *ch_power_info; 20840 uint8_t *buf_ptr; 20841 uint16_t idx; 20842 uint32_t len; 20843 QDF_STATUS ret; 20844 20845 len = sizeof(wmi_vdev_set_tpc_power_fixed_param) + WMI_TLV_HDR_SIZE; 20846 len += (sizeof(wmi_vdev_ch_power_info) * param->num_pwr_levels); 20847 20848 buf = wmi_buf_alloc(wmi_handle, len); 20849 if (!buf) 20850 return QDF_STATUS_E_NOMEM; 20851 20852 buf_ptr = (uint8_t *)wmi_buf_data(buf); 20853 tpc_power_info_param = (wmi_vdev_set_tpc_power_fixed_param *)buf_ptr; 20854 20855 WMITLV_SET_HDR(&tpc_power_info_param->tlv_header, 20856 WMITLV_TAG_STRUC_wmi_vdev_set_tpc_power_cmd_fixed_param, 20857 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_tpc_power_fixed_param)); 20858 20859 tpc_power_info_param->vdev_id = vdev_id; 20860 tpc_power_info_param->psd_power = param->is_psd_power; 20861 tpc_power_info_param->eirp_power = param->eirp_power; 20862 tpc_power_info_param->power_type_6ghz = param->power_type_6g; 20863 wmi_debug("eirp_power = %d is_psd_power = %d", 20864 tpc_power_info_param->eirp_power, 20865 tpc_power_info_param->psd_power); 20866 reg_print_ap_power_type_6ghz(tpc_power_info_param->power_type_6ghz); 20867 20868 buf_ptr += sizeof(wmi_vdev_set_tpc_power_fixed_param); 20869 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 20870 param->num_pwr_levels * sizeof(wmi_vdev_ch_power_info)); 20871 20872 buf_ptr += WMI_TLV_HDR_SIZE; 20873 ch_power_info = (wmi_vdev_ch_power_info *)buf_ptr; 20874 20875 for (idx = 0; idx < param->num_pwr_levels; ++idx) { 20876 WMITLV_SET_HDR(&ch_power_info[idx].tlv_header, 20877 WMITLV_TAG_STRUC_wmi_vdev_ch_power_info, 20878 WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_ch_power_info)); 20879 ch_power_info[idx].chan_cfreq = 20880 param->chan_power_info[idx].chan_cfreq; 20881 ch_power_info[idx].tx_power = 20882 param->chan_power_info[idx].tx_power; 20883 wmi_debug("chan_cfreq = %d tx_power = %d", 20884 ch_power_info[idx].chan_cfreq, 20885 ch_power_info[idx].tx_power); 20886 buf_ptr += sizeof(wmi_vdev_ch_power_info); 20887 } 20888 20889 wmi_mtrace(WMI_VDEV_SET_TPC_POWER_CMDID, vdev_id, 0); 20890 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 20891 WMI_VDEV_SET_TPC_POWER_CMDID); 20892 if (QDF_IS_STATUS_ERROR(ret)) 20893 wmi_buf_free(buf); 20894 20895 20896 return ret; 20897 } 20898 20899 /** 20900 * extract_dpd_status_ev_param_tlv() - extract dpd status from FW event 20901 * @wmi_handle: wmi handle 20902 * @evt_buf: event buffer 20903 * @param: dpd status info 20904 * 20905 * Return: QDF_STATUS_SUCCESS for success or error code 20906 */ 20907 static QDF_STATUS 20908 extract_dpd_status_ev_param_tlv(wmi_unified_t wmi_handle, 20909 void *evt_buf, 20910 struct wmi_host_pdev_get_dpd_status_event *param) 20911 { 20912 WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *param_buf; 20913 wmi_pdev_get_dpd_status_evt_fixed_param *dpd_status; 20914 20915 param_buf = (WMI_PDEV_GET_DPD_STATUS_EVENTID_param_tlvs *)evt_buf; 20916 if (!param_buf) { 20917 wmi_err("Invalid get dpd_status event"); 20918 return QDF_STATUS_E_INVAL; 20919 } 20920 20921 dpd_status = param_buf->fixed_param; 20922 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20923 (wmi_handle, dpd_status->pdev_id); 20924 param->dpd_status = dpd_status->dpd_status; 20925 20926 return QDF_STATUS_SUCCESS; 20927 } 20928 20929 static int 20930 convert_halphy_status(wmi_pdev_get_halphy_cal_status_evt_fixed_param *status, 20931 WMI_HALPHY_CAL_VALID_BITMAP_STATUS valid_bit) 20932 { 20933 if (status->halphy_cal_valid_bmap && valid_bit) 20934 return (status->halphy_cal_status && valid_bit); 20935 20936 return 0; 20937 } 20938 20939 static QDF_STATUS 20940 extract_halphy_cal_status_ev_param_tlv(wmi_unified_t wmi_handle, 20941 void *evt_buf, 20942 struct wmi_host_pdev_get_halphy_cal_status_event *param) 20943 { 20944 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *param_buf; 20945 wmi_pdev_get_halphy_cal_status_evt_fixed_param *halphy_cal_status; 20946 20947 param_buf = (WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID_param_tlvs *)evt_buf; 20948 if (!param_buf) { 20949 wmi_err("Invalid get halphy cal status event"); 20950 return QDF_STATUS_E_INVAL; 20951 } 20952 20953 halphy_cal_status = param_buf->fixed_param; 20954 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 20955 (wmi_handle, halphy_cal_status->pdev_id); 20956 param->halphy_cal_adc_status = 20957 convert_halphy_status(halphy_cal_status, 20958 WMI_HALPHY_CAL_ADC_BMAP); 20959 param->halphy_cal_bwfilter_status = 20960 convert_halphy_status(halphy_cal_status, 20961 WMI_HALPHY_CAL_BWFILTER_BMAP); 20962 param->halphy_cal_pdet_and_pal_status = 20963 convert_halphy_status(halphy_cal_status, 20964 WMI_HALPHY_CAL_PDET_AND_PAL_BMAP); 20965 param->halphy_cal_rxdco_status = 20966 convert_halphy_status(halphy_cal_status, 20967 WMI_HALPHY_CAL_RXDCO_BMAP); 20968 param->halphy_cal_comb_txiq_rxiq_status = 20969 convert_halphy_status(halphy_cal_status, 20970 WMI_HALPHY_CAL_COMB_TXLO_TXIQ_RXIQ_BMAP); 20971 param->halphy_cal_ibf_status = 20972 convert_halphy_status(halphy_cal_status, 20973 WMI_HALPHY_CAL_IBF_BMAP); 20974 param->halphy_cal_pa_droop_status = 20975 convert_halphy_status(halphy_cal_status, 20976 WMI_HALPHY_CAL_PA_DROOP_BMAP); 20977 param->halphy_cal_dac_status = 20978 convert_halphy_status(halphy_cal_status, 20979 WMI_HALPHY_CAL_DAC_BMAP); 20980 param->halphy_cal_ani_status = 20981 convert_halphy_status(halphy_cal_status, 20982 WMI_HALPHY_CAL_ANI_BMAP); 20983 param->halphy_cal_noise_floor_status = 20984 convert_halphy_status(halphy_cal_status, 20985 WMI_HALPHY_CAL_NOISE_FLOOR_BMAP); 20986 20987 return QDF_STATUS_SUCCESS; 20988 } 20989 20990 /** 20991 * set_halphy_cal_fw_status_to_host_status() - Convert set halphy cal status to host enum 20992 * @fw_status: set halphy cal status from WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID event 20993 * 20994 * Return: host_set_halphy_cal_status 20995 */ 20996 static enum wmi_host_set_halphy_cal_status 20997 set_halphy_cal_fw_status_to_host_status(uint32_t fw_status) 20998 { 20999 if (fw_status == 0) 21000 return WMI_HOST_SET_HALPHY_CAL_STATUS_SUCCESS; 21001 else if (fw_status == 1) 21002 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 21003 21004 wmi_debug("Unknown set halphy status code(%u) from WMI", fw_status); 21005 return WMI_HOST_SET_HALPHY_CAL_STATUS_FAIL; 21006 } 21007 21008 /** 21009 * extract_halphy_cal_ev_param_tlv() - extract dpd status from FW event 21010 * @wmi_handle: wmi handle 21011 * @evt_buf: event buffer 21012 * @param: set halphy cal status info 21013 * 21014 * Return: QDF_STATUS_SUCCESS for success or error code 21015 */ 21016 static QDF_STATUS 21017 extract_halphy_cal_ev_param_tlv(wmi_unified_t wmi_handle, 21018 void *evt_buf, 21019 struct wmi_host_pdev_set_halphy_cal_event *param) 21020 { 21021 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *param_buf; 21022 wmi_pdev_set_halphy_cal_bmap_evt_fixed_param *set_halphy_status; 21023 21024 param_buf = (WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID_param_tlvs *)evt_buf; 21025 if (!param_buf) { 21026 wmi_err("Invalid set halphy_status event"); 21027 return QDF_STATUS_E_INVAL; 21028 } 21029 21030 set_halphy_status = param_buf->fixed_param; 21031 param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host 21032 (wmi_handle, set_halphy_status->pdev_id); 21033 param->status = set_halphy_cal_fw_status_to_host_status(set_halphy_status->status); 21034 21035 return QDF_STATUS_SUCCESS; 21036 } 21037 21038 /** 21039 * extract_install_key_comp_event_tlv() - extract install key complete event tlv 21040 * @wmi_handle: wmi handle 21041 * @evt_buf: pointer to event buffer 21042 * @len: length of the event buffer 21043 * @param: Pointer to hold install key complete event param 21044 * 21045 * Return: QDF_STATUS_SUCCESS for success or error code 21046 */ 21047 static QDF_STATUS 21048 extract_install_key_comp_event_tlv(wmi_unified_t wmi_handle, 21049 void *evt_buf, uint32_t len, 21050 struct wmi_install_key_comp_event *param) 21051 { 21052 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf; 21053 wmi_vdev_install_key_complete_event_fixed_param *key_fp; 21054 21055 if (len < sizeof(*param_buf)) { 21056 wmi_err("invalid event buf len %d", len); 21057 return QDF_STATUS_E_INVAL; 21058 } 21059 21060 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *)evt_buf; 21061 if (!param_buf) { 21062 wmi_err("received null buf from target"); 21063 return QDF_STATUS_E_INVAL; 21064 } 21065 21066 key_fp = param_buf->fixed_param; 21067 if (!key_fp) { 21068 wmi_err("received null event data from target"); 21069 return QDF_STATUS_E_INVAL; 21070 } 21071 21072 param->vdev_id = key_fp->vdev_id; 21073 param->key_ix = key_fp->key_ix; 21074 param->key_flags = key_fp->key_flags; 21075 param->status = key_fp->status; 21076 WMI_MAC_ADDR_TO_CHAR_ARRAY(&key_fp->peer_macaddr, 21077 param->peer_macaddr); 21078 21079 return QDF_STATUS_SUCCESS; 21080 } 21081 21082 static QDF_STATUS 21083 send_set_halphy_cal_tlv(wmi_unified_t wmi_handle, 21084 struct wmi_host_send_set_halphy_cal_info *param) 21085 { 21086 wmi_buf_t buf; 21087 wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param *cmd; 21088 QDF_STATUS ret; 21089 uint32_t len; 21090 21091 len = sizeof(*cmd); 21092 21093 buf = wmi_buf_alloc(wmi_handle, len); 21094 if (!buf) 21095 return QDF_STATUS_E_FAILURE; 21096 21097 cmd = (void *)wmi_buf_data(buf); 21098 21099 WMITLV_SET_HDR(&cmd->tlv_header, 21100 WMITLV_TAG_STRUC_wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param, 21101 WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_halphy_cal_bmap_cmd_fixed_param)); 21102 21103 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(wmi_handle, 21104 param->pdev_id); 21105 cmd->online_halphy_cals_bmap = param->value; 21106 cmd->home_scan_channel = param->chan_sel; 21107 21108 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21109 WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID); 21110 if (QDF_IS_STATUS_ERROR(ret)) { 21111 wmi_err("WMI_PDEV_SET_HALPHY_CAL_BMAP_CMDID send returned Error %d",ret); 21112 wmi_buf_free(buf); 21113 } 21114 21115 return ret; 21116 } 21117 21118 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21119 /** 21120 * send_set_mac_address_cmd_tlv() - send set MAC address command to fw 21121 * @wmi: wmi handle 21122 * @params: set MAC address command params 21123 * 21124 * Return: QDF_STATUS_SUCCESS for success or error code 21125 */ 21126 static QDF_STATUS 21127 send_set_mac_address_cmd_tlv(wmi_unified_t wmi, 21128 struct set_mac_addr_params *params) 21129 { 21130 wmi_vdev_update_mac_addr_cmd_fixed_param *cmd; 21131 wmi_buf_t buf; 21132 int32_t len = sizeof(*cmd); 21133 21134 buf = wmi_buf_alloc(wmi, len); 21135 if (!buf) 21136 return QDF_STATUS_E_NOMEM; 21137 21138 cmd = (wmi_vdev_update_mac_addr_cmd_fixed_param *)wmi_buf_data(buf); 21139 WMITLV_SET_HDR( 21140 &cmd->tlv_header, 21141 WMITLV_TAG_STRUC_wmi_vdev_update_mac_addr_cmd_fixed_param, 21142 WMITLV_GET_STRUCT_TLVLEN 21143 (wmi_vdev_update_mac_addr_cmd_fixed_param)); 21144 cmd->vdev_id = params->vdev_id; 21145 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mac_addr.bytes, &cmd->vdev_macaddr); 21146 WMI_CHAR_ARRAY_TO_MAC_ADDR(params->mld_addr.bytes, &cmd->mld_macaddr); 21147 21148 wmi_debug("vdev %d mac_addr " QDF_MAC_ADDR_FMT " mld_addr " 21149 QDF_MAC_ADDR_FMT, cmd->vdev_id, 21150 QDF_MAC_ADDR_REF(params->mac_addr.bytes), 21151 QDF_MAC_ADDR_REF(params->mld_addr.bytes)); 21152 wmi_mtrace(WMI_VDEV_UPDATE_MAC_ADDR_CMDID, cmd->vdev_id, 0); 21153 if (wmi_unified_cmd_send(wmi, buf, len, 21154 WMI_VDEV_UPDATE_MAC_ADDR_CMDID)) { 21155 wmi_buf_free(buf); 21156 return QDF_STATUS_E_FAILURE; 21157 } 21158 21159 return QDF_STATUS_SUCCESS; 21160 } 21161 21162 /** 21163 * extract_update_mac_address_event_tlv() - extract update MAC address event 21164 * @wmi_handle: WMI handle 21165 * @evt_buf: event buffer 21166 * @vdev_id: VDEV ID 21167 * @status: FW status of the set MAC address operation 21168 * 21169 * Return: QDF_STATUS 21170 */ 21171 static QDF_STATUS extract_update_mac_address_event_tlv( 21172 wmi_unified_t wmi_handle, void *evt_buf, 21173 uint8_t *vdev_id, uint8_t *status) 21174 { 21175 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *param_buf; 21176 wmi_vdev_update_mac_addr_conf_event_fixed_param *event; 21177 21178 param_buf = 21179 (WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID_param_tlvs *)evt_buf; 21180 21181 event = param_buf->fixed_param; 21182 21183 *vdev_id = event->vdev_id; 21184 *status = event->status; 21185 21186 return QDF_STATUS_SUCCESS; 21187 } 21188 #endif 21189 21190 #ifdef WLAN_FEATURE_11BE_MLO 21191 /** 21192 * extract_quiet_offload_event_tlv() - extract quiet offload event 21193 * @wmi_handle: WMI handle 21194 * @evt_buf: event buffer 21195 * @quiet_event: quiet event extracted from the buffer 21196 * 21197 * Return: QDF_STATUS 21198 */ 21199 static QDF_STATUS extract_quiet_offload_event_tlv( 21200 wmi_unified_t wmi_handle, void *evt_buf, 21201 struct vdev_sta_quiet_event *quiet_event) 21202 { 21203 WMI_QUIET_HANDLING_EVENTID_param_tlvs *param_buf; 21204 wmi_quiet_event_fixed_param *event; 21205 21206 param_buf = (WMI_QUIET_HANDLING_EVENTID_param_tlvs *)evt_buf; 21207 21208 event = param_buf->fixed_param; 21209 21210 if (!(event->mld_mac_address_present && event->linkid_present) && 21211 !event->link_mac_address_present) { 21212 wmi_err("Invalid sta quiet offload event. present bit: mld mac %d link mac %d linkid %d", 21213 event->mld_mac_address_present, 21214 event->linkid_present, 21215 event->link_mac_address_present); 21216 return QDF_STATUS_E_INVAL; 21217 } 21218 21219 if (event->mld_mac_address_present) 21220 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->mld_mac_address, 21221 quiet_event->mld_mac.bytes); 21222 if (event->link_mac_address_present) 21223 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->link_mac_address, 21224 quiet_event->link_mac.bytes); 21225 if (event->linkid_present) 21226 quiet_event->link_id = event->linkid; 21227 quiet_event->quiet_status = (event->quiet_status == 21228 WMI_QUIET_EVENT_START); 21229 21230 return QDF_STATUS_SUCCESS; 21231 } 21232 #endif 21233 21234 /** 21235 * send_vdev_pn_mgmt_rxfilter_cmd_tlv() - Send PN mgmt RxFilter command to FW 21236 * @wmi_handle: wmi handle 21237 * @params: RxFilter params 21238 * 21239 * Return: QDF_STATUS_SUCCESS for success or error code 21240 */ 21241 static QDF_STATUS 21242 send_vdev_pn_mgmt_rxfilter_cmd_tlv(wmi_unified_t wmi_handle, 21243 struct vdev_pn_mgmt_rxfilter_params *params) 21244 { 21245 wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *cmd; 21246 wmi_buf_t buf; 21247 uint32_t len = sizeof(wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param); 21248 21249 if (!is_service_enabled_tlv(wmi_handle, 21250 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT)) { 21251 wmi_err("Rx PN Replay Check not supported by target"); 21252 return QDF_STATUS_E_NOSUPPORT; 21253 } 21254 21255 buf = wmi_buf_alloc(wmi_handle, len); 21256 if (!buf) { 21257 wmi_err("wmi buf alloc failed"); 21258 return QDF_STATUS_E_NOMEM; 21259 } 21260 21261 cmd = (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param *)wmi_buf_data(buf); 21262 WMITLV_SET_HDR( 21263 &cmd->tlv_header, 21264 WMITLV_TAG_STRUC_wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param, 21265 WMITLV_GET_STRUCT_TLVLEN 21266 (wmi_vdev_pn_mgmt_rx_filter_cmd_fixed_param)); 21267 21268 cmd->vdev_id = params->vdev_id; 21269 cmd->pn_rx_filter = params->pn_rxfilter; 21270 21271 if (wmi_unified_cmd_send(wmi_handle, buf, len, 21272 WMI_VDEV_PN_MGMT_RX_FILTER_CMDID)) { 21273 wmi_err("Failed to send WMI command"); 21274 wmi_buf_free(buf); 21275 return QDF_STATUS_E_FAILURE; 21276 } 21277 21278 return QDF_STATUS_SUCCESS; 21279 } 21280 21281 static QDF_STATUS 21282 send_egid_info_cmd_tlv(wmi_unified_t wmi_handle, 21283 struct esl_egid_params *param) 21284 { 21285 wmi_esl_egid_cmd_fixed_param *cmd; 21286 wmi_buf_t buf; 21287 21288 uint32_t len = sizeof(*cmd); 21289 21290 buf = wmi_buf_alloc(wmi_handle, len); 21291 if (!buf) { 21292 wmi_err("wmi_buf_alloc failed"); 21293 return QDF_STATUS_E_NOMEM; 21294 } 21295 21296 cmd = (wmi_esl_egid_cmd_fixed_param *)wmi_buf_data(buf); 21297 WMITLV_SET_HDR( 21298 &cmd->tlv_header, 21299 WMITLV_TAG_STRUC_wmi_esl_egid_cmd_fixed_param, 21300 WMITLV_GET_STRUCT_TLVLEN(wmi_esl_egid_cmd_fixed_param)); 21301 qdf_mem_copy(cmd->egid_info, 21302 param->egid_info, 21303 sizeof(param->egid_info)); 21304 if (wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ESL_EGID_CMDID)) { 21305 wmi_err("Failed to send WMI command"); 21306 wmi_buf_free(buf); 21307 return QDF_STATUS_E_FAILURE; 21308 } 21309 21310 return QDF_STATUS_SUCCESS; 21311 } 21312 21313 static QDF_STATUS 21314 extract_pktlog_decode_info_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, 21315 uint8_t *pdev_id, uint8_t *software_image, 21316 uint8_t *chip_info, 21317 uint32_t *pktlog_json_version) 21318 { 21319 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *param_buf; 21320 wmi_pdev_pktlog_decode_info_evt_fixed_param *event; 21321 21322 param_buf = 21323 (WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID_param_tlvs *)evt_buf; 21324 21325 event = param_buf->fixed_param; 21326 21327 if ((event->software_image[0] == '\0') || 21328 (event->chip_info[0] == '\0')) { 21329 *pdev_id = event->pdev_id; 21330 return QDF_STATUS_E_INVAL; 21331 } 21332 21333 qdf_mem_copy(software_image, event->software_image, 40); 21334 qdf_mem_copy(chip_info, event->chip_info, 40); 21335 *pktlog_json_version = event->pktlog_defs_json_version; 21336 *pdev_id = event->pdev_id; 21337 return QDF_STATUS_SUCCESS; 21338 } 21339 21340 #ifdef HEALTH_MON_SUPPORT 21341 /** 21342 * extract_health_mon_init_done_info_event_tlv() - Extract health monitor from 21343 * fw 21344 * @wmi_handle: wmi handle 21345 * @evt_buf: pointer to event buffer 21346 * @param: health monitor params 21347 * 21348 * Return: QDF_STATUS_SUCCESS for success or error code 21349 */ 21350 static QDF_STATUS 21351 extract_health_mon_init_done_info_event_tlv(wmi_unified_t wmi_handle, 21352 void *evt_buf, 21353 struct wmi_health_mon_params *param) 21354 { 21355 WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *param_buf; 21356 wmi_health_mon_init_done_fixed_param *event; 21357 21358 param_buf = 21359 (WMI_HEALTH_MON_INIT_DONE_EVENTID_param_tlvs *)evt_buf; 21360 21361 event = param_buf->fixed_param; 21362 21363 param->ring_buf_paddr_low = event->ring_buf_paddr_low; 21364 param->ring_buf_paddr_high = event->ring_buf_paddr_high; 21365 param->initial_upload_period_ms = event->initial_upload_period_ms; 21366 param->read_index = 0; 21367 21368 return QDF_STATUS_SUCCESS; 21369 } 21370 #endif /* HEALTH_MON_SUPPORT */ 21371 21372 /** 21373 * extract_pdev_telemetry_stats_tlv - extract pdev telemetry stats 21374 * @wmi_handle: wmi handle 21375 * @evt_buf: pointer to event buffer 21376 * @pdev_stats: Pointer to hold pdev telemetry stats 21377 * 21378 * Return: QDF_STATUS_SUCCESS for success or error code 21379 */ 21380 static QDF_STATUS 21381 extract_pdev_telemetry_stats_tlv( 21382 wmi_unified_t wmi_handle, void *evt_buf, 21383 struct wmi_host_pdev_telemetry_stats *pdev_stats) 21384 { 21385 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 21386 wmi_pdev_telemetry_stats *ev; 21387 21388 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 21389 21390 if (param_buf->pdev_telemetry_stats) { 21391 ev = (wmi_pdev_telemetry_stats *)(param_buf->pdev_telemetry_stats); 21392 qdf_mem_copy(pdev_stats->avg_chan_lat_per_ac, 21393 ev->avg_chan_lat_per_ac, 21394 sizeof(ev->avg_chan_lat_per_ac)); 21395 pdev_stats->estimated_air_time_per_ac = 21396 ev->estimated_air_time_per_ac; 21397 } 21398 21399 return QDF_STATUS_SUCCESS; 21400 } 21401 21402 static QDF_STATUS 21403 send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle, 21404 struct set_rx_mac_filter *param) 21405 { 21406 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd; 21407 uint32_t len; 21408 wmi_buf_t buf; 21409 int ret; 21410 21411 if (!wmi_handle) { 21412 wmi_err("WMA context is invalid!"); 21413 return QDF_STATUS_E_INVAL; 21414 } 21415 21416 len = sizeof(*cmd); 21417 buf = wmi_buf_alloc(wmi_handle, len); 21418 if (!buf) { 21419 wmi_err("Failed allocate wmi buffer"); 21420 return QDF_STATUS_E_NOMEM; 21421 } 21422 21423 cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *) 21424 wmi_buf_data(buf); 21425 21426 WMITLV_SET_HDR( 21427 &cmd->tlv_header, 21428 WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param, 21429 WMITLV_GET_STRUCT_TLVLEN( 21430 wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param)); 21431 21432 cmd->vdev_id = param->vdev_id; 21433 cmd->freq = param->freq; 21434 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr); 21435 if (param->set) 21436 cmd->enable = 1; 21437 else 21438 cmd->enable = 0; 21439 wmi_debug("set random mac rx vdev:%d freq:%d set:%d " QDF_MAC_ADDR_FMT, 21440 param->vdev_id, param->freq, param->set, 21441 QDF_MAC_ADDR_REF(param->mac)); 21442 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 21443 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID); 21444 if (ret) { 21445 wmi_err("Failed to send action frame random mac cmd"); 21446 wmi_buf_free(buf); 21447 return QDF_STATUS_E_FAILURE; 21448 } 21449 21450 return QDF_STATUS_SUCCESS; 21451 } 21452 21453 static QDF_STATUS 21454 extract_sap_coex_fix_chan_caps(wmi_unified_t wmi_handle, 21455 uint8_t *event, 21456 struct wmi_host_coex_fix_chan_cap *cap) 21457 { 21458 WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; 21459 WMI_COEX_FIX_CHANNEL_CAPABILITIES *fw_cap; 21460 21461 param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; 21462 if (!param_buf) 21463 return QDF_STATUS_E_INVAL; 21464 21465 fw_cap = param_buf->coex_fix_channel_caps; 21466 if (!fw_cap) 21467 return QDF_STATUS_E_INVAL; 21468 21469 cap->fix_chan_priority = fw_cap->fix_channel_priority; 21470 21471 return QDF_STATUS_SUCCESS; 21472 } 21473 21474 static QDF_STATUS extract_tgtr2p_table_event_tlv(wmi_unified_t wmi_handle, 21475 uint8_t *evt_buf, 21476 struct r2p_table_update_status_obj *update_status, 21477 uint32_t len) 21478 { 21479 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *param_buf; 21480 wmi_pdev_set_tgtr2p_table_event_fixed_param *event_fixed_hdr; 21481 21482 param_buf = (WMI_PDEV_SET_TGTR2P_TABLE_EVENTID_param_tlvs *)evt_buf; 21483 if (!param_buf) { 21484 wmi_err("Invalid TGTR2P event buf"); 21485 return QDF_STATUS_E_FAILURE; 21486 } 21487 21488 event_fixed_hdr = param_buf->fixed_param; 21489 update_status->pdev_id = event_fixed_hdr->pdev_id; 21490 update_status->status = event_fixed_hdr->status; 21491 21492 if (update_status->status != WMI_PDEV_TGTR2P_SUCCESS && 21493 update_status->status != 21494 WMI_PDEV_TGTR2P_SUCCESS_WAITING_FOR_END_OF_UPDATE) { 21495 wmi_err("Rate2Power table update failed. Status = %d", 21496 update_status->status); 21497 } 21498 21499 return QDF_STATUS_SUCCESS; 21500 } 21501 21502 struct wmi_ops tlv_ops = { 21503 .send_vdev_create_cmd = send_vdev_create_cmd_tlv, 21504 .send_vdev_delete_cmd = send_vdev_delete_cmd_tlv, 21505 .send_vdev_nss_chain_params_cmd = send_vdev_nss_chain_params_cmd_tlv, 21506 .send_vdev_down_cmd = send_vdev_down_cmd_tlv, 21507 .send_vdev_start_cmd = send_vdev_start_cmd_tlv, 21508 .send_peer_flush_tids_cmd = send_peer_flush_tids_cmd_tlv, 21509 .send_peer_param_cmd = send_peer_param_cmd_tlv, 21510 .send_vdev_up_cmd = send_vdev_up_cmd_tlv, 21511 .send_vdev_stop_cmd = send_vdev_stop_cmd_tlv, 21512 .send_peer_create_cmd = send_peer_create_cmd_tlv, 21513 .send_peer_delete_cmd = send_peer_delete_cmd_tlv, 21514 .send_peer_delete_all_cmd = send_peer_delete_all_cmd_tlv, 21515 .send_peer_rx_reorder_queue_setup_cmd = 21516 send_peer_rx_reorder_queue_setup_cmd_tlv, 21517 .send_peer_multi_rx_reorder_queue_setup_cmd = 21518 send_peer_multi_rx_reorder_queue_setup_cmd_tlv, 21519 .send_peer_rx_reorder_queue_remove_cmd = 21520 send_peer_rx_reorder_queue_remove_cmd_tlv, 21521 .send_pdev_utf_cmd = send_pdev_utf_cmd_tlv, 21522 .send_pdev_param_cmd = send_pdev_param_cmd_tlv, 21523 .send_multiple_pdev_param_cmd = send_multiple_pdev_param_cmd_tlv, 21524 .send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv, 21525 .send_pdev_set_rf_path_cmd = send_pdev_set_rf_path_cmd_tlv, 21526 .send_suspend_cmd = send_suspend_cmd_tlv, 21527 .send_resume_cmd = send_resume_cmd_tlv, 21528 .send_wow_enable_cmd = send_wow_enable_cmd_tlv, 21529 .send_set_ap_ps_param_cmd = send_set_ap_ps_param_cmd_tlv, 21530 .send_set_sta_ps_param_cmd = send_set_sta_ps_param_cmd_tlv, 21531 .send_crash_inject_cmd = send_crash_inject_cmd_tlv, 21532 .send_dbglog_cmd = send_dbglog_cmd_tlv, 21533 .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, 21534 .send_vdev_set_mu_snif_cmd = send_vdev_set_mu_snif_cmd_tlv, 21535 .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, 21536 .send_peer_based_pktlog_cmd = send_peer_based_pktlog_cmd, 21537 .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, 21538 .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, 21539 .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv, 21540 .send_fd_tmpl_cmd = send_fd_tmpl_cmd_tlv, 21541 .send_peer_assoc_cmd = send_peer_assoc_cmd_tlv, 21542 .send_scan_start_cmd = send_scan_start_cmd_tlv, 21543 .send_scan_stop_cmd = send_scan_stop_cmd_tlv, 21544 .send_scan_chan_list_cmd = send_scan_chan_list_cmd_tlv, 21545 .send_mgmt_cmd = send_mgmt_cmd_tlv, 21546 .send_offchan_data_tx_cmd = send_offchan_data_tx_cmd_tlv, 21547 .send_modem_power_state_cmd = send_modem_power_state_cmd_tlv, 21548 .send_set_sta_ps_mode_cmd = send_set_sta_ps_mode_cmd_tlv, 21549 .send_idle_roam_monitor_cmd = send_idle_roam_monitor_cmd_tlv, 21550 .send_set_sta_uapsd_auto_trig_cmd = 21551 send_set_sta_uapsd_auto_trig_cmd_tlv, 21552 .send_get_temperature_cmd = send_get_temperature_cmd_tlv, 21553 .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, 21554 .send_set_mimops_cmd = send_set_mimops_cmd_tlv, 21555 .send_set_thermal_mgmt_cmd = send_set_thermal_mgmt_cmd_tlv, 21556 .send_lro_config_cmd = send_lro_config_cmd_tlv, 21557 .send_peer_rate_report_cmd = send_peer_rate_report_cmd_tlv, 21558 .send_probe_rsp_tmpl_send_cmd = 21559 send_probe_rsp_tmpl_send_cmd_tlv, 21560 .send_p2p_go_set_beacon_ie_cmd = 21561 send_p2p_go_set_beacon_ie_cmd_tlv, 21562 .send_setup_install_key_cmd = 21563 send_setup_install_key_cmd_tlv, 21564 .send_scan_probe_setoui_cmd = 21565 send_scan_probe_setoui_cmd_tlv, 21566 #ifdef IPA_OFFLOAD 21567 .send_ipa_offload_control_cmd = 21568 send_ipa_offload_control_cmd_tlv, 21569 #endif 21570 .send_pno_stop_cmd = send_pno_stop_cmd_tlv, 21571 .send_pno_start_cmd = send_pno_start_cmd_tlv, 21572 .send_obss_disable_cmd = send_obss_disable_cmd_tlv, 21573 .send_nlo_mawc_cmd = send_nlo_mawc_cmd_tlv, 21574 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 21575 .send_process_ll_stats_clear_cmd = send_process_ll_stats_clear_cmd_tlv, 21576 .send_process_ll_stats_set_cmd = send_process_ll_stats_set_cmd_tlv, 21577 .send_process_ll_stats_get_cmd = send_process_ll_stats_get_cmd_tlv, 21578 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 21579 .send_unified_ll_stats_get_sta_cmd = 21580 send_unified_ll_stats_get_sta_cmd_tlv, 21581 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 21582 #endif /* WLAN_FEATURE_LINK_LAYER_STATS*/ 21583 .send_congestion_cmd = send_congestion_cmd_tlv, 21584 .send_snr_request_cmd = send_snr_request_cmd_tlv, 21585 .send_snr_cmd = send_snr_cmd_tlv, 21586 .send_link_status_req_cmd = send_link_status_req_cmd_tlv, 21587 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) 21588 .send_pktlog_wmi_send_cmd = send_pktlog_wmi_send_cmd_tlv, 21589 #endif 21590 #ifdef WLAN_SUPPORT_GREEN_AP 21591 .send_egap_conf_params_cmd = send_egap_conf_params_cmd_tlv, 21592 .send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv, 21593 .extract_green_ap_egap_status_info = 21594 extract_green_ap_egap_status_info_tlv, 21595 #endif 21596 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 21597 .send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv, 21598 .extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv, 21599 #endif 21600 .send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv, 21601 .send_start_oem_data_cmd = send_start_oem_data_cmd_tlv, 21602 #ifdef FEATURE_OEM_DATA 21603 .send_start_oemv2_data_cmd = send_start_oemv2_data_cmd_tlv, 21604 #endif 21605 #ifdef WLAN_FEATURE_CIF_CFR 21606 .send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv, 21607 #endif 21608 .send_dfs_phyerr_filter_offload_en_cmd = 21609 send_dfs_phyerr_filter_offload_en_cmd_tlv, 21610 .send_stats_ext_req_cmd = send_stats_ext_req_cmd_tlv, 21611 .send_process_dhcpserver_offload_cmd = 21612 send_process_dhcpserver_offload_cmd_tlv, 21613 .send_pdev_set_regdomain_cmd = 21614 send_pdev_set_regdomain_cmd_tlv, 21615 .send_regdomain_info_to_fw_cmd = send_regdomain_info_to_fw_cmd_tlv, 21616 .send_cfg_action_frm_tb_ppdu_cmd = send_cfg_action_frm_tb_ppdu_cmd_tlv, 21617 .save_fw_version_cmd = save_fw_version_cmd_tlv, 21618 .check_and_update_fw_version = 21619 check_and_update_fw_version_cmd_tlv, 21620 .send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv, 21621 .send_enable_specific_fw_logs_cmd = 21622 send_enable_specific_fw_logs_cmd_tlv, 21623 .send_flush_logs_to_fw_cmd = send_flush_logs_to_fw_cmd_tlv, 21624 .send_unit_test_cmd = send_unit_test_cmd_tlv, 21625 #ifdef FEATURE_WLAN_APF 21626 .send_set_active_apf_mode_cmd = wmi_send_set_active_apf_mode_cmd_tlv, 21627 .send_apf_enable_cmd = wmi_send_apf_enable_cmd_tlv, 21628 .send_apf_write_work_memory_cmd = 21629 wmi_send_apf_write_work_memory_cmd_tlv, 21630 .send_apf_read_work_memory_cmd = 21631 wmi_send_apf_read_work_memory_cmd_tlv, 21632 .extract_apf_read_memory_resp_event = 21633 wmi_extract_apf_read_memory_resp_event_tlv, 21634 #endif /* FEATURE_WLAN_APF */ 21635 .init_cmd_send = init_cmd_send_tlv, 21636 .send_vdev_set_custom_aggr_size_cmd = 21637 send_vdev_set_custom_aggr_size_cmd_tlv, 21638 .send_vdev_set_qdepth_thresh_cmd = 21639 send_vdev_set_qdepth_thresh_cmd_tlv, 21640 .send_set_vap_dscp_tid_map_cmd = send_set_vap_dscp_tid_map_cmd_tlv, 21641 .send_vdev_set_fwtest_param_cmd = send_vdev_set_fwtest_param_cmd_tlv, 21642 .send_phyerr_disable_cmd = send_phyerr_disable_cmd_tlv, 21643 .send_phyerr_enable_cmd = send_phyerr_enable_cmd_tlv, 21644 .send_periodic_chan_stats_config_cmd = 21645 send_periodic_chan_stats_config_cmd_tlv, 21646 #ifdef WLAN_IOT_SIM_SUPPORT 21647 .send_simulation_test_cmd = send_simulation_test_cmd_tlv, 21648 #endif 21649 .send_vdev_spectral_configure_cmd = 21650 send_vdev_spectral_configure_cmd_tlv, 21651 .send_vdev_spectral_enable_cmd = 21652 send_vdev_spectral_enable_cmd_tlv, 21653 #ifdef WLAN_CONV_SPECTRAL_ENABLE 21654 .extract_pdev_sscan_fw_cmd_fixed_param = 21655 extract_pdev_sscan_fw_cmd_fixed_param_tlv, 21656 .extract_pdev_sscan_fft_bin_index = 21657 extract_pdev_sscan_fft_bin_index_tlv, 21658 .extract_pdev_spectral_session_chan_info = 21659 extract_pdev_spectral_session_chan_info_tlv, 21660 .extract_pdev_spectral_session_detector_info = 21661 extract_pdev_spectral_session_detector_info_tlv, 21662 .extract_spectral_caps_fixed_param = 21663 extract_spectral_caps_fixed_param_tlv, 21664 .extract_spectral_scan_bw_caps = 21665 extract_spectral_scan_bw_caps_tlv, 21666 .extract_spectral_fft_size_caps = 21667 extract_spectral_fft_size_caps_tlv, 21668 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 21669 .send_thermal_mitigation_param_cmd = 21670 send_thermal_mitigation_param_cmd_tlv, 21671 .send_process_update_edca_param_cmd = 21672 send_process_update_edca_param_cmd_tlv, 21673 .send_bss_color_change_enable_cmd = 21674 send_bss_color_change_enable_cmd_tlv, 21675 .send_coex_config_cmd = send_coex_config_cmd_tlv, 21676 .send_coex_multi_config_cmd = send_coex_multi_config_cmd_tlv, 21677 .send_set_country_cmd = send_set_country_cmd_tlv, 21678 .send_addba_send_cmd = send_addba_send_cmd_tlv, 21679 .send_delba_send_cmd = send_delba_send_cmd_tlv, 21680 .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, 21681 .get_target_cap_from_service_ready = extract_service_ready_tlv, 21682 .extract_hal_reg_cap = extract_hal_reg_cap_tlv, 21683 .extract_num_mem_reqs = extract_num_mem_reqs_tlv, 21684 .extract_host_mem_req = extract_host_mem_req_tlv, 21685 .save_service_bitmap = save_service_bitmap_tlv, 21686 .save_ext_service_bitmap = save_ext_service_bitmap_tlv, 21687 .is_service_enabled = is_service_enabled_tlv, 21688 .save_fw_version = save_fw_version_in_service_ready_tlv, 21689 .ready_extract_init_status = ready_extract_init_status_tlv, 21690 .ready_extract_mac_addr = ready_extract_mac_addr_tlv, 21691 .ready_extract_mac_addr_list = ready_extract_mac_addr_list_tlv, 21692 .extract_ready_event_params = extract_ready_event_params_tlv, 21693 .extract_dbglog_data_len = extract_dbglog_data_len_tlv, 21694 .extract_mgmt_rx_params = extract_mgmt_rx_params_tlv, 21695 .extract_frame_pn_params = extract_frame_pn_params_tlv, 21696 .extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv, 21697 .extract_vdev_roam_param = extract_vdev_roam_param_tlv, 21698 .extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv, 21699 #ifdef FEATURE_WLAN_SCAN_PNO 21700 .extract_nlo_match_ev_param = extract_nlo_match_ev_param_tlv, 21701 .extract_nlo_complete_ev_param = extract_nlo_complete_ev_param_tlv, 21702 #endif 21703 .extract_unit_test = extract_unit_test_tlv, 21704 .extract_pdev_ext_stats = extract_pdev_ext_stats_tlv, 21705 .extract_bcn_stats = extract_bcn_stats_tlv, 21706 .extract_bcnflt_stats = extract_bcnflt_stats_tlv, 21707 .extract_chan_stats = extract_chan_stats_tlv, 21708 .extract_vdev_prb_fils_stats = extract_vdev_prb_fils_stats_tlv, 21709 .extract_profile_ctx = extract_profile_ctx_tlv, 21710 .extract_profile_data = extract_profile_data_tlv, 21711 .send_fw_test_cmd = send_fw_test_cmd_tlv, 21712 .send_wfa_test_cmd = send_wfa_test_cmd_tlv, 21713 .send_power_dbg_cmd = send_power_dbg_cmd_tlv, 21714 .extract_service_ready_ext = extract_service_ready_ext_tlv, 21715 .extract_service_ready_ext2 = extract_service_ready_ext2_tlv, 21716 .extract_dbs_or_sbs_service_ready_ext2 = 21717 extract_dbs_or_sbs_cap_service_ready_ext2_tlv, 21718 .extract_hw_mode_cap_service_ready_ext = 21719 extract_hw_mode_cap_service_ready_ext_tlv, 21720 .extract_mac_phy_cap_service_ready_ext = 21721 extract_mac_phy_cap_service_ready_ext_tlv, 21722 .extract_mac_phy_cap_service_ready_ext2 = 21723 extract_mac_phy_cap_service_ready_ext2_tlv, 21724 .extract_reg_cap_service_ready_ext = 21725 extract_reg_cap_service_ready_ext_tlv, 21726 .extract_hal_reg_cap_ext2 = extract_hal_reg_cap_ext2_tlv, 21727 .extract_dbr_ring_cap_service_ready_ext = 21728 extract_dbr_ring_cap_service_ready_ext_tlv, 21729 .extract_dbr_ring_cap_service_ready_ext2 = 21730 extract_dbr_ring_cap_service_ready_ext2_tlv, 21731 .extract_scan_radio_cap_service_ready_ext2 = 21732 extract_scan_radio_cap_service_ready_ext2_tlv, 21733 .extract_msdu_idx_qtype_map_service_ready_ext2 = 21734 extract_msdu_idx_qtype_map_service_ready_ext2_tlv, 21735 .extract_sw_cal_ver_ext2 = extract_sw_cal_ver_ext2_tlv, 21736 .extract_aux_dev_cap_service_ready_ext2 = 21737 extract_aux_dev_cap_service_ready_ext2_tlv, 21738 .extract_sar_cap_service_ready_ext = 21739 extract_sar_cap_service_ready_ext_tlv, 21740 .extract_pdev_utf_event = extract_pdev_utf_event_tlv, 21741 .wmi_set_htc_tx_tag = wmi_set_htc_tx_tag_tlv, 21742 .extract_fips_event_data = extract_fips_event_data_tlv, 21743 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21744 .extract_fips_extend_ev_data = extract_fips_extend_event_data_tlv, 21745 #endif 21746 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) 21747 .send_vdev_fils_enable_cmd = send_vdev_fils_enable_cmd_send, 21748 #endif 21749 #ifdef WLAN_FEATURE_DISA 21750 .extract_encrypt_decrypt_resp_event = 21751 extract_encrypt_decrypt_resp_event_tlv, 21752 #endif 21753 .send_pdev_fips_cmd = send_pdev_fips_cmd_tlv, 21754 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 21755 .send_pdev_fips_extend_cmd = send_pdev_fips_extend_cmd_tlv, 21756 .send_pdev_fips_mode_set_cmd = send_pdev_fips_mode_set_cmd_tlv, 21757 #endif 21758 .extract_get_pn_data = extract_get_pn_data_tlv, 21759 .send_pdev_get_pn_cmd = send_pdev_get_pn_cmd_tlv, 21760 .extract_get_rxpn_data = extract_get_rxpn_data_tlv, 21761 .send_pdev_get_rxpn_cmd = send_pdev_get_rxpn_cmd_tlv, 21762 .send_wlan_profile_enable_cmd = send_wlan_profile_enable_cmd_tlv, 21763 #ifdef WLAN_FEATURE_DISA 21764 .send_encrypt_decrypt_send_cmd = send_encrypt_decrypt_send_cmd_tlv, 21765 #endif 21766 .send_wlan_profile_trigger_cmd = send_wlan_profile_trigger_cmd_tlv, 21767 .send_wlan_profile_hist_intvl_cmd = 21768 send_wlan_profile_hist_intvl_cmd_tlv, 21769 .is_management_record = is_management_record_tlv, 21770 .is_diag_event = is_diag_event_tlv, 21771 .is_force_fw_hang_cmd = is_force_fw_hang_cmd_tlv, 21772 #ifdef WLAN_FEATURE_ACTION_OUI 21773 .send_action_oui_cmd = send_action_oui_cmd_tlv, 21774 #endif 21775 .send_dfs_phyerr_offload_en_cmd = send_dfs_phyerr_offload_en_cmd_tlv, 21776 #ifdef QCA_SUPPORT_AGILE_DFS 21777 .send_adfs_ch_cfg_cmd = send_adfs_ch_cfg_cmd_tlv, 21778 .send_adfs_ocac_abort_cmd = send_adfs_ocac_abort_cmd_tlv, 21779 #endif 21780 .send_dfs_phyerr_offload_dis_cmd = send_dfs_phyerr_offload_dis_cmd_tlv, 21781 .extract_reg_chan_list_update_event = 21782 extract_reg_chan_list_update_event_tlv, 21783 #ifdef CONFIG_BAND_6GHZ 21784 .extract_reg_chan_list_ext_update_event = 21785 extract_reg_chan_list_ext_update_event_tlv, 21786 #ifdef CONFIG_AFC_SUPPORT 21787 .extract_afc_event = extract_afc_event_tlv, 21788 #endif 21789 #endif 21790 #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION 21791 .extract_num_rf_characterization_entries = 21792 extract_num_rf_characterization_entries_tlv, 21793 .extract_rf_characterization_entries = 21794 extract_rf_characterization_entries_tlv, 21795 #endif 21796 .extract_chainmask_tables = 21797 extract_chainmask_tables_tlv, 21798 .extract_thermal_stats = extract_thermal_stats_tlv, 21799 .extract_thermal_level_stats = extract_thermal_level_stats_tlv, 21800 .send_get_rcpi_cmd = send_get_rcpi_cmd_tlv, 21801 .extract_rcpi_response_event = extract_rcpi_response_event_tlv, 21802 #ifdef DFS_COMPONENT_ENABLE 21803 .extract_dfs_cac_complete_event = extract_dfs_cac_complete_event_tlv, 21804 .extract_dfs_ocac_complete_event = extract_dfs_ocac_complete_event_tlv, 21805 .extract_dfs_radar_detection_event = 21806 extract_dfs_radar_detection_event_tlv, 21807 .extract_wlan_radar_event_info = extract_wlan_radar_event_info_tlv, 21808 #endif 21809 .convert_pdev_id_host_to_target = 21810 convert_host_pdev_id_to_target_pdev_id_legacy, 21811 .convert_pdev_id_target_to_host = 21812 convert_target_pdev_id_to_host_pdev_id_legacy, 21813 21814 .convert_host_pdev_id_to_target = 21815 convert_host_pdev_id_to_target_pdev_id, 21816 .convert_target_pdev_id_to_host = 21817 convert_target_pdev_id_to_host_pdev_id, 21818 21819 .convert_host_vdev_param_tlv = convert_host_vdev_param_tlv, 21820 21821 .convert_phy_id_host_to_target = 21822 convert_host_phy_id_to_target_phy_id_legacy, 21823 .convert_phy_id_target_to_host = 21824 convert_target_phy_id_to_host_phy_id_legacy, 21825 21826 .convert_host_phy_id_to_target = 21827 convert_host_phy_id_to_target_phy_id, 21828 .convert_target_phy_id_to_host = 21829 convert_target_phy_id_to_host_phy_id, 21830 21831 .send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv, 21832 .send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv, 21833 .extract_reg_11d_new_country_event = 21834 extract_reg_11d_new_country_event_tlv, 21835 .send_user_country_code_cmd = send_user_country_code_cmd_tlv, 21836 .extract_reg_ch_avoid_event = 21837 extract_reg_ch_avoid_event_tlv, 21838 .send_obss_detection_cfg_cmd = send_obss_detection_cfg_cmd_tlv, 21839 .extract_obss_detection_info = extract_obss_detection_info_tlv, 21840 .wmi_pdev_id_conversion_enable = wmi_tlv_pdev_id_conversion_enable, 21841 .wmi_free_allocated_event = wmitlv_free_allocated_event_tlvs, 21842 .wmi_check_and_pad_event = wmitlv_check_and_pad_event_tlvs, 21843 .wmi_check_command_params = wmitlv_check_command_tlv_params, 21844 .extract_comb_phyerr = extract_comb_phyerr_tlv, 21845 .extract_single_phyerr = extract_single_phyerr_tlv, 21846 #ifdef QCA_SUPPORT_CP_STATS 21847 .extract_cca_stats = extract_cca_stats_tlv, 21848 #endif 21849 .extract_esp_estimation_ev_param = 21850 extract_esp_estimation_ev_param_tlv, 21851 .send_roam_scan_stats_cmd = send_roam_scan_stats_cmd_tlv, 21852 .extract_roam_scan_stats_res_evt = extract_roam_scan_stats_res_evt_tlv, 21853 #ifdef OBSS_PD 21854 .send_obss_spatial_reuse_set = send_obss_spatial_reuse_set_cmd_tlv, 21855 .send_obss_spatial_reuse_set_def_thresh = 21856 send_obss_spatial_reuse_set_def_thresh_cmd_tlv, 21857 .send_self_srg_bss_color_bitmap_set = 21858 send_self_srg_bss_color_bitmap_set_cmd_tlv, 21859 .send_self_srg_partial_bssid_bitmap_set = 21860 send_self_srg_partial_bssid_bitmap_set_cmd_tlv, 21861 .send_self_srg_obss_color_enable_bitmap = 21862 send_self_srg_obss_color_enable_bitmap_cmd_tlv, 21863 .send_self_srg_obss_bssid_enable_bitmap = 21864 send_self_srg_obss_bssid_enable_bitmap_cmd_tlv, 21865 .send_self_non_srg_obss_color_enable_bitmap = 21866 send_self_non_srg_obss_color_enable_bitmap_cmd_tlv, 21867 .send_self_non_srg_obss_bssid_enable_bitmap = 21868 send_self_non_srg_obss_bssid_enable_bitmap_cmd_tlv, 21869 #endif 21870 .extract_offload_bcn_tx_status_evt = extract_offload_bcn_tx_status_evt, 21871 .extract_ctl_failsafe_check_ev_param = 21872 extract_ctl_failsafe_check_ev_param_tlv, 21873 #ifdef WIFI_POS_CONVERGED 21874 .extract_oem_response_param = extract_oem_response_param_tlv, 21875 #endif /* WIFI_POS_CONVERGED */ 21876 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 21877 .extract_pasn_peer_create_req_event = 21878 extract_pasn_peer_create_req_event_tlv, 21879 .extract_pasn_peer_delete_req_event = 21880 extract_pasn_peer_delete_req_event_tlv, 21881 .send_rtt_pasn_auth_status_cmd = 21882 send_rtt_pasn_auth_status_cmd_tlv, 21883 .send_rtt_pasn_deauth_cmd = 21884 send_rtt_pasn_deauth_cmd_tlv, 21885 #endif 21886 #ifdef WLAN_MWS_INFO_DEBUGFS 21887 .send_mws_coex_status_req_cmd = send_mws_coex_status_req_cmd_tlv, 21888 #endif 21889 .extract_hw_mode_resp_event = extract_hw_mode_resp_event_status_tlv, 21890 #ifdef FEATURE_ANI_LEVEL_REQUEST 21891 .send_ani_level_cmd = send_ani_level_cmd_tlv, 21892 .extract_ani_level = extract_ani_level_tlv, 21893 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 21894 .extract_roam_trigger_stats = extract_roam_trigger_stats_tlv, 21895 .extract_roam_scan_stats = extract_roam_scan_stats_tlv, 21896 .extract_roam_result_stats = extract_roam_result_stats_tlv, 21897 .extract_roam_11kv_stats = extract_roam_11kv_stats_tlv, 21898 #ifdef WLAN_FEATURE_PKT_CAPTURE 21899 .extract_vdev_mgmt_offload_event = extract_vdev_mgmt_offload_event_tlv, 21900 #endif 21901 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 21902 .extract_smart_monitor_event = extract_smart_monitor_event_tlv, 21903 #endif 21904 21905 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 21906 .send_wlan_time_sync_ftm_trigger_cmd = send_wlan_ts_ftm_trigger_cmd_tlv, 21907 .send_wlan_ts_qtime_cmd = send_wlan_ts_qtime_cmd_tlv, 21908 .extract_time_sync_ftm_start_stop_event = 21909 extract_time_sync_ftm_start_stop_event_tlv, 21910 .extract_time_sync_ftm_offset_event = 21911 extract_time_sync_ftm_offset_event_tlv, 21912 #endif /* FEATURE_WLAN_TIME_SYNC_FTM */ 21913 .send_roam_scan_ch_list_req_cmd = send_roam_scan_ch_list_req_cmd_tlv, 21914 .send_injector_config_cmd = send_injector_config_cmd_tlv, 21915 .send_cp_stats_cmd = send_cp_stats_cmd_tlv, 21916 .send_halphy_stats_cmd = send_halphy_stats_cmd_tlv, 21917 #ifdef FEATURE_MEC_OFFLOAD 21918 .send_pdev_set_mec_timer_cmd = send_pdev_set_mec_timer_cmd_tlv, 21919 #endif 21920 #if defined(WLAN_SUPPORT_INFRA_CTRL_PATH_STATS) || defined(WLAN_CONFIG_TELEMETRY_AGENT) 21921 .extract_infra_cp_stats = extract_infra_cp_stats_tlv, 21922 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 21923 .extract_cp_stats_more_pending = 21924 extract_cp_stats_more_pending_tlv, 21925 .extract_halphy_stats_end_of_event = 21926 extract_halphy_stats_end_of_event_tlv, 21927 .extract_halphy_stats_event_count = 21928 extract_halphy_stats_event_count_tlv, 21929 .send_vdev_tsf_tstamp_action_cmd = send_vdev_tsf_tstamp_action_cmd_tlv, 21930 .extract_vdev_tsf_report_event = extract_vdev_tsf_report_event_tlv, 21931 .extract_pdev_csa_switch_count_status = 21932 extract_pdev_csa_switch_count_status_tlv, 21933 .send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv, 21934 #ifdef CONFIG_AFC_SUPPORT 21935 .send_afc_cmd = send_afc_cmd_tlv, 21936 #endif 21937 .extract_dpd_status_ev_param = extract_dpd_status_ev_param_tlv, 21938 .extract_install_key_comp_event = extract_install_key_comp_event_tlv, 21939 .send_vdev_set_ltf_key_seed_cmd = 21940 send_vdev_set_ltf_key_seed_cmd_tlv, 21941 .extract_halphy_cal_status_ev_param = extract_halphy_cal_status_ev_param_tlv, 21942 .send_set_halphy_cal = send_set_halphy_cal_tlv, 21943 .extract_halphy_cal_ev_param = extract_halphy_cal_ev_param_tlv, 21944 #ifdef WLAN_MGMT_RX_REO_SUPPORT 21945 .extract_mgmt_rx_fw_consumed = extract_mgmt_rx_fw_consumed_tlv, 21946 .extract_mgmt_rx_reo_params = extract_mgmt_rx_reo_params_tlv, 21947 .send_mgmt_rx_reo_filter_config_cmd = 21948 send_mgmt_rx_reo_filter_config_cmd_tlv, 21949 #endif 21950 21951 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 21952 .send_roam_set_param_cmd = send_roam_set_param_cmd_tlv, 21953 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 21954 21955 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 21956 .send_set_mac_address_cmd = send_set_mac_address_cmd_tlv, 21957 .extract_update_mac_address_event = 21958 extract_update_mac_address_event_tlv, 21959 #endif 21960 21961 #ifdef WLAN_FEATURE_11BE_MLO 21962 .extract_quiet_offload_event = 21963 extract_quiet_offload_event_tlv, 21964 #endif 21965 21966 #ifdef WLAN_SUPPORT_PPEDS 21967 .peer_ppe_ds_param_send = peer_ppe_ds_param_send_tlv, 21968 #endif /* WLAN_SUPPORT_PPEDS */ 21969 21970 .send_vdev_pn_mgmt_rxfilter_cmd = send_vdev_pn_mgmt_rxfilter_cmd_tlv, 21971 .extract_pktlog_decode_info_event = 21972 extract_pktlog_decode_info_event_tlv, 21973 .extract_pdev_telemetry_stats = extract_pdev_telemetry_stats_tlv, 21974 .extract_mgmt_rx_ext_params = extract_mgmt_rx_ext_params_tlv, 21975 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 21976 .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, 21977 #endif 21978 #ifdef WLAN_FEATURE_DBAM_CONFIG 21979 .send_dbam_config_cmd = send_dbam_config_cmd_tlv, 21980 .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, 21981 #endif 21982 #ifdef FEATURE_SET 21983 .feature_set_cmd_send = feature_set_cmd_send_tlv, 21984 #endif 21985 #ifdef HEALTH_MON_SUPPORT 21986 .extract_health_mon_init_done_info_event = 21987 extract_health_mon_init_done_info_event_tlv, 21988 #endif /* HEALTH_MON_SUPPORT */ 21989 .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, 21990 .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, 21991 .send_update_edca_pifs_param_cmd = 21992 send_update_edca_pifs_param_cmd_tlv, 21993 .extract_sap_coex_cap_service_ready_ext2 = 21994 extract_sap_coex_fix_chan_caps, 21995 .extract_tgtr2p_table_event = extract_tgtr2p_table_event_tlv, 21996 .send_egid_info_cmd = send_egid_info_cmd_tlv, 21997 .extract_csa_ie_received_ev_params = 21998 extract_csa_ie_received_ev_params_tlv, 21999 .extract_rf_path_resp = extract_rf_path_resp_tlv, 22000 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 22001 .extract_aoa_caps_service_ready_ext2 = 22002 extract_aoa_caps_tlv, 22003 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 22004 }; 22005 22006 #ifdef WLAN_FEATURE_11BE_MLO 22007 static void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 22008 { 22009 event_ids[wmi_mlo_setup_complete_event_id] = 22010 WMI_MLO_SETUP_COMPLETE_EVENTID; 22011 event_ids[wmi_mlo_teardown_complete_event_id] = 22012 WMI_MLO_TEARDOWN_COMPLETE_EVENTID; 22013 event_ids[wmi_mlo_link_set_active_resp_eventid] = 22014 WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; 22015 event_ids[wmi_vdev_quiet_offload_eventid] = 22016 WMI_QUIET_HANDLING_EVENTID; 22017 event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = 22018 WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; 22019 event_ids[wmi_mlo_link_removal_eventid] = 22020 WMI_MLO_LINK_REMOVAL_EVENTID; 22021 event_ids[wmi_mlo_link_state_info_eventid] = 22022 WMI_MLO_VDEV_LINK_INFO_EVENTID; 22023 event_ids[wmi_mlo_link_disable_request_eventid] = 22024 WMI_MLO_LINK_DISABLE_REQUEST_EVENTID; 22025 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 22026 event_ids[wmi_mlo_link_switch_request_eventid] = 22027 WMI_MLO_LINK_SWITCH_REQUEST_EVENTID; 22028 event_ids[wmi_mlo_link_state_switch_eventid] = 22029 WMI_MLO_LINK_STATE_SWITCH_EVENTID; 22030 #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */ 22031 } 22032 #else /* WLAN_FEATURE_11BE_MLO */ 22033 static inline void populate_tlv_events_id_mlo(WMI_EVT_ID *event_ids) 22034 { 22035 } 22036 #endif /* WLAN_FEATURE_11BE_MLO */ 22037 22038 /** 22039 * populate_tlv_events_id() - populates wmi event ids 22040 * @event_ids: Pointer to hold event ids 22041 * 22042 * Return: None 22043 */ 22044 static void populate_tlv_events_id(WMI_EVT_ID *event_ids) 22045 { 22046 event_ids[wmi_service_ready_event_id] = WMI_SERVICE_READY_EVENTID; 22047 event_ids[wmi_ready_event_id] = WMI_READY_EVENTID; 22048 event_ids[wmi_scan_event_id] = WMI_SCAN_EVENTID; 22049 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22050 event_ids[wmi_chan_info_event_id] = WMI_CHAN_INFO_EVENTID; 22051 event_ids[wmi_phyerr_event_id] = WMI_PHYERR_EVENTID; 22052 event_ids[wmi_pdev_dump_event_id] = WMI_PDEV_DUMP_EVENTID; 22053 event_ids[wmi_tx_pause_event_id] = WMI_TX_PAUSE_EVENTID; 22054 event_ids[wmi_dfs_radar_event_id] = WMI_DFS_RADAR_EVENTID; 22055 event_ids[wmi_pdev_l1ss_track_event_id] = WMI_PDEV_L1SS_TRACK_EVENTID; 22056 event_ids[wmi_pdev_temperature_event_id] = WMI_PDEV_TEMPERATURE_EVENTID; 22057 event_ids[wmi_service_ready_ext_event_id] = 22058 WMI_SERVICE_READY_EXT_EVENTID; 22059 event_ids[wmi_service_ready_ext2_event_id] = 22060 WMI_SERVICE_READY_EXT2_EVENTID; 22061 event_ids[wmi_vdev_start_resp_event_id] = WMI_VDEV_START_RESP_EVENTID; 22062 event_ids[wmi_vdev_stopped_event_id] = WMI_VDEV_STOPPED_EVENTID; 22063 event_ids[wmi_vdev_install_key_complete_event_id] = 22064 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID; 22065 event_ids[wmi_vdev_mcc_bcn_intvl_change_req_event_id] = 22066 WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID; 22067 22068 event_ids[wmi_vdev_tsf_report_event_id] = WMI_VDEV_TSF_REPORT_EVENTID; 22069 event_ids[wmi_peer_sta_kickout_event_id] = WMI_PEER_STA_KICKOUT_EVENTID; 22070 event_ids[wmi_peer_info_event_id] = WMI_PEER_INFO_EVENTID; 22071 event_ids[wmi_peer_tx_fail_cnt_thr_event_id] = 22072 WMI_PEER_TX_FAIL_CNT_THR_EVENTID; 22073 event_ids[wmi_peer_estimated_linkspeed_event_id] = 22074 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID; 22075 event_ids[wmi_peer_state_event_id] = WMI_PEER_STATE_EVENTID; 22076 event_ids[wmi_peer_create_conf_event_id] = 22077 WMI_PEER_CREATE_CONF_EVENTID; 22078 event_ids[wmi_peer_delete_response_event_id] = 22079 WMI_PEER_DELETE_RESP_EVENTID; 22080 event_ids[wmi_peer_delete_all_response_event_id] = 22081 WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID; 22082 event_ids[wmi_peer_oper_mode_change_event_id] = 22083 WMI_PEER_OPER_MODE_CHANGE_EVENTID; 22084 event_ids[wmi_mgmt_rx_event_id] = WMI_MGMT_RX_EVENTID; 22085 event_ids[wmi_host_swba_event_id] = WMI_HOST_SWBA_EVENTID; 22086 event_ids[wmi_tbttoffset_update_event_id] = 22087 WMI_TBTTOFFSET_UPDATE_EVENTID; 22088 event_ids[wmi_ext_tbttoffset_update_event_id] = 22089 WMI_TBTTOFFSET_EXT_UPDATE_EVENTID; 22090 event_ids[wmi_offload_bcn_tx_status_event_id] = 22091 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID; 22092 event_ids[wmi_offload_prob_resp_tx_status_event_id] = 22093 WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID; 22094 event_ids[wmi_mgmt_tx_completion_event_id] = 22095 WMI_MGMT_TX_COMPLETION_EVENTID; 22096 event_ids[wmi_pdev_nfcal_power_all_channels_event_id] = 22097 WMI_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID; 22098 event_ids[wmi_tx_delba_complete_event_id] = 22099 WMI_TX_DELBA_COMPLETE_EVENTID; 22100 event_ids[wmi_tx_addba_complete_event_id] = 22101 WMI_TX_ADDBA_COMPLETE_EVENTID; 22102 event_ids[wmi_ba_rsp_ssn_event_id] = WMI_BA_RSP_SSN_EVENTID; 22103 22104 event_ids[wmi_aggr_state_trig_event_id] = WMI_AGGR_STATE_TRIG_EVENTID; 22105 22106 event_ids[wmi_roam_event_id] = WMI_ROAM_EVENTID; 22107 event_ids[wmi_profile_match] = WMI_PROFILE_MATCH; 22108 22109 event_ids[wmi_roam_synch_event_id] = WMI_ROAM_SYNCH_EVENTID; 22110 event_ids[wmi_roam_synch_frame_event_id] = WMI_ROAM_SYNCH_FRAME_EVENTID; 22111 22112 event_ids[wmi_p2p_disc_event_id] = WMI_P2P_DISC_EVENTID; 22113 22114 event_ids[wmi_p2p_noa_event_id] = WMI_P2P_NOA_EVENTID; 22115 event_ids[wmi_p2p_lo_stop_event_id] = 22116 WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID; 22117 event_ids[wmi_vdev_add_macaddr_rx_filter_event_id] = 22118 WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID; 22119 event_ids[wmi_pdev_resume_event_id] = WMI_PDEV_RESUME_EVENTID; 22120 event_ids[wmi_wow_wakeup_host_event_id] = WMI_WOW_WAKEUP_HOST_EVENTID; 22121 event_ids[wmi_d0_wow_disable_ack_event_id] = 22122 WMI_D0_WOW_DISABLE_ACK_EVENTID; 22123 event_ids[wmi_wow_initial_wakeup_event_id] = 22124 WMI_WOW_INITIAL_WAKEUP_EVENTID; 22125 22126 event_ids[wmi_rtt_meas_report_event_id] = 22127 WMI_RTT_MEASUREMENT_REPORT_EVENTID; 22128 event_ids[wmi_tsf_meas_report_event_id] = 22129 WMI_TSF_MEASUREMENT_REPORT_EVENTID; 22130 event_ids[wmi_rtt_error_report_event_id] = WMI_RTT_ERROR_REPORT_EVENTID; 22131 event_ids[wmi_stats_ext_event_id] = WMI_STATS_EXT_EVENTID; 22132 event_ids[wmi_iface_link_stats_event_id] = WMI_IFACE_LINK_STATS_EVENTID; 22133 event_ids[wmi_peer_link_stats_event_id] = WMI_PEER_LINK_STATS_EVENTID; 22134 event_ids[wmi_radio_link_stats_link] = WMI_RADIO_LINK_STATS_EVENTID; 22135 event_ids[wmi_diag_event_id_log_supported_event_id] = 22136 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID; 22137 event_ids[wmi_nlo_match_event_id] = WMI_NLO_MATCH_EVENTID; 22138 event_ids[wmi_nlo_scan_complete_event_id] = 22139 WMI_NLO_SCAN_COMPLETE_EVENTID; 22140 event_ids[wmi_apfind_event_id] = WMI_APFIND_EVENTID; 22141 event_ids[wmi_passpoint_match_event_id] = WMI_PASSPOINT_MATCH_EVENTID; 22142 22143 event_ids[wmi_gtk_offload_status_event_id] = 22144 WMI_GTK_OFFLOAD_STATUS_EVENTID; 22145 event_ids[wmi_gtk_rekey_fail_event_id] = WMI_GTK_REKEY_FAIL_EVENTID; 22146 event_ids[wmi_csa_handling_event_id] = WMI_CSA_HANDLING_EVENTID; 22147 event_ids[wmi_chatter_pc_query_event_id] = WMI_CHATTER_PC_QUERY_EVENTID; 22148 22149 event_ids[wmi_echo_event_id] = WMI_ECHO_EVENTID; 22150 22151 event_ids[wmi_pdev_utf_event_id] = WMI_PDEV_UTF_EVENTID; 22152 22153 event_ids[wmi_dbg_msg_event_id] = WMI_DEBUG_MESG_EVENTID; 22154 event_ids[wmi_update_stats_event_id] = WMI_UPDATE_STATS_EVENTID; 22155 event_ids[wmi_debug_print_event_id] = WMI_DEBUG_PRINT_EVENTID; 22156 event_ids[wmi_dcs_interference_event_id] = WMI_DCS_INTERFERENCE_EVENTID; 22157 event_ids[wmi_pdev_qvit_event_id] = WMI_PDEV_QVIT_EVENTID; 22158 event_ids[wmi_wlan_profile_data_event_id] = 22159 WMI_WLAN_PROFILE_DATA_EVENTID; 22160 event_ids[wmi_pdev_ftm_intg_event_id] = WMI_PDEV_FTM_INTG_EVENTID; 22161 event_ids[wmi_wlan_freq_avoid_event_id] = WMI_WLAN_FREQ_AVOID_EVENTID; 22162 event_ids[wmi_vdev_get_keepalive_event_id] = 22163 WMI_VDEV_GET_KEEPALIVE_EVENTID; 22164 event_ids[wmi_thermal_mgmt_event_id] = WMI_THERMAL_MGMT_EVENTID; 22165 22166 event_ids[wmi_diag_container_event_id] = 22167 WMI_DIAG_DATA_CONTAINER_EVENTID; 22168 22169 event_ids[wmi_host_auto_shutdown_event_id] = 22170 WMI_HOST_AUTO_SHUTDOWN_EVENTID; 22171 22172 event_ids[wmi_update_whal_mib_stats_event_id] = 22173 WMI_UPDATE_WHAL_MIB_STATS_EVENTID; 22174 22175 /*update ht/vht info based on vdev (rx and tx NSS and preamble) */ 22176 event_ids[wmi_update_vdev_rate_stats_event_id] = 22177 WMI_UPDATE_VDEV_RATE_STATS_EVENTID; 22178 22179 event_ids[wmi_diag_event_id] = WMI_DIAG_EVENTID; 22180 event_ids[wmi_unit_test_event_id] = WMI_UNIT_TEST_EVENTID; 22181 22182 /** Set OCB Sched Response, deprecated */ 22183 event_ids[wmi_ocb_set_sched_event_id] = WMI_OCB_SET_SCHED_EVENTID; 22184 22185 event_ids[wmi_dbg_mesg_flush_complete_event_id] = 22186 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID; 22187 event_ids[wmi_rssi_breach_event_id] = WMI_RSSI_BREACH_EVENTID; 22188 22189 /* GPIO Event */ 22190 event_ids[wmi_gpio_input_event_id] = WMI_GPIO_INPUT_EVENTID; 22191 event_ids[wmi_uploadh_event_id] = WMI_UPLOADH_EVENTID; 22192 22193 event_ids[wmi_captureh_event_id] = WMI_CAPTUREH_EVENTID; 22194 event_ids[wmi_rfkill_state_change_event_id] = 22195 WMI_RFKILL_STATE_CHANGE_EVENTID; 22196 22197 /* TDLS Event */ 22198 event_ids[wmi_tdls_peer_event_id] = WMI_TDLS_PEER_EVENTID; 22199 22200 event_ids[wmi_batch_scan_enabled_event_id] = 22201 WMI_BATCH_SCAN_ENABLED_EVENTID; 22202 event_ids[wmi_batch_scan_result_event_id] = 22203 WMI_BATCH_SCAN_RESULT_EVENTID; 22204 /* OEM Event */ 22205 event_ids[wmi_oem_cap_event_id] = WMI_OEM_CAPABILITY_EVENTID; 22206 event_ids[wmi_oem_meas_report_event_id] = 22207 WMI_OEM_MEASUREMENT_REPORT_EVENTID; 22208 event_ids[wmi_oem_report_event_id] = WMI_OEM_ERROR_REPORT_EVENTID; 22209 22210 /* NAN Event */ 22211 event_ids[wmi_nan_event_id] = WMI_NAN_EVENTID; 22212 22213 /* LPI Event */ 22214 event_ids[wmi_lpi_result_event_id] = WMI_LPI_RESULT_EVENTID; 22215 event_ids[wmi_lpi_status_event_id] = WMI_LPI_STATUS_EVENTID; 22216 event_ids[wmi_lpi_handoff_event_id] = WMI_LPI_HANDOFF_EVENTID; 22217 22218 /* ExtScan events */ 22219 event_ids[wmi_extscan_start_stop_event_id] = 22220 WMI_EXTSCAN_START_STOP_EVENTID; 22221 event_ids[wmi_extscan_operation_event_id] = 22222 WMI_EXTSCAN_OPERATION_EVENTID; 22223 event_ids[wmi_extscan_table_usage_event_id] = 22224 WMI_EXTSCAN_TABLE_USAGE_EVENTID; 22225 event_ids[wmi_extscan_cached_results_event_id] = 22226 WMI_EXTSCAN_CACHED_RESULTS_EVENTID; 22227 event_ids[wmi_extscan_wlan_change_results_event_id] = 22228 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID; 22229 event_ids[wmi_extscan_hotlist_match_event_id] = 22230 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID; 22231 event_ids[wmi_extscan_capabilities_event_id] = 22232 WMI_EXTSCAN_CAPABILITIES_EVENTID; 22233 event_ids[wmi_extscan_hotlist_ssid_match_event_id] = 22234 WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID; 22235 22236 /* mDNS offload events */ 22237 event_ids[wmi_mdns_stats_event_id] = WMI_MDNS_STATS_EVENTID; 22238 22239 /* SAP Authentication offload events */ 22240 event_ids[wmi_sap_ofl_add_sta_event_id] = WMI_SAP_OFL_ADD_STA_EVENTID; 22241 event_ids[wmi_sap_ofl_del_sta_event_id] = WMI_SAP_OFL_DEL_STA_EVENTID; 22242 22243 /** Out-of-context-of-bss (OCB) events */ 22244 event_ids[wmi_ocb_set_config_resp_event_id] = 22245 WMI_OCB_SET_CONFIG_RESP_EVENTID; 22246 event_ids[wmi_ocb_get_tsf_timer_resp_event_id] = 22247 WMI_OCB_GET_TSF_TIMER_RESP_EVENTID; 22248 event_ids[wmi_dcc_get_stats_resp_event_id] = 22249 WMI_DCC_GET_STATS_RESP_EVENTID; 22250 event_ids[wmi_dcc_update_ndl_resp_event_id] = 22251 WMI_DCC_UPDATE_NDL_RESP_EVENTID; 22252 event_ids[wmi_dcc_stats_event_id] = WMI_DCC_STATS_EVENTID; 22253 /* System-On-Chip events */ 22254 event_ids[wmi_soc_set_hw_mode_resp_event_id] = 22255 WMI_SOC_SET_HW_MODE_RESP_EVENTID; 22256 event_ids[wmi_soc_hw_mode_transition_event_id] = 22257 WMI_SOC_HW_MODE_TRANSITION_EVENTID; 22258 event_ids[wmi_soc_set_dual_mac_config_resp_event_id] = 22259 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID; 22260 event_ids[wmi_pdev_fips_event_id] = WMI_PDEV_FIPS_EVENTID; 22261 #ifdef WLAN_FEATURE_FIPS_BER_CCMGCM 22262 event_ids[wmi_pdev_fips_extend_event_id] = WMI_PDEV_FIPS_EXTEND_EVENTID; 22263 #endif 22264 event_ids[wmi_pdev_csa_switch_count_status_event_id] = 22265 WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID; 22266 event_ids[wmi_vdev_ocac_complete_event_id] = 22267 WMI_VDEV_ADFS_OCAC_COMPLETE_EVENTID; 22268 event_ids[wmi_reg_chan_list_cc_event_id] = WMI_REG_CHAN_LIST_CC_EVENTID; 22269 event_ids[wmi_reg_chan_list_cc_ext_event_id] = 22270 WMI_REG_CHAN_LIST_CC_EXT_EVENTID; 22271 #ifdef CONFIG_AFC_SUPPORT 22272 event_ids[wmi_afc_event_id] = WMI_AFC_EVENTID, 22273 #endif 22274 event_ids[wmi_inst_rssi_stats_event_id] = WMI_INST_RSSI_STATS_EVENTID; 22275 event_ids[wmi_pdev_tpc_config_event_id] = WMI_PDEV_TPC_CONFIG_EVENTID; 22276 event_ids[wmi_peer_sta_ps_statechg_event_id] = 22277 WMI_PEER_STA_PS_STATECHG_EVENTID; 22278 event_ids[wmi_pdev_channel_hopping_event_id] = 22279 WMI_PDEV_CHANNEL_HOPPING_EVENTID; 22280 event_ids[wmi_offchan_data_tx_completion_event] = 22281 WMI_OFFCHAN_DATA_TX_COMPLETION_EVENTID; 22282 event_ids[wmi_dfs_cac_complete_id] = WMI_VDEV_DFS_CAC_COMPLETE_EVENTID; 22283 event_ids[wmi_dfs_radar_detection_event_id] = 22284 WMI_PDEV_DFS_RADAR_DETECTION_EVENTID; 22285 event_ids[wmi_tt_stats_event_id] = WMI_THERM_THROT_STATS_EVENTID; 22286 event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID; 22287 event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID; 22288 event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID; 22289 event_ids[wmi_service_available_event_id] = 22290 WMI_SERVICE_AVAILABLE_EVENTID; 22291 event_ids[wmi_update_rcpi_event_id] = WMI_UPDATE_RCPI_EVENTID; 22292 event_ids[wmi_pdev_check_cal_version_event_id] = WMI_PDEV_CHECK_CAL_VERSION_EVENTID; 22293 /* NDP events */ 22294 event_ids[wmi_ndp_initiator_rsp_event_id] = 22295 WMI_NDP_INITIATOR_RSP_EVENTID; 22296 event_ids[wmi_ndp_indication_event_id] = WMI_NDP_INDICATION_EVENTID; 22297 event_ids[wmi_ndp_confirm_event_id] = WMI_NDP_CONFIRM_EVENTID; 22298 event_ids[wmi_ndp_responder_rsp_event_id] = 22299 WMI_NDP_RESPONDER_RSP_EVENTID; 22300 event_ids[wmi_ndp_end_indication_event_id] = 22301 WMI_NDP_END_INDICATION_EVENTID; 22302 event_ids[wmi_ndp_end_rsp_event_id] = WMI_NDP_END_RSP_EVENTID; 22303 event_ids[wmi_ndl_schedule_update_event_id] = 22304 WMI_NDL_SCHEDULE_UPDATE_EVENTID; 22305 event_ids[wmi_ndp_event_id] = WMI_NDP_EVENTID; 22306 22307 event_ids[wmi_oem_response_event_id] = WMI_OEM_RESPONSE_EVENTID; 22308 event_ids[wmi_peer_stats_info_event_id] = WMI_PEER_STATS_INFO_EVENTID; 22309 event_ids[wmi_pdev_chip_power_stats_event_id] = 22310 WMI_PDEV_CHIP_POWER_STATS_EVENTID; 22311 event_ids[wmi_ap_ps_egap_info_event_id] = WMI_AP_PS_EGAP_INFO_EVENTID; 22312 event_ids[wmi_peer_assoc_conf_event_id] = WMI_PEER_ASSOC_CONF_EVENTID; 22313 event_ids[wmi_vdev_delete_resp_event_id] = WMI_VDEV_DELETE_RESP_EVENTID; 22314 event_ids[wmi_apf_capability_info_event_id] = 22315 WMI_BPF_CAPABILIY_INFO_EVENTID; 22316 event_ids[wmi_vdev_encrypt_decrypt_data_rsp_event_id] = 22317 WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID; 22318 event_ids[wmi_report_rx_aggr_failure_event_id] = 22319 WMI_REPORT_RX_AGGR_FAILURE_EVENTID; 22320 event_ids[wmi_pdev_chip_pwr_save_failure_detect_event_id] = 22321 WMI_PDEV_CHIP_POWER_SAVE_FAILURE_DETECTED_EVENTID; 22322 event_ids[wmi_peer_antdiv_info_event_id] = WMI_PEER_ANTDIV_INFO_EVENTID; 22323 event_ids[wmi_pdev_set_hw_mode_rsp_event_id] = 22324 WMI_PDEV_SET_HW_MODE_RESP_EVENTID; 22325 event_ids[wmi_pdev_hw_mode_transition_event_id] = 22326 WMI_PDEV_HW_MODE_TRANSITION_EVENTID; 22327 event_ids[wmi_pdev_set_mac_config_resp_event_id] = 22328 WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID; 22329 event_ids[wmi_coex_bt_activity_event_id] = 22330 WMI_WLAN_COEX_BT_ACTIVITY_EVENTID; 22331 event_ids[wmi_mgmt_tx_bundle_completion_event_id] = 22332 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID; 22333 event_ids[wmi_radio_tx_power_level_stats_event_id] = 22334 WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID; 22335 event_ids[wmi_report_stats_event_id] = WMI_REPORT_STATS_EVENTID; 22336 event_ids[wmi_dma_buf_release_event_id] = 22337 WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID; 22338 event_ids[wmi_sap_obss_detection_report_event_id] = 22339 WMI_SAP_OBSS_DETECTION_REPORT_EVENTID; 22340 event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; 22341 event_ids[wmi_sar_get_limits_event_id] = WMI_SAR_GET_LIMITS_EVENTID; 22342 event_ids[wmi_obss_color_collision_report_event_id] = 22343 WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID; 22344 event_ids[wmi_pdev_div_rssi_antid_event_id] = 22345 WMI_PDEV_DIV_RSSI_ANTID_EVENTID; 22346 #ifdef WLAN_SUPPORT_TWT 22347 event_ids[wmi_twt_enable_complete_event_id] = 22348 WMI_TWT_ENABLE_COMPLETE_EVENTID; 22349 event_ids[wmi_twt_disable_complete_event_id] = 22350 WMI_TWT_DISABLE_COMPLETE_EVENTID; 22351 event_ids[wmi_twt_add_dialog_complete_event_id] = 22352 WMI_TWT_ADD_DIALOG_COMPLETE_EVENTID; 22353 event_ids[wmi_twt_del_dialog_complete_event_id] = 22354 WMI_TWT_DEL_DIALOG_COMPLETE_EVENTID; 22355 event_ids[wmi_twt_pause_dialog_complete_event_id] = 22356 WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; 22357 event_ids[wmi_twt_resume_dialog_complete_event_id] = 22358 WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; 22359 event_ids[wmi_twt_nudge_dialog_complete_event_id] = 22360 WMI_TWT_NUDGE_DIALOG_COMPLETE_EVENTID; 22361 event_ids[wmi_twt_session_stats_event_id] = 22362 WMI_TWT_SESSION_STATS_EVENTID; 22363 event_ids[wmi_twt_notify_event_id] = 22364 WMI_TWT_NOTIFY_EVENTID; 22365 event_ids[wmi_twt_ack_complete_event_id] = 22366 WMI_TWT_ACK_EVENTID; 22367 #endif 22368 event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = 22369 WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; 22370 event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID; 22371 event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID; 22372 event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID; 22373 #ifdef WLAN_FEATURE_INTEROP_ISSUES_AP 22374 event_ids[wmi_pdev_interop_issues_ap_event_id] = 22375 WMI_PDEV_RAP_INFO_EVENTID; 22376 #endif 22377 #ifdef AST_HKV1_WORKAROUND 22378 event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID; 22379 #endif 22380 event_ids[wmi_pdev_ctl_failsafe_check_event_id] = 22381 WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID; 22382 event_ids[wmi_vdev_bcn_reception_stats_event_id] = 22383 WMI_VDEV_BCN_RECEPTION_STATS_EVENTID; 22384 event_ids[wmi_roam_denylist_event_id] = WMI_ROAM_BLACKLIST_EVENTID; 22385 event_ids[wmi_wlm_stats_event_id] = WMI_WLM_STATS_EVENTID; 22386 event_ids[wmi_peer_cfr_capture_event_id] = WMI_PEER_CFR_CAPTURE_EVENTID; 22387 event_ids[wmi_pdev_cold_boot_cal_event_id] = 22388 WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID; 22389 #ifdef WLAN_MWS_INFO_DEBUGFS 22390 event_ids[wmi_vdev_get_mws_coex_state_eventid] = 22391 WMI_VDEV_GET_MWS_COEX_STATE_EVENTID; 22392 event_ids[wmi_vdev_get_mws_coex_dpwb_state_eventid] = 22393 WMI_VDEV_GET_MWS_COEX_DPWB_STATE_EVENTID; 22394 event_ids[wmi_vdev_get_mws_coex_tdm_state_eventid] = 22395 WMI_VDEV_GET_MWS_COEX_TDM_STATE_EVENTID; 22396 event_ids[wmi_vdev_get_mws_coex_idrx_state_eventid] = 22397 WMI_VDEV_GET_MWS_COEX_IDRX_STATE_EVENTID; 22398 event_ids[wmi_vdev_get_mws_coex_antenna_sharing_state_eventid] = 22399 WMI_VDEV_GET_MWS_COEX_ANTENNA_SHARING_STATE_EVENTID; 22400 #endif 22401 event_ids[wmi_coex_report_antenna_isolation_event_id] = 22402 WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID; 22403 event_ids[wmi_peer_ratecode_list_event_id] = 22404 WMI_PEER_RATECODE_LIST_EVENTID; 22405 event_ids[wmi_chan_rf_characterization_info_event_id] = 22406 WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; 22407 event_ids[wmi_roam_auth_offload_event_id] = 22408 WMI_ROAM_PREAUTH_START_EVENTID; 22409 event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; 22410 event_ids[wmi_motion_det_host_eventid] = WMI_MOTION_DET_HOST_EVENTID; 22411 event_ids[wmi_motion_det_base_line_host_eventid] = 22412 WMI_MOTION_DET_BASE_LINE_HOST_EVENTID; 22413 event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID; 22414 event_ids[wmi_peer_tx_pn_response_event_id] = 22415 WMI_PEER_TX_PN_RESPONSE_EVENTID; 22416 event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID; 22417 event_ids[wmi_oem_data_event_id] = WMI_OEM_DATA_EVENTID; 22418 event_ids[wmi_mgmt_offload_data_event_id] = 22419 WMI_VDEV_MGMT_OFFLOAD_EVENTID; 22420 event_ids[wmi_nan_dmesg_event_id] = 22421 WMI_NAN_DMESG_EVENTID; 22422 event_ids[wmi_pdev_multi_vdev_restart_response_event_id] = 22423 WMI_PDEV_MULTIPLE_VDEV_RESTART_RESP_EVENTID; 22424 event_ids[wmi_roam_pmkid_request_event_id] = 22425 WMI_ROAM_PMKID_REQUEST_EVENTID; 22426 #ifdef FEATURE_WLAN_TIME_SYNC_FTM 22427 event_ids[wmi_wlan_time_sync_ftm_start_stop_event_id] = 22428 WMI_VDEV_AUDIO_SYNC_START_STOP_EVENTID; 22429 event_ids[wmi_wlan_time_sync_q_initiator_target_offset_eventid] = 22430 WMI_VDEV_AUDIO_SYNC_Q_MASTER_SLAVE_OFFSET_EVENTID; 22431 #endif 22432 event_ids[wmi_roam_scan_chan_list_id] = 22433 WMI_ROAM_SCAN_CHANNEL_LIST_EVENTID; 22434 event_ids[wmi_muedca_params_config_eventid] = 22435 WMI_MUEDCA_PARAMS_CONFIG_EVENTID; 22436 event_ids[wmi_pdev_sscan_fw_param_eventid] = 22437 WMI_PDEV_SSCAN_FW_PARAM_EVENTID; 22438 event_ids[wmi_roam_cap_report_event_id] = 22439 WMI_ROAM_CAPABILITY_REPORT_EVENTID; 22440 event_ids[wmi_vdev_bcn_latency_event_id] = 22441 WMI_VDEV_BCN_LATENCY_EVENTID; 22442 event_ids[wmi_vdev_disconnect_event_id] = 22443 WMI_VDEV_DISCONNECT_EVENTID; 22444 event_ids[wmi_peer_create_conf_event_id] = 22445 WMI_PEER_CREATE_CONF_EVENTID; 22446 event_ids[wmi_pdev_cp_fwstats_eventid] = 22447 WMI_CTRL_PATH_STATS_EVENTID; 22448 event_ids[wmi_pdev_halphy_fwstats_eventid] = 22449 WMI_HALPHY_CTRL_PATH_STATS_EVENTID; 22450 event_ids[wmi_vdev_send_big_data_p2_eventid] = 22451 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID; 22452 event_ids[wmi_pdev_get_dpd_status_event_id] = 22453 WMI_PDEV_GET_DPD_STATUS_EVENTID; 22454 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 22455 event_ids[wmi_vdev_smart_monitor_event_id] = 22456 WMI_VDEV_SMART_MONITOR_EVENTID; 22457 #endif 22458 event_ids[wmi_pdev_get_halphy_cal_status_event_id] = 22459 WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID; 22460 event_ids[wmi_pdev_set_halphy_cal_event_id] = 22461 WMI_PDEV_SET_HALPHY_CAL_BMAP_EVENTID; 22462 event_ids[wmi_pdev_aoa_phasedelta_event_id] = 22463 WMI_PDEV_AOA_PHASEDELTA_EVENTID; 22464 #ifdef WLAN_MGMT_RX_REO_SUPPORT 22465 event_ids[wmi_mgmt_rx_fw_consumed_eventid] = 22466 WMI_MGMT_RX_FW_CONSUMED_EVENTID; 22467 #endif 22468 populate_tlv_events_id_mlo(event_ids); 22469 event_ids[wmi_roam_frame_event_id] = 22470 WMI_ROAM_FRAME_EVENTID; 22471 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 22472 event_ids[wmi_vdev_update_mac_addr_conf_eventid] = 22473 WMI_VDEV_UPDATE_MAC_ADDR_CONF_EVENTID; 22474 #endif 22475 #ifdef WLAN_FEATURE_MCC_QUOTA 22476 event_ids[wmi_resmgr_chan_time_quota_changed_eventid] = 22477 WMI_RESMGR_CHAN_TIME_QUOTA_CHANGED_EVENTID; 22478 #endif 22479 event_ids[wmi_peer_rx_pn_response_event_id] = 22480 WMI_PEER_RX_PN_RESPONSE_EVENTID; 22481 event_ids[wmi_extract_pktlog_decode_info_eventid] = 22482 WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID; 22483 #ifdef QCA_RSSI_DB2DBM 22484 event_ids[wmi_pdev_rssi_dbm_conversion_params_info_eventid] = 22485 WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID; 22486 #endif 22487 #ifdef MULTI_CLIENT_LL_SUPPORT 22488 event_ids[wmi_vdev_latency_event_id] = WMI_VDEV_LATENCY_LEVEL_EVENTID; 22489 #endif 22490 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22491 event_ids[wmi_rtt_pasn_peer_create_req_eventid] = 22492 WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID; 22493 event_ids[wmi_rtt_pasn_peer_delete_eventid] = 22494 WMI_RTT_PASN_PEER_DELETE_EVENTID; 22495 #endif 22496 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 22497 event_ids[wmi_get_roam_vendor_control_param_event_id] = 22498 WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; 22499 #endif 22500 #ifdef WLAN_FEATURE_DBAM_CONFIG 22501 event_ids[wmi_coex_dbam_complete_event_id] = 22502 WMI_COEX_DBAM_COMPLETE_EVENTID; 22503 #endif 22504 event_ids[wmi_spectral_capabilities_eventid] = 22505 WMI_SPECTRAL_CAPABILITIES_EVENTID; 22506 #ifdef WLAN_FEATURE_COAP 22507 event_ids[wmi_wow_coap_buf_info_eventid] = 22508 WMI_WOW_COAP_BUF_INFO_EVENTID; 22509 #endif 22510 #ifdef HEALTH_MON_SUPPORT 22511 event_ids[wmi_extract_health_mon_init_done_info_eventid] = 22512 WMI_HEALTH_MON_INIT_DONE_EVENTID; 22513 #endif /* HEALTH_MON_SUPPORT */ 22514 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 22515 event_ids[wmi_xgap_enable_complete_eventid] = 22516 WMI_XGAP_ENABLE_COMPLETE_EVENTID; 22517 #endif 22518 event_ids[wmi_pdev_set_tgtr2p_table_eventid] = 22519 WMI_PDEV_SET_TGTR2P_TABLE_EVENTID; 22520 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 22521 event_ids[wmi_manual_ul_ofdma_trig_feedback_eventid] = 22522 WMI_MANUAL_UL_OFDMA_TRIG_FEEDBACK_EVENTID; 22523 event_ids[wmi_manual_ul_ofdma_trig_rx_peer_userinfo_eventid] = 22524 WMI_MANUAL_UL_OFDMA_TRIG_RX_PEER_USERINFO_EVENTID; 22525 #endif 22526 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 22527 event_ids[wmi_vdev_standalone_sound_complete_eventid] = 22528 WMI_VDEV_STANDALONE_SOUND_COMPLETE_EVENTID; 22529 #endif 22530 event_ids[wmi_csa_ie_received_event_id] = WMI_CSA_IE_RECEIVED_EVENTID; 22531 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO) 22532 event_ids[wmi_roam_synch_key_event_id] = WMI_ROAM_SYNCH_KEY_EVENTID; 22533 #endif 22534 #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE 22535 event_ids[wmi_peer_ptqm_migration_response_eventid] = 22536 WMI_MLO_PRIMARY_LINK_PEER_MIGRATION_EVENTID; 22537 #endif 22538 event_ids[wmi_pdev_set_rf_path_resp_eventid] = 22539 WMI_PDEV_SET_RF_PATH_RESP_EVENTID; 22540 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 22541 event_ids[wmi_pdev_enhanced_aoa_phasedelta_eventid] = 22542 WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID; 22543 #endif 22544 #ifdef WLAN_FEATURE_LL_LT_SAP 22545 event_ids[wmi_audio_transport_switch_type_event_id] = 22546 WMI_AUDIO_TRANSPORT_SWITCH_TYPE_EVENTID; 22547 #endif 22548 22549 } 22550 22551 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 22552 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 22553 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22554 { 22555 wmi_service[wmi_service_get_station_in_ll_stats_req] = 22556 WMI_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT; 22557 } 22558 #else 22559 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22560 { 22561 } 22562 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 22563 #else 22564 static void wmi_populate_service_get_sta_in_ll_stats_req(uint32_t *wmi_service) 22565 { 22566 } 22567 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 22568 22569 #ifdef WLAN_FEATURE_11BE_MLO 22570 static void populate_tlv_service_mlo(uint32_t *wmi_service) 22571 { 22572 wmi_service[wmi_service_mlo_sta_nan_ndi_support] = 22573 WMI_SERVICE_MLO_STA_NAN_NDI_SUPPORT; 22574 } 22575 #else /* WLAN_FEATURE_11BE_MLO */ 22576 static inline void populate_tlv_service_mlo(uint32_t *wmi_service) 22577 { 22578 } 22579 #endif /* WLAN_FEATURE_11BE_MLO */ 22580 22581 /** 22582 * populate_tlv_service() - populates wmi services 22583 * @wmi_service: Pointer to hold wmi_service 22584 * 22585 * Return: None 22586 */ 22587 static void populate_tlv_service(uint32_t *wmi_service) 22588 { 22589 wmi_service[wmi_service_beacon_offload] = WMI_SERVICE_BEACON_OFFLOAD; 22590 wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_ACK_TIMEOUT; 22591 wmi_service[wmi_service_scan_offload] = WMI_SERVICE_SCAN_OFFLOAD; 22592 wmi_service[wmi_service_roam_scan_offload] = 22593 WMI_SERVICE_ROAM_SCAN_OFFLOAD; 22594 wmi_service[wmi_service_bcn_miss_offload] = 22595 WMI_SERVICE_BCN_MISS_OFFLOAD; 22596 wmi_service[wmi_service_sta_pwrsave] = WMI_SERVICE_STA_PWRSAVE; 22597 wmi_service[wmi_service_sta_advanced_pwrsave] = 22598 WMI_SERVICE_STA_ADVANCED_PWRSAVE; 22599 wmi_service[wmi_service_ap_uapsd] = WMI_SERVICE_AP_UAPSD; 22600 wmi_service[wmi_service_ap_dfs] = WMI_SERVICE_AP_DFS; 22601 wmi_service[wmi_service_11ac] = WMI_SERVICE_11AC; 22602 wmi_service[wmi_service_blockack] = WMI_SERVICE_BLOCKACK; 22603 wmi_service[wmi_service_phyerr] = WMI_SERVICE_PHYERR; 22604 wmi_service[wmi_service_bcn_filter] = WMI_SERVICE_BCN_FILTER; 22605 wmi_service[wmi_service_rtt] = WMI_SERVICE_RTT; 22606 wmi_service[wmi_service_wow] = WMI_SERVICE_WOW; 22607 wmi_service[wmi_service_ratectrl_cache] = WMI_SERVICE_RATECTRL_CACHE; 22608 wmi_service[wmi_service_iram_tids] = WMI_SERVICE_IRAM_TIDS; 22609 wmi_service[wmi_service_arpns_offload] = WMI_SERVICE_ARPNS_OFFLOAD; 22610 wmi_service[wmi_service_nlo] = WMI_SERVICE_NLO; 22611 wmi_service[wmi_service_gtk_offload] = WMI_SERVICE_GTK_OFFLOAD; 22612 wmi_service[wmi_service_scan_sch] = WMI_SERVICE_SCAN_SCH; 22613 wmi_service[wmi_service_csa_offload] = WMI_SERVICE_CSA_OFFLOAD; 22614 wmi_service[wmi_service_chatter] = WMI_SERVICE_CHATTER; 22615 wmi_service[wmi_service_coex_freqavoid] = WMI_SERVICE_COEX_FREQAVOID; 22616 wmi_service[wmi_service_packet_power_save] = 22617 WMI_SERVICE_PACKET_POWER_SAVE; 22618 wmi_service[wmi_service_force_fw_hang] = WMI_SERVICE_FORCE_FW_HANG; 22619 wmi_service[wmi_service_gpio] = WMI_SERVICE_GPIO; 22620 wmi_service[wmi_service_sta_dtim_ps_modulated_dtim] = 22621 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM; 22622 wmi_service[wmi_sta_uapsd_basic_auto_trig] = 22623 WMI_STA_UAPSD_BASIC_AUTO_TRIG; 22624 wmi_service[wmi_sta_uapsd_var_auto_trig] = WMI_STA_UAPSD_VAR_AUTO_TRIG; 22625 wmi_service[wmi_service_sta_keep_alive] = WMI_SERVICE_STA_KEEP_ALIVE; 22626 wmi_service[wmi_service_tx_encap] = WMI_SERVICE_TX_ENCAP; 22627 wmi_service[wmi_service_ap_ps_detect_out_of_sync] = 22628 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC; 22629 wmi_service[wmi_service_early_rx] = WMI_SERVICE_EARLY_RX; 22630 wmi_service[wmi_service_sta_smps] = WMI_SERVICE_STA_SMPS; 22631 wmi_service[wmi_service_fwtest] = WMI_SERVICE_FWTEST; 22632 wmi_service[wmi_service_sta_wmmac] = WMI_SERVICE_STA_WMMAC; 22633 wmi_service[wmi_service_tdls] = WMI_SERVICE_TDLS; 22634 wmi_service[wmi_service_burst] = WMI_SERVICE_BURST; 22635 wmi_service[wmi_service_mcc_bcn_interval_change] = 22636 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE; 22637 wmi_service[wmi_service_adaptive_ocs] = WMI_SERVICE_ADAPTIVE_OCS; 22638 wmi_service[wmi_service_ba_ssn_support] = WMI_SERVICE_BA_SSN_SUPPORT; 22639 wmi_service[wmi_service_filter_ipsec_natkeepalive] = 22640 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE; 22641 wmi_service[wmi_service_wlan_hb] = WMI_SERVICE_WLAN_HB; 22642 wmi_service[wmi_service_lte_ant_share_support] = 22643 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT; 22644 wmi_service[wmi_service_batch_scan] = WMI_SERVICE_BATCH_SCAN; 22645 wmi_service[wmi_service_qpower] = WMI_SERVICE_QPOWER; 22646 wmi_service[wmi_service_plmreq] = WMI_SERVICE_PLMREQ; 22647 wmi_service[wmi_service_thermal_mgmt] = WMI_SERVICE_THERMAL_MGMT; 22648 wmi_service[wmi_service_rmc] = WMI_SERVICE_RMC; 22649 wmi_service[wmi_service_mhf_offload] = WMI_SERVICE_MHF_OFFLOAD; 22650 wmi_service[wmi_service_coex_sar] = WMI_SERVICE_COEX_SAR; 22651 wmi_service[wmi_service_bcn_txrate_override] = 22652 WMI_SERVICE_BCN_TXRATE_OVERRIDE; 22653 wmi_service[wmi_service_nan] = WMI_SERVICE_NAN; 22654 wmi_service[wmi_service_l1ss_stat] = WMI_SERVICE_L1SS_STAT; 22655 wmi_service[wmi_service_estimate_linkspeed] = 22656 WMI_SERVICE_ESTIMATE_LINKSPEED; 22657 wmi_service[wmi_service_obss_scan] = WMI_SERVICE_OBSS_SCAN; 22658 wmi_service[wmi_service_tdls_offchan] = WMI_SERVICE_TDLS_OFFCHAN; 22659 wmi_service[wmi_service_tdls_uapsd_buffer_sta] = 22660 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA; 22661 wmi_service[wmi_service_tdls_uapsd_sleep_sta] = 22662 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA; 22663 wmi_service[wmi_service_ibss_pwrsave] = WMI_SERVICE_IBSS_PWRSAVE; 22664 wmi_service[wmi_service_lpass] = WMI_SERVICE_LPASS; 22665 wmi_service[wmi_service_extscan] = WMI_SERVICE_EXTSCAN; 22666 wmi_service[wmi_service_d0wow] = WMI_SERVICE_D0WOW; 22667 wmi_service[wmi_service_hsoffload] = WMI_SERVICE_HSOFFLOAD; 22668 wmi_service[wmi_service_roam_ho_offload] = WMI_SERVICE_ROAM_HO_OFFLOAD; 22669 wmi_service[wmi_service_rx_full_reorder] = WMI_SERVICE_RX_FULL_REORDER; 22670 wmi_service[wmi_service_dhcp_offload] = WMI_SERVICE_DHCP_OFFLOAD; 22671 wmi_service[wmi_service_sta_rx_ipa_offload_support] = 22672 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT; 22673 wmi_service[wmi_service_mdns_offload] = WMI_SERVICE_MDNS_OFFLOAD; 22674 wmi_service[wmi_service_sap_auth_offload] = 22675 WMI_SERVICE_SAP_AUTH_OFFLOAD; 22676 wmi_service[wmi_service_dual_band_simultaneous_support] = 22677 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT; 22678 wmi_service[wmi_service_ocb] = WMI_SERVICE_OCB; 22679 wmi_service[wmi_service_ap_arpns_offload] = 22680 WMI_SERVICE_AP_ARPNS_OFFLOAD; 22681 wmi_service[wmi_service_per_band_chainmask_support] = 22682 WMI_SERVICE_PER_BAND_CHAINMASK_SUPPORT; 22683 wmi_service[wmi_service_packet_filter_offload] = 22684 WMI_SERVICE_PACKET_FILTER_OFFLOAD; 22685 wmi_service[wmi_service_mgmt_tx_htt] = WMI_SERVICE_MGMT_TX_HTT; 22686 wmi_service[wmi_service_mgmt_tx_wmi] = WMI_SERVICE_MGMT_TX_WMI; 22687 wmi_service[wmi_service_ext_msg] = WMI_SERVICE_EXT_MSG; 22688 wmi_service[wmi_service_ext2_msg] = WMI_SERVICE_EXT2_MSG; 22689 wmi_service[wmi_service_mawc] = WMI_SERVICE_MAWC; 22690 wmi_service[wmi_service_multiple_vdev_restart] = 22691 WMI_SERVICE_MULTIPLE_VDEV_RESTART; 22692 wmi_service[wmi_service_multiple_vdev_restart_bmap] = 22693 WMI_SERVICE_MULTIPLE_VDEV_RESTART_BITMAP_SUPPORT; 22694 wmi_service[wmi_service_smart_antenna_sw_support] = 22695 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT; 22696 wmi_service[wmi_service_smart_antenna_hw_support] = 22697 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT; 22698 22699 wmi_service[wmi_service_roam_offload] = WMI_SERVICE_UNAVAILABLE; 22700 wmi_service[wmi_service_ratectrl] = WMI_SERVICE_UNAVAILABLE; 22701 wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE; 22702 wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT; 22703 wmi_service[wmi_service_atf] = WMI_SERVICE_ATF; 22704 wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE; 22705 wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE; 22706 wmi_service[wmi_service_aux_spectral_intf] = WMI_SERVICE_UNAVAILABLE; 22707 wmi_service[wmi_service_aux_chan_load_intf] = WMI_SERVICE_UNAVAILABLE; 22708 wmi_service[wmi_service_bss_channel_info_64] = WMI_SERVICE_UNAVAILABLE; 22709 wmi_service[wmi_service_ext_res_cfg_support] = WMI_SERVICE_UNAVAILABLE; 22710 wmi_service[wmi_service_mesh] = WMI_SERVICE_UNAVAILABLE; 22711 wmi_service[wmi_service_restrt_chnl_support] = WMI_SERVICE_UNAVAILABLE; 22712 wmi_service[wmi_service_peer_stats] = WMI_SERVICE_UNAVAILABLE; 22713 wmi_service[wmi_service_mesh_11s] = WMI_SERVICE_UNAVAILABLE; 22714 wmi_service[wmi_service_periodic_chan_stat_support] = 22715 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT; 22716 wmi_service[wmi_service_tx_mode_push_only] = WMI_SERVICE_UNAVAILABLE; 22717 wmi_service[wmi_service_tx_mode_push_pull] = WMI_SERVICE_UNAVAILABLE; 22718 wmi_service[wmi_service_tx_mode_dynamic] = WMI_SERVICE_UNAVAILABLE; 22719 wmi_service[wmi_service_btcoex_duty_cycle] = WMI_SERVICE_UNAVAILABLE; 22720 wmi_service[wmi_service_4_wire_coex_support] = WMI_SERVICE_UNAVAILABLE; 22721 wmi_service[wmi_service_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22722 wmi_service[wmi_service_peer_assoc_conf] = WMI_SERVICE_PEER_ASSOC_CONF; 22723 wmi_service[wmi_service_egap] = WMI_SERVICE_EGAP; 22724 wmi_service[wmi_service_sta_pmf_offload] = WMI_SERVICE_STA_PMF_OFFLOAD; 22725 wmi_service[wmi_service_unified_wow_capability] = 22726 WMI_SERVICE_UNIFIED_WOW_CAPABILITY; 22727 wmi_service[wmi_service_enterprise_mesh] = WMI_SERVICE_ENTERPRISE_MESH; 22728 wmi_service[wmi_service_apf_offload] = WMI_SERVICE_BPF_OFFLOAD; 22729 wmi_service[wmi_service_sync_delete_cmds] = 22730 WMI_SERVICE_SYNC_DELETE_CMDS; 22731 wmi_service[wmi_service_ratectrl_limit_max_min_rates] = 22732 WMI_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES; 22733 wmi_service[wmi_service_nan_data] = WMI_SERVICE_NAN_DATA; 22734 wmi_service[wmi_service_nan_rtt] = WMI_SERVICE_NAN_RTT; 22735 wmi_service[wmi_service_11ax] = WMI_SERVICE_11AX; 22736 wmi_service[wmi_service_deprecated_replace] = 22737 WMI_SERVICE_DEPRECATED_REPLACE; 22738 wmi_service[wmi_service_tdls_conn_tracker_in_host_mode] = 22739 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE; 22740 wmi_service[wmi_service_enhanced_mcast_filter] = 22741 WMI_SERVICE_ENHANCED_MCAST_FILTER; 22742 wmi_service[wmi_service_half_rate_quarter_rate_support] = 22743 WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT; 22744 wmi_service[wmi_service_vdev_rx_filter] = WMI_SERVICE_VDEV_RX_FILTER; 22745 wmi_service[wmi_service_p2p_listen_offload_support] = 22746 WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT; 22747 wmi_service[wmi_service_mark_first_wakeup_packet] = 22748 WMI_SERVICE_MARK_FIRST_WAKEUP_PACKET; 22749 wmi_service[wmi_service_multiple_mcast_filter_set] = 22750 WMI_SERVICE_MULTIPLE_MCAST_FILTER_SET; 22751 wmi_service[wmi_service_host_managed_rx_reorder] = 22752 WMI_SERVICE_HOST_MANAGED_RX_REORDER; 22753 wmi_service[wmi_service_flash_rdwr_support] = 22754 WMI_SERVICE_FLASH_RDWR_SUPPORT; 22755 wmi_service[wmi_service_wlan_stats_report] = 22756 WMI_SERVICE_WLAN_STATS_REPORT; 22757 wmi_service[wmi_service_tx_msdu_id_new_partition_support] = 22758 WMI_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT; 22759 wmi_service[wmi_service_dfs_phyerr_offload] = 22760 WMI_SERVICE_DFS_PHYERR_OFFLOAD; 22761 wmi_service[wmi_service_rcpi_support] = WMI_SERVICE_RCPI_SUPPORT; 22762 wmi_service[wmi_service_fw_mem_dump_support] = 22763 WMI_SERVICE_FW_MEM_DUMP_SUPPORT; 22764 wmi_service[wmi_service_peer_stats_info] = WMI_SERVICE_PEER_STATS_INFO; 22765 wmi_service[wmi_service_regulatory_db] = WMI_SERVICE_REGULATORY_DB; 22766 wmi_service[wmi_service_11d_offload] = WMI_SERVICE_11D_OFFLOAD; 22767 wmi_service[wmi_service_hw_data_filtering] = 22768 WMI_SERVICE_HW_DATA_FILTERING; 22769 wmi_service[wmi_service_pkt_routing] = WMI_SERVICE_PKT_ROUTING; 22770 wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_OFFCHAN_TX_WMI; 22771 wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; 22772 wmi_service[wmi_service_extended_nss_support] = 22773 WMI_SERVICE_EXTENDED_NSS_SUPPORT; 22774 wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; 22775 wmi_service[wmi_service_bcn_offload_start_stop_support] = 22776 WMI_SERVICE_BCN_OFFLOAD_START_STOP_SUPPORT; 22777 wmi_service[wmi_service_offchan_data_tid_support] = 22778 WMI_SERVICE_OFFCHAN_DATA_TID_SUPPORT; 22779 wmi_service[wmi_service_support_dma] = 22780 WMI_SERVICE_SUPPORT_DIRECT_DMA; 22781 wmi_service[wmi_service_8ss_tx_bfee] = WMI_SERVICE_8SS_TX_BFEE; 22782 wmi_service[wmi_service_fils_support] = WMI_SERVICE_FILS_SUPPORT; 22783 wmi_service[wmi_service_mawc_support] = WMI_SERVICE_MAWC_SUPPORT; 22784 wmi_service[wmi_service_wow_wakeup_by_timer_pattern] = 22785 WMI_SERVICE_WOW_WAKEUP_BY_TIMER_PATTERN; 22786 wmi_service[wmi_service_11k_neighbour_report_support] = 22787 WMI_SERVICE_11K_NEIGHBOUR_REPORT_SUPPORT; 22788 wmi_service[wmi_service_ap_obss_detection_offload] = 22789 WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD; 22790 wmi_service[wmi_service_bss_color_offload] = 22791 WMI_SERVICE_BSS_COLOR_OFFLOAD; 22792 wmi_service[wmi_service_gmac_offload_support] = 22793 WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; 22794 wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = 22795 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; 22796 wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = 22797 WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; 22798 wmi_service[wmi_service_twt_requestor] = WMI_SERVICE_STA_TWT; 22799 wmi_service[wmi_service_twt_responder] = WMI_SERVICE_AP_TWT; 22800 wmi_service[wmi_service_listen_interval_offload_support] = 22801 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT; 22802 wmi_service[wmi_service_esp_support] = WMI_SERVICE_ESP_SUPPORT; 22803 wmi_service[wmi_service_obss_spatial_reuse] = 22804 WMI_SERVICE_OBSS_SPATIAL_REUSE; 22805 wmi_service[wmi_service_per_vdev_chain_support] = 22806 WMI_SERVICE_PER_VDEV_CHAINMASK_CONFIG_SUPPORT; 22807 wmi_service[wmi_service_new_htt_msg_format] = 22808 WMI_SERVICE_HTT_H2T_NO_HTC_HDR_LEN_IN_MSG_LEN; 22809 wmi_service[wmi_service_peer_unmap_cnf_support] = 22810 WMI_SERVICE_PEER_UNMAP_RESPONSE_SUPPORT; 22811 wmi_service[wmi_service_beacon_reception_stats] = 22812 WMI_SERVICE_BEACON_RECEPTION_STATS; 22813 wmi_service[wmi_service_vdev_latency_config] = 22814 WMI_SERVICE_VDEV_LATENCY_CONFIG; 22815 wmi_service[wmi_service_nan_dbs_support] = WMI_SERVICE_NAN_DBS_SUPPORT; 22816 wmi_service[wmi_service_ndi_dbs_support] = WMI_SERVICE_NDI_DBS_SUPPORT; 22817 wmi_service[wmi_service_nan_sap_support] = WMI_SERVICE_NAN_SAP_SUPPORT; 22818 wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; 22819 wmi_service[wmi_service_nan_disable_support] = 22820 WMI_SERVICE_NAN_DISABLE_SUPPORT; 22821 wmi_service[wmi_service_sta_plus_sta_support] = 22822 WMI_SERVICE_STA_PLUS_STA_SUPPORT; 22823 wmi_service[wmi_service_hw_db2dbm_support] = 22824 WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; 22825 wmi_service[wmi_service_wlm_stats_support] = 22826 WMI_SERVICE_WLM_STATS_REQUEST; 22827 wmi_service[wmi_service_infra_mbssid] = WMI_SERVICE_INFRA_MBSSID; 22828 wmi_service[wmi_service_ema_ap_support] = WMI_SERVICE_EMA_AP_SUPPORT; 22829 wmi_service[wmi_service_ul_ru26_allowed] = WMI_SERVICE_UL_RU26_ALLOWED; 22830 wmi_service[wmi_service_cfr_capture_support] = 22831 WMI_SERVICE_CFR_CAPTURE_SUPPORT; 22832 wmi_service[wmi_service_cfr_capture_pdev_id_soc] = 22833 WMI_SERVICE_CFR_CAPTURE_PDEV_ID_SOC; 22834 wmi_service[wmi_service_bcast_twt_support] = 22835 WMI_SERVICE_BROADCAST_TWT; 22836 wmi_service[wmi_service_wpa3_ft_sae_support] = 22837 WMI_SERVICE_WPA3_FT_SAE_SUPPORT; 22838 wmi_service[wmi_service_wpa3_ft_suite_b_support] = 22839 WMI_SERVICE_WPA3_FT_SUITE_B_SUPPORT; 22840 wmi_service[wmi_service_ft_fils] = 22841 WMI_SERVICE_WPA3_FT_FILS; 22842 wmi_service[wmi_service_adaptive_11r_support] = 22843 WMI_SERVICE_ADAPTIVE_11R_ROAM; 22844 wmi_service[wmi_service_tx_compl_tsf64] = 22845 WMI_SERVICE_TX_COMPL_TSF64; 22846 wmi_service[wmi_service_data_stall_recovery_support] = 22847 WMI_SERVICE_DSM_ROAM_FILTER; 22848 wmi_service[wmi_service_vdev_delete_all_peer] = 22849 WMI_SERVICE_DELETE_ALL_PEER_SUPPORT; 22850 wmi_service[wmi_service_three_way_coex_config_legacy] = 22851 WMI_SERVICE_THREE_WAY_COEX_CONFIG_LEGACY; 22852 wmi_service[wmi_service_multiple_coex_config_support] = 22853 WMI_SERVICE_MULTIPLE_COEX_CONFIG_SUPPORT; 22854 wmi_service[wmi_service_rx_fse_support] = 22855 WMI_SERVICE_RX_FSE_SUPPORT; 22856 wmi_service[wmi_service_sae_roam_support] = 22857 WMI_SERVICE_WPA3_SAE_ROAM_SUPPORT; 22858 wmi_service[wmi_service_owe_roam_support] = 22859 WMI_SERVICE_WPA3_OWE_ROAM_SUPPORT; 22860 wmi_service[wmi_service_6ghz_support] = 22861 WMI_SERVICE_6GHZ_SUPPORT; 22862 wmi_service[wmi_service_bw_165mhz_support] = 22863 WMI_SERVICE_BW_165MHZ_SUPPORT; 22864 wmi_service[wmi_service_bw_restricted_80p80_support] = 22865 WMI_SERVICE_BW_RESTRICTED_80P80_SUPPORT; 22866 wmi_service[wmi_service_packet_capture_support] = 22867 WMI_SERVICE_PACKET_CAPTURE_SUPPORT; 22868 wmi_service[wmi_service_nan_vdev] = WMI_SERVICE_NAN_VDEV_SUPPORT; 22869 wmi_service[wmi_service_peer_delete_no_peer_flush_tids_cmd] = 22870 WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD; 22871 wmi_service[wmi_service_multiple_vdev_restart_ext] = 22872 WMI_SERVICE_UNAVAILABLE; 22873 wmi_service[wmi_service_time_sync_ftm] = 22874 WMI_SERVICE_AUDIO_SYNC_SUPPORT; 22875 wmi_service[wmi_service_nss_ratio_to_host_support] = 22876 WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT; 22877 wmi_service[wmi_roam_scan_chan_list_to_host_support] = 22878 WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT; 22879 wmi_service[wmi_beacon_protection_support] = 22880 WMI_SERVICE_BEACON_PROTECTION_SUPPORT; 22881 wmi_service[wmi_service_sta_nan_ndi_four_port] = 22882 WMI_SERVICE_NDI_NDI_STA_SUPPORT; 22883 wmi_service[wmi_service_host_scan_stop_vdev_all] = 22884 WMI_SERVICE_HOST_SCAN_STOP_VDEV_ALL_SUPPORT; 22885 wmi_service[wmi_support_extend_address] = 22886 WMI_SERVICE_SUPPORT_EXTEND_ADDRESS; 22887 wmi_service[wmi_service_srg_srp_spatial_reuse_support] = 22888 WMI_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT; 22889 wmi_service[wmi_service_suiteb_roam_support] = 22890 WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT; 22891 wmi_service[wmi_service_no_interband_mcc_support] = 22892 WMI_SERVICE_NO_INTERBAND_MCC_SUPPORT; 22893 wmi_service[wmi_service_dual_sta_roam_support] = 22894 WMI_SERVICE_DUAL_STA_ROAM_SUPPORT; 22895 wmi_service[wmi_service_peer_create_conf] = 22896 WMI_SERVICE_PEER_CREATE_CONF; 22897 wmi_service[wmi_service_configure_roam_trigger_param_support] = 22898 WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT; 22899 wmi_service[wmi_service_5dot9_ghz_support] = 22900 WMI_SERVICE_5_DOT_9GHZ_SUPPORT; 22901 wmi_service[wmi_service_cfr_ta_ra_as_fp_support] = 22902 WMI_SERVICE_CFR_TA_RA_AS_FP_SUPPORT; 22903 wmi_service[wmi_service_cfr_capture_count_support] = 22904 WMI_SERVICE_CFR_CAPTURE_COUNT_SUPPORT; 22905 wmi_service[wmi_service_ocv_support] = 22906 WMI_SERVICE_OCV_SUPPORT; 22907 wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] = 22908 WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT; 22909 wmi_service[wmi_service_thermal_multi_client_support] = 22910 WMI_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT; 22911 wmi_service[wmi_service_mbss_param_in_vdev_start_support] = 22912 WMI_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT; 22913 wmi_service[wmi_service_fse_cmem_alloc_support] = 22914 WMI_SERVICE_FSE_CMEM_ALLOC_SUPPORT; 22915 wmi_service[wmi_service_scan_conf_per_ch_support] = 22916 WMI_SERVICE_SCAN_CONFIG_PER_CHANNEL; 22917 wmi_service[wmi_service_csa_beacon_template] = 22918 WMI_SERVICE_CSA_BEACON_TEMPLATE; 22919 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 22920 wmi_service[wmi_service_rtt_11az_ntb_support] = 22921 WMI_SERVICE_RTT_11AZ_NTB_SUPPORT; 22922 wmi_service[wmi_service_rtt_11az_tb_support] = 22923 WMI_SERVICE_RTT_11AZ_TB_SUPPORT; 22924 wmi_service[wmi_service_rtt_11az_tb_rsta_support] = 22925 WMI_SERVICE_RTT_11AZ_TB_RSTA_SUPPORT; 22926 wmi_service[wmi_service_rtt_11az_mac_sec_support] = 22927 WMI_SERVICE_RTT_11AZ_MAC_SEC_SUPPORT; 22928 wmi_service[wmi_service_rtt_11az_mac_phy_sec_support] = 22929 WMI_SERVICE_RTT_11AZ_MAC_PHY_SEC_SUPPORT; 22930 #endif 22931 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 22932 wmi_service[wmi_service_igmp_offload_support] = 22933 WMI_SERVICE_IGMP_OFFLOAD_SUPPORT; 22934 #endif 22935 22936 #ifdef FEATURE_WLAN_TDLS 22937 #ifdef WLAN_FEATURE_11AX 22938 wmi_service[wmi_service_tdls_ax_support] = 22939 WMI_SERVICE_11AX_TDLS_SUPPORT; 22940 wmi_service[wmi_service_tdls_6g_support] = 22941 WMI_SERVICE_TDLS_6GHZ_SUPPORT; 22942 #endif 22943 wmi_service[wmi_service_tdls_wideband_support] = 22944 WMI_SERVICE_TDLS_WIDEBAND_SUPPORT; 22945 wmi_service[wmi_service_tdls_concurrency_support] = 22946 WMI_SERVICE_TDLS_CONCURRENCY_SUPPORT; 22947 #endif 22948 #ifdef FEATURE_WLAN_TDLS 22949 #ifdef WLAN_FEATURE_11BE 22950 wmi_service[wmi_service_tdls_mlo_support] = 22951 WMI_SERVICE_11BE_MLO_TDLS_SUPPORT; 22952 #endif 22953 #endif 22954 #ifdef WLAN_SUPPORT_TWT 22955 wmi_service[wmi_service_twt_bcast_req_support] = 22956 WMI_SERVICE_BROADCAST_TWT_REQUESTER; 22957 wmi_service[wmi_service_twt_bcast_resp_support] = 22958 WMI_SERVICE_BROADCAST_TWT_RESPONDER; 22959 wmi_service[wmi_service_twt_nudge] = 22960 WMI_SERVICE_TWT_NUDGE; 22961 wmi_service[wmi_service_all_twt] = 22962 WMI_SERVICE_TWT_ALL_DIALOG_ID; 22963 wmi_service[wmi_service_twt_statistics] = 22964 WMI_SERVICE_TWT_STATS; 22965 wmi_service[wmi_service_restricted_twt] = WMI_SERVICE_RESTRICTED_TWT; 22966 #endif 22967 wmi_service[wmi_service_spectral_scan_disabled] = 22968 WMI_SERVICE_SPECTRAL_SCAN_DISABLED; 22969 wmi_service[wmi_service_sae_eapol_offload_support] = 22970 WMI_SERVICE_SAE_EAPOL_OFFLOAD_SUPPORT; 22971 wmi_populate_service_get_sta_in_ll_stats_req(wmi_service); 22972 22973 wmi_service[wmi_service_wapi_concurrency_supported] = 22974 WMI_SERVICE_WAPI_CONCURRENCY_SUPPORTED; 22975 wmi_service[wmi_service_sap_connected_d3_wow] = 22976 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22977 wmi_service[wmi_service_go_connected_d3_wow] = 22978 WMI_SERVICE_SAP_CONNECTED_D3WOW; 22979 wmi_service[wmi_service_ext_tpc_reg_support] = 22980 WMI_SERVICE_EXT_TPC_REG_SUPPORT; 22981 wmi_service[wmi_service_eirp_preferred_support] = 22982 WMI_SERVICE_EIRP_PREFERRED_SUPPORT; 22983 wmi_service[wmi_service_ndi_txbf_support] = 22984 WMI_SERVICE_NDI_TXBF_SUPPORT; 22985 wmi_service[wmi_service_reg_cc_ext_event_support] = 22986 WMI_SERVICE_REG_CC_EXT_EVENT_SUPPORT; 22987 wmi_service[wmi_service_bang_radar_320_support] = 22988 WMI_SERVICE_BANG_RADAR_320_SUPPORT; 22989 #if defined(CONFIG_BAND_6GHZ) 22990 wmi_service[wmi_service_lower_6g_edge_ch_supp] = 22991 WMI_SERVICE_ENABLE_LOWER_6G_EDGE_CH_SUPP; 22992 wmi_service[wmi_service_disable_upper_6g_edge_ch_supp] = 22993 WMI_SERVICE_DISABLE_UPPER_6G_EDGE_CH_SUPP; 22994 #ifdef CONFIG_AFC_SUPPORT 22995 wmi_service[wmi_service_afc_support] = 22996 WMI_SERVICE_AFC_SUPPORT; 22997 #endif 22998 #endif 22999 wmi_service[wmi_service_dcs_awgn_int_support] = 23000 WMI_SERVICE_DCS_AWGN_INT_SUPPORT; 23001 wmi_populate_service_11be(wmi_service); 23002 23003 #ifdef WLAN_FEATURE_BIG_DATA_STATS 23004 wmi_service[wmi_service_big_data_support] = 23005 WMI_SERVICE_BIG_DATA_SUPPORT; 23006 #endif 23007 wmi_service[wmi_service_ampdu_tx_buf_size_256_support] = 23008 WMI_SERVICE_AMPDU_TX_BUF_SIZE_256_SUPPORT; 23009 wmi_service[wmi_service_halphy_cal_enable_disable_support] = 23010 WMI_SERVICE_HALPHY_CAL_ENABLE_DISABLE_SUPPORT; 23011 wmi_service[wmi_service_halphy_cal_status] = 23012 WMI_SERVICE_HALPHY_CAL_STATUS; 23013 wmi_service[wmi_service_rtt_ap_initiator_staggered_mode_supported] = 23014 WMI_SERVICE_RTT_AP_INITIATOR_STAGGERED_MODE_SUPPORTED; 23015 wmi_service[wmi_service_rtt_ap_initiator_bursted_mode_supported] = 23016 WMI_SERVICE_RTT_AP_INITIATOR_BURSTED_MODE_SUPPORTED; 23017 wmi_service[wmi_service_ema_multiple_group_supported] = 23018 WMI_SERVICE_EMA_MULTIPLE_GROUP_SUPPORT; 23019 wmi_service[wmi_service_large_beacon_supported] = 23020 WMI_SERVICE_LARGE_BEACON_SUPPORT; 23021 wmi_service[wmi_service_aoa_for_rcc_supported] = 23022 WMI_SERVICE_AOA_FOR_RCC_SUPPORTED; 23023 #ifdef WLAN_FEATURE_P2P_P2P_STA 23024 wmi_service[wmi_service_p2p_p2p_cc_support] = 23025 WMI_SERVICE_P2P_P2P_CONCURRENCY_SUPPORT; 23026 #endif 23027 #ifdef THERMAL_STATS_SUPPORT 23028 wmi_service[wmi_service_thermal_stats_temp_range_supported] = 23029 WMI_SERVICE_THERMAL_THROT_STATS_TEMP_RANGE_SUPPORT; 23030 #endif 23031 wmi_service[wmi_service_hw_mode_policy_offload_support] = 23032 WMI_SERVICE_HW_MODE_POLICY_OFFLOAD_SUPPORT; 23033 wmi_service[wmi_service_mgmt_rx_reo_supported] = 23034 WMI_SERVICE_MGMT_RX_REO_SUPPORTED; 23035 wmi_service[wmi_service_phy_dma_byte_swap_support] = 23036 WMI_SERVICE_UNAVAILABLE; 23037 wmi_service[wmi_service_spectral_session_info_support] = 23038 WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; 23039 wmi_service[wmi_service_umac_hang_recovery_support] = 23040 WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; 23041 wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; 23042 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 23043 wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] = 23044 WMI_SERVICE_DYNAMIC_VDEV_MAC_ADDR_UPDATE_SUPPORT; 23045 #endif 23046 wmi_service[wmi_service_probe_all_bw_support] = 23047 WMI_SERVICE_PROBE_ALL_BW_SUPPORT; 23048 wmi_service[wmi_service_pno_scan_conf_per_ch_support] = 23049 WMI_SERVICE_PNO_SCAN_CONFIG_PER_CHANNEL; 23050 #ifdef QCA_UNDECODED_METADATA_SUPPORT 23051 wmi_service[wmi_service_fp_phy_err_filter_support] = 23052 WMI_SERVICE_FP_PHY_ERR_FILTER_SUPPORT; 23053 #endif 23054 populate_tlv_service_mlo(wmi_service); 23055 wmi_service[wmi_service_pdev_rate_config_support] = 23056 WMI_SERVICE_PDEV_RATE_CONFIG_SUPPORT; 23057 wmi_service[wmi_service_multi_peer_group_cmd_support] = 23058 WMI_SERVICE_MULTIPLE_PEER_GROUP_CMD_SUPPORT; 23059 #ifdef WLAN_FEATURE_11BE 23060 wmi_service[wmi_service_radar_found_chan_freq_eq_center_freq] = 23061 WMI_IS_RADAR_FOUND_CHAN_FREQ_IS_CENTER_FREQ; 23062 #endif 23063 #ifdef WLAN_PDEV_VDEV_SEND_MULTI_PARAM 23064 wmi_service[wmi_service_combined_set_param_support] = 23065 WMI_SERVICE_COMBINED_SET_PARAM_SUPPORT; 23066 #endif 23067 wmi_service[wmi_service_pn_replay_check_support] = 23068 WMI_SERVICE_PN_REPLAY_CHECK_SUPPORT; 23069 #ifdef QCA_RSSI_DB2DBM 23070 wmi_service[wmi_service_pdev_rssi_dbm_conv_event_support] = 23071 WMI_SERVICE_PDEV_RSSI_DBM_CONV_EVENT_SUPPORT; 23072 #endif 23073 wmi_service[wmi_service_pktlog_decode_info_support] = 23074 WMI_SERVICE_PKTLOG_DECODE_INFO_SUPPORT; 23075 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 23076 wmi_service[wmi_service_roam_stats_per_candidate_frame_info] = 23077 WMI_SERVICE_ROAM_STAT_PER_CANDIDATE_FRAME_INFO_SUPPORT; 23078 #endif 23079 #ifdef MULTI_CLIENT_LL_SUPPORT 23080 wmi_service[wmi_service_configure_multi_client_ll_support] = 23081 WMI_SERVICE_MULTI_CLIENT_LL_SUPPORT; 23082 #endif 23083 #ifdef WLAN_VENDOR_HANDOFF_CONTROL 23084 wmi_service[wmi_service_configure_vendor_handoff_control_support] = 23085 WMI_SERVICE_FW_INI_PARSE_SUPPORT; 23086 #endif 23087 wmi_service[wmi_service_linkspeed_roam_trigger_support] = 23088 WMI_SERVICE_LINKSPEED_ROAM_TRIGGER_SUPPORT; 23089 #ifdef FEATURE_SET 23090 wmi_service[wmi_service_feature_set_event_support] = 23091 WMI_SERVICE_FEATURE_SET_EVENT_SUPPORT; 23092 #endif 23093 #ifdef WLAN_FEATURE_SR 23094 wmi_service[wmi_service_obss_per_packet_sr_support] = 23095 WMI_SERVICE_OBSS_PER_PACKET_SR_SUPPORT; 23096 #endif 23097 wmi_service[wmi_service_wpa3_sha384_roam_support] = 23098 WMI_SERVICE_WMI_SERVICE_WPA3_SHA384_ROAM_SUPPORT; 23099 wmi_service[wmi_service_self_mld_roam_between_dbs_and_hbs] = 23100 WMI_SERVICE_SELF_MLD_ROAM_BETWEEN_DBS_AND_HBS; 23101 /* TODO: Assign FW Enum after FW Shared header changes are merged */ 23102 wmi_service[wmi_service_v1a_v1b_supported] = 23103 WMI_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT; 23104 #ifdef QCA_MANUAL_TRIGGERED_ULOFDMA 23105 wmi_service[wmi_service_manual_ulofdma_trigger_support] = 23106 WMI_SERVICE_MANUAL_ULOFDMA_TRIGGER_SUPPORT; 23107 #endif 23108 wmi_service[wmi_service_pre_rx_timeout] = 23109 WMI_SERVICE_PRE_RX_TO; 23110 #ifdef QCA_STANDALONE_SOUNDING_TRIGGER 23111 wmi_service[wmi_service_standalone_sound] = 23112 WMI_SERVICE_STANDALONE_SOUND; 23113 #endif 23114 wmi_service[wmi_service_cca_busy_info_for_each_20mhz] = 23115 WMI_SERVICE_CCA_BUSY_INFO_FOREACH_20MHZ; 23116 wmi_service[wmi_service_vdev_param_chwidth_with_notify_support] = 23117 WMI_SERVICE_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT; 23118 #ifdef WLAN_FEATURE_11BE_MLO 23119 wmi_service[wmi_service_mlo_tsf_sync] = WMI_SERVICE_MLO_TSF_SYNC; 23120 wmi_service[wmi_service_n_link_mlo_support] = 23121 WMI_SERVICE_N_LINK_MLO_SUPPORT; 23122 wmi_service[wmi_service_per_link_stats_support] = 23123 WMI_SERVICE_PER_LINK_STATS_SUPPORT; 23124 wmi_service[wmi_service_pdev_wsi_stats_info_support] = 23125 WMI_SERVICE_PDEV_WSI_STATS_INFO_SUPPORT; 23126 wmi_service[wmi_service_mlo_tid_to_link_mapping_support] = 23127 WMI_SERVICE_MLO_TID_TO_LINK_MAPPING_SUPPORT; 23128 #endif 23129 wmi_service[wmi_service_aux_mac_support] = WMI_SERVICE_AUX_MAC_SUPPORT; 23130 #ifdef WLAN_ATF_INCREASED_STA 23131 wmi_service[wmi_service_atf_max_client_512_support] = 23132 WMI_SERVICE_ATF_MAX_CLIENT_512_SUPPORT; 23133 #endif 23134 wmi_service[wmi_service_fisa_dynamic_msdu_aggr_size_support] = 23135 WMI_SERVICE_FISA_DYNAMIC_MSDU_AGGR_SIZE_SUPPORT; 23136 wmi_service[wmi_service_radar_flags_support] = 23137 WMI_SERVICE_RADAR_FLAGS_SUPPORT; 23138 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 23139 wmi_service[wmi_service_5ghz_hi_rssi_roam_support] = 23140 WMI_SERVICE_5GHZ_HI_RSSI_ROAM_SUPPORT; 23141 #endif 23142 wmi_service[wmi_service_pdev_param_in_utf_wmi] = 23143 WMI_SERVICE_PDEV_PARAM_IN_UTF_WMI; 23144 #ifdef WLAN_FEATURE_LL_LT_SAP 23145 wmi_service[wmi_service_xpan_support] = WMI_SERVICE_XPAN_SUPPORT; 23146 #endif 23147 wmi_service[wmi_service_multiple_reorder_queue_setup_support] = 23148 WMI_SERVICE_MULTIPLE_REORDER_QUEUE_SETUP_SUPPORT; 23149 wmi_service[wmi_service_p2p_device_update_mac_addr_support] = 23150 WMI_SERVICE_P2P_DEVICE_UPDATE_MAC_ADDR_SUPPORT; 23151 #ifdef WLAN_CHIPSET_STATS 23152 wmi_service[wmi_service_chipset_logging_support] = 23153 WMI_SERVICE_CHIPSET_LOGGING_SUPPORT; 23154 #endif 23155 } 23156 23157 /** 23158 * wmi_ocb_ut_attach() - Attach OCB test framework 23159 * @wmi_handle: wmi handle 23160 * 23161 * Return: None 23162 */ 23163 #ifdef WLAN_OCB_UT 23164 void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle); 23165 #else 23166 static inline void wmi_ocb_ut_attach(struct wmi_unified *wmi_handle) 23167 { 23168 return; 23169 } 23170 #endif 23171 23172 /** 23173 * wmi_tlv_attach() - Attach TLV APIs 23174 * @wmi_handle: wmi handle 23175 * Return: None 23176 */ 23177 void wmi_tlv_attach(wmi_unified_t wmi_handle) 23178 { 23179 wmi_handle->ops = &tlv_ops; 23180 wmi_ocb_ut_attach(wmi_handle); 23181 wmi_handle->soc->svc_ids = &multi_svc_ids[0]; 23182 #ifdef WMI_INTERFACE_EVENT_LOGGING 23183 /* Skip saving WMI_CMD_HDR and TLV HDR */ 23184 wmi_handle->soc->buf_offset_command = 8; 23185 /* WMI_CMD_HDR is already stripped, skip saving TLV HDR */ 23186 wmi_handle->soc->buf_offset_event = 4; 23187 #endif 23188 populate_tlv_events_id(wmi_handle->wmi_events); 23189 populate_tlv_service(wmi_handle->services); 23190 wmi_wds_attach_tlv(wmi_handle); 23191 wmi_twt_attach_tlv(wmi_handle); 23192 wmi_extscan_attach_tlv(wmi_handle); 23193 wmi_smart_ant_attach_tlv(wmi_handle); 23194 wmi_dbr_attach_tlv(wmi_handle); 23195 wmi_atf_attach_tlv(wmi_handle); 23196 wmi_ap_attach_tlv(wmi_handle); 23197 wmi_bcn_attach_tlv(wmi_handle); 23198 wmi_ocb_attach_tlv(wmi_handle); 23199 wmi_nan_attach_tlv(wmi_handle); 23200 wmi_p2p_attach_tlv(wmi_handle); 23201 wmi_interop_issues_ap_attach_tlv(wmi_handle); 23202 wmi_dcs_attach_tlv(wmi_handle); 23203 wmi_roam_attach_tlv(wmi_handle); 23204 wmi_concurrency_attach_tlv(wmi_handle); 23205 wmi_pmo_attach_tlv(wmi_handle); 23206 wmi_sta_attach_tlv(wmi_handle); 23207 wmi_11ax_bss_color_attach_tlv(wmi_handle); 23208 wmi_fwol_attach_tlv(wmi_handle); 23209 wmi_vdev_attach_tlv(wmi_handle); 23210 wmi_cfr_attach_tlv(wmi_handle); 23211 wmi_cp_stats_attach_tlv(wmi_handle); 23212 wmi_gpio_attach_tlv(wmi_handle); 23213 wmi_11be_attach_tlv(wmi_handle); 23214 wmi_coap_attach_tlv(wmi_handle); 23215 wmi_mlme_attach_tlv(wmi_handle); 23216 } 23217 qdf_export_symbol(wmi_tlv_attach); 23218 23219 /** 23220 * wmi_tlv_init() - Initialize WMI TLV module by registering TLV attach routine 23221 * 23222 * Return: None 23223 */ 23224 void wmi_tlv_init(void) 23225 { 23226 wmi_unified_register_module(WMI_TLV_TARGET, &wmi_tlv_attach); 23227 } 23228